Changeset: 34050ce51a7d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=34050ce51a7d Added Files: sql/test/rename/Tests/rename06.sql sql/test/rename/Tests/rename06.stable.err sql/test/rename/Tests/rename06.stable.out Modified Files: clients/mapiclient/mhelp.c sql/server/rel_schema.c sql/server/sql_parser.y sql/test/rename/Tests/All Branch: rename-sql Log Message:
Alter table statements with "if exists" checks. diffs (truncated from 599 to 300 lines): diff --git a/clients/mapiclient/mhelp.c b/clients/mapiclient/mhelp.c --- a/clients/mapiclient/mhelp.c +++ b/clients/mapiclient/mhelp.c @@ -47,28 +47,28 @@ SQLhelp sqlhelp[] = { // major commands {"ALTER TABLE", "", - "ALTER TABLE qname ADD [ COLUMN ] { column_def | table_constraint }\n" - "ALTER TABLE qname ALTER [ COLUMN ] ident SET DEFAULT value\n" - "ALTER TABLE qname ALTER [ COLUMN ] ident SET [NOT] NULL\n" - "ALTER TABLE qname ALTER [ COLUMN ] ident DROP DEFAULT\n" - "ALTER TABLE qname ALTER [ COLUMN ] ident SET STORAGE {string | NULL}\n" - "ALTER TABLE qname ALTER [ COLUMN ] ident RENAME TO ident\n" - "ALTER TABLE qname DROP [ COLUMN ] ident [ RESTRICT | CASCADE ]\n" - "ALTER TABLE qname DROP CONSTRAINT ident [ RESTRICT | CASCADE ]\n" - "ALTER TABLE qname SET { { READ | INSERT } ONLY | READ WRITE }\n" - "ALTER TABLE qname RENAME TO ident", + "ALTER TABLE [ IF EXISTS ] qname ADD [ COLUMN ] { column_def | table_constraint }\n" + "ALTER TABLE [ IF EXISTS ] qname ALTER [ COLUMN ] ident SET DEFAULT value\n" + "ALTER TABLE [ IF EXISTS ] qname ALTER [ COLUMN ] ident SET [NOT] NULL\n" + "ALTER TABLE [ IF EXISTS ] qname ALTER [ COLUMN ] ident DROP DEFAULT\n" + "ALTER TABLE [ IF EXISTS ] qname ALTER [ COLUMN ] ident SET STORAGE {string | NULL}\n" + "ALTER TABLE [ IF EXISTS ] qname ALTER [ COLUMN ] ident RENAME TO ident\n" + "ALTER TABLE [ IF EXISTS ] qname DROP [ COLUMN ] ident [ RESTRICT | CASCADE ]\n" + "ALTER TABLE [ IF EXISTS ] qname DROP CONSTRAINT ident [ RESTRICT | CASCADE ]\n" + "ALTER TABLE [ IF EXISTS ] qname SET { { READ | INSERT } ONLY | READ WRITE }\n" + "ALTER TABLE [ IF EXISTS ] qname RENAME TO ident", "column_def,table_constraint", "See also https://www.monetdb.org/Documentation/SQLreference/Alter"}, {"ALTER MERGE TABLE", "", - "ALTER TABLE qname ADD TABLE qname [ AS PARTITION opt_partition_spec ]\n" - "ALTER TABLE qname DROP TABLE qname [ RESTRICT | CASCADE ]\n" - "ALTER TABLE qname SET TABLE qname AS PARTITION opt_partition_spec", + "ALTER TABLE [ IF EXISTS ] qname ADD TABLE qname [ AS PARTITION opt_partition_spec ]\n" + "ALTER TABLE [ IF EXISTS ] qname DROP TABLE qname [ RESTRICT | CASCADE ]\n" + "ALTER TABLE [ IF EXISTS ] qname SET TABLE qname AS PARTITION opt_partition_spec", "opt_partition_spec", "See also https://www.monetdb.org/Documentation/Cookbooks/SQLrecipes/DataPartitioning"}, {"ALTER SCHEMA", "", - "ALTER SCHEMA ident RENAME TO ident", + "ALTER SCHEMA [ IF EXISTS ] ident RENAME TO ident", NULL, "See also https://www.monetdb.org/Documentation/SQLreference/Alter"}, {"ALTER SEQUENCE", diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c --- a/sql/server/rel_schema.c +++ b/sql/server/rel_schema.c @@ -1413,7 +1413,7 @@ get_schema_name( mvc *sql, char *sname, } static sql_rel * -sql_alter_table(mvc *sql, dlist *qname, symbol *te, symbol *extra) +sql_alter_table(mvc *sql, dlist *dl, dlist *qname, symbol *te, int if_exists) { char *sname = qname_schema(qname); char *tname = qname_table(qname); @@ -1421,8 +1421,9 @@ sql_alter_table(mvc *sql, dlist *qname, sql_table *t = NULL; if (sname && !(s=mvc_bind_schema(sql, sname))) { - (void) sql_error(sql, 02, SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", sname); - return NULL; + if(if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); + return sql_error(sql, 02, SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", sname); } if (!s) s = cur_schema(sql); @@ -1430,6 +1431,8 @@ sql_alter_table(mvc *sql, dlist *qname, if ((t = mvc_bind_table(sql, s, tname)) == NULL) { if (mvc_bind_table(sql, mvc_bind_schema(sql, "tmp"), tname) != NULL) return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: not supported on TEMPORARY table '%s'", tname); + if(if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", tname, s->base.name); } else { node *n; @@ -1469,6 +1472,8 @@ sql_alter_table(mvc *sql, dlist *qname, return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", ntname, spt->base.name); if (te->token == SQL_TABLE) { + symbol *extra = dl->h->next->next->next->data.sym; + if(!extra) return rel_alter_table(sql->sa, DDL_ALTER_TABLE_ADD_TABLE, sname, tname, sname, ntname, 0); @@ -2436,15 +2441,18 @@ credentials_password(dlist *credentials) } static sql_rel * -rel_rename_schema(mvc *sql, char *old_name, char *new_name) +rel_rename_schema(mvc *sql, char *old_name, char *new_name, int if_exists) { sql_schema *s; sql_rel *rel; list *exps; assert(old_name && new_name); - if (!(s = mvc_bind_schema(sql, old_name))) + if (!(s = mvc_bind_schema(sql, old_name))) { + if (if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SCHEMA: no such schema '%s'", old_name); + } if (!mvc_schema_privs(sql, s)) return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SCHEMA: access denied for %s to schema '%s'", stack_get_string(sql, "current_user"), old_name); if (s->system) @@ -2467,7 +2475,7 @@ rel_rename_schema(mvc *sql, char *old_na } static sql_rel * -rel_rename_table(mvc *sql, char* schema_name, char *old_name, char *new_name) +rel_rename_table(mvc *sql, char* schema_name, char *old_name, char *new_name, int if_exists) { sql_schema *s; sql_table *t; @@ -2476,12 +2484,18 @@ rel_rename_table(mvc *sql, char* schema_ assert(schema_name && old_name && new_name); - if (!(s = mvc_bind_schema(sql, schema_name))) + if (!(s = mvc_bind_schema(sql, schema_name))) { + if (if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: no such schema '%s'", schema_name); + } if (!mvc_schema_privs(sql, s)) return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", stack_get_string(sql, "current_user"), schema_name); - if (!(t = mvc_bind_table(sql, s, old_name))) + if (!(t = mvc_bind_table(sql, s, old_name))) { + if (if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", old_name, schema_name); + } if (t->system) return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: cannot rename a system table"); if (mvc_check_dependency(sql, t->base.id, TABLE_DEPENDENCY, NULL)) @@ -2503,7 +2517,7 @@ rel_rename_table(mvc *sql, char* schema_ } static sql_rel * -rel_rename_column(mvc *sql, char* schema_name, char *table_name, char *old_name, char *new_name) +rel_rename_column(mvc *sql, char* schema_name, char *table_name, char *old_name, char *new_name, int if_exists) { sql_schema *s; sql_table *t; @@ -2513,12 +2527,18 @@ rel_rename_column(mvc *sql, char* schema assert(schema_name && table_name && old_name && new_name); - if (!(s = mvc_bind_schema(sql, schema_name))) + if (!(s = mvc_bind_schema(sql, schema_name))) { + if (if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: no such schema '%s'", schema_name); + } if (!mvc_schema_privs(sql, s)) return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", stack_get_string(sql, "current_user"), schema_name); - if (!(t = mvc_bind_table(sql, s, table_name))) + if (!(t = mvc_bind_table(sql, s, table_name))) { + if (if_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", table_name, schema_name); + } if (t->system) return sql_error(sql, 02, SQLSTATE(42000) "ALTER TABLE: cannot rename a column in a system table"); if (isView(t)) @@ -2642,10 +2662,10 @@ rel_schemas(mvc *sql, symbol *s) { dlist *l = s->data.lval; - ret = sql_alter_table(sql, + ret = sql_alter_table(sql, l, l->h->data.lval, /* table name */ l->h->next->data.sym, /* table element */ - l->h->next->next->data.sym); + l->h->next->next->data.i_val); /* if exists */ } break; case SQL_GRANT_ROLES: { @@ -2751,7 +2771,7 @@ rel_schemas(mvc *sql, symbol *s) } break; case SQL_RENAME_SCHEMA: { dlist *l = s->data.lval; - ret = rel_rename_schema(sql, l->h->data.sval, l->h->next->data.sval); + ret = rel_rename_schema(sql, l->h->data.sval, l->h->next->data.sval, l->h->next->next->data.i_val); } break; case SQL_RENAME_TABLE: { dlist *l = s->data.lval; @@ -2759,7 +2779,7 @@ rel_schemas(mvc *sql, symbol *s) char *tname = qname_table(l->h->data.lval); if (!sname) sname = cur_schema(sql)->base.name; - ret = rel_rename_table(sql, sname, tname, l->h->next->data.sval); + ret = rel_rename_table(sql, sname, tname, l->h->next->data.sval, l->h->next->next->data.i_val); } break; case SQL_RENAME_COLUMN: { dlist *l = s->data.lval; @@ -2767,7 +2787,7 @@ rel_schemas(mvc *sql, symbol *s) char *tname = qname_table(l->h->data.lval); if (!sname) sname = cur_schema(sql)->base.name; - ret = rel_rename_column(sql, sname, tname, l->h->next->data.sval, l->h->next->next->data.sval); + ret = rel_rename_column(sql, sname, tname, l->h->next->data.sval, l->h->next->next->data.sval, l->h->next->next->next->data.i_val); } break; case SQL_CREATE_TYPE: { dlist *l = s->data.lval; diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -1059,77 +1059,82 @@ grantee: /* DOMAIN, ASSERTION, CHARACTER SET, TRANSLATION, TRIGGER */ alter_statement: - ALTER TABLE qname ADD opt_column add_table_element - + ALTER TABLE if_exists qname ADD opt_column add_table_element { dlist *l = L(); - append_list(l, $3); - append_symbol(l, $6); - append_symbol(l, NULL); /* used only in ADD TABLE */ + append_list(l, $4); + append_symbol(l, $7); + append_int(l, $3); $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } - | ALTER TABLE qname ADD TABLE qname opt_as_partition + | ALTER TABLE if_exists qname ADD TABLE qname opt_as_partition { dlist *l = L(), *part; - append_list(l, $3); - append_symbol(l, _symbol_create_list( SQL_TABLE, append_list(L(),$6))); - if($7) { - part = $7->data.lval; - append_int(part, FALSE); + append_list(l, $4); + append_symbol(l, _symbol_create_list( SQL_TABLE, append_list(L(),$7))); + append_int(l, $3); + if($8) { + part = $8->data.lval; + append_int(part, FALSE); } - append_symbol(l, $7); + append_symbol(l, $8); $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } - | ALTER TABLE qname ALTER alter_table_element + | ALTER TABLE if_exists qname ALTER alter_table_element + { dlist *l = L(); + append_list(l, $4); + append_symbol(l, $6); + append_int(l, $3); + $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } + | ALTER TABLE if_exists qname DROP drop_table_element { dlist *l = L(); - append_list(l, $3); - append_symbol(l, $5); - append_symbol(l, NULL); /* used only in ADD TABLE */ + append_list(l, $4); + append_symbol(l, $6); + append_int(l, $3); + $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } + | ALTER TABLE if_exists qname SET READ ONLY + { dlist *l = L(); + append_list(l, $4); + append_symbol(l, _symbol_create_int(SQL_ALTER_TABLE, tr_readonly)); + append_int(l, $3); $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } - | ALTER TABLE qname DROP drop_table_element + | ALTER TABLE if_exists qname SET INSERT ONLY { dlist *l = L(); - append_list(l, $3); - append_symbol(l, $5); - append_symbol(l, NULL); /* used only in ADD TABLE */ + append_list(l, $4); + append_symbol(l, _symbol_create_int(SQL_ALTER_TABLE, tr_append)); + append_int(l, $3); $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } - | ALTER TABLE qname SET READ ONLY + | ALTER TABLE if_exists qname SET READ WRITE { dlist *l = L(); - append_list(l, $3); - append_symbol(l, _symbol_create_int(SQL_ALTER_TABLE, tr_readonly)); - append_symbol(l, NULL); /* used only in ADD TABLE */ + append_list(l, $4); + append_symbol(l, _symbol_create_int(SQL_ALTER_TABLE, tr_writable)); + append_int(l, $3); $$ = _symbol_create_list( SQL_ALTER_TABLE, l ); } - | ALTER TABLE qname SET INSERT ONLY - { dlist *l = L(); - append_list(l, $3); - append_symbol(l, _symbol_create_int(SQL_ALTER_TABLE, tr_append)); - append_symbol(l, NULL); /* used only in ADD TABLE */ + | ALTER TABLE if_exists qname SET TABLE qname opt_as_partition + { dlist *l = L(), *part; + append_list(l, $4); + append_symbol(l, _symbol_create_list( SQL_TABLE, append_list(L(),$7))); + append_int(l, $3); + if($8) { + part = $8->data.lval; + append_int(part, TRUE); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list