1#include "duckdb/parser/statement/alter_table_statement.hpp"
2#include "duckdb/parser/transformer.hpp"
3#include "duckdb/parser/tableref/basetableref.hpp"
4#include "duckdb/parser/expression/cast_expression.hpp"
5#include "duckdb/parser/expression/columnref_expression.hpp"
6#include "duckdb/parser/constraint.hpp"
7
8using namespace std;
9
10namespace duckdb {
11
12unique_ptr<AlterTableStatement> Transformer::TransformAlter(PGNode *node) {
13 auto stmt = reinterpret_cast<PGAlterTableStmt *>(node);
14 assert(stmt);
15 assert(stmt->relation);
16
17 auto result = make_unique<AlterTableStatement>();
18
19 auto table = TransformRangeVar(stmt->relation);
20 assert(table->type == TableReferenceType::BASE_TABLE);
21
22 auto &basetable = (BaseTableRef &)*table;
23 // first we check the type of ALTER
24 for (auto c = stmt->cmds->head; c != NULL; c = c->next) {
25 auto command = reinterpret_cast<PGAlterTableCmd *>(lfirst(c));
26 // TODO: Include more options for command->subtype
27 switch (command->subtype) {
28 case PG_AT_AddColumn: {
29 auto cdef = (PGColumnDef *)command->def;
30 auto centry = TransformColumnDefinition(cdef);
31 if (cdef->constraints) {
32 for (auto constr = cdef->constraints->head; constr != nullptr; constr = constr->next) {
33 auto constraint = TransformConstraint(constr, centry, 0);
34 if (constraint) {
35 throw ParserException("Adding columns with constraints not yet supported");
36 }
37 }
38 }
39 result->info = make_unique<AddColumnInfo>(basetable.schema_name, basetable.table_name, move(centry));
40 break;
41 }
42 case PG_AT_DropColumn: {
43 result->info = make_unique<RemoveColumnInfo>(basetable.schema_name, basetable.table_name, command->name,
44 command->missing_ok);
45 break;
46 }
47 case PG_AT_ColumnDefault: {
48 auto expr = TransformExpression(command->def);
49 result->info =
50 make_unique<SetDefaultInfo>(basetable.schema_name, basetable.table_name, command->name, move(expr));
51 break;
52 }
53 case PG_AT_AlterColumnType: {
54 auto cdef = (PGColumnDef *)command->def;
55 SQLType target_type = TransformTypeName(cdef->typeName);
56 target_type.collation = TransformCollation(cdef->collClause);
57
58 unique_ptr<ParsedExpression> expr;
59 if (cdef->raw_default) {
60 expr = TransformExpression(cdef->raw_default);
61 } else {
62 auto colref = make_unique<ColumnRefExpression>(command->name);
63 expr = make_unique<CastExpression>(target_type, move(colref));
64 }
65 result->info = make_unique<ChangeColumnTypeInfo>(basetable.schema_name, basetable.table_name, command->name,
66 target_type, move(expr));
67 break;
68 }
69 case PG_AT_DropConstraint:
70 case PG_AT_DropNotNull:
71 default:
72 throw NotImplementedException("ALTER TABLE option not supported yet!");
73 }
74 }
75
76 return result;
77}
78
79} // namespace duckdb
80