Changeset: 510b0d47c5c0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=510b0d47c5c0 Modified Files: sql/server/rel_psm.c sql/server/rel_schema.c sql/server/rel_schema.h sql/test/scoping/Tests/scoping01.sql Branch: scoping Log Message:
When declaring a local table, search on the stack only diffs (113 lines): diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c --- a/sql/server/rel_psm.c +++ b/sql/server/rel_psm.c @@ -233,15 +233,9 @@ rel_psm_declare_table(sql_query *query, const char *sname = qname_schema(qname); const char *name = qname_schema_object(qname); sql_table *t; - sql_schema *s = cur_schema(sql); - - if (sname && !(s = mvc_bind_schema(sql, sname))) - return sql_error(sql, 02, SQLSTATE(3F000) "DECLARE: No such schema '%s'", sname); - if (stack_find_table(sql, s, name)) - return sql_error(sql, 01, SQLSTATE(42000) "DECLARE: Table '%s' already declared", name); assert(n->next->next->next->type == type_int); - rel = rel_create_table(query, SQL_DECLARED_TABLE, s->base.name, name, n->next->next->data.sym, + rel = rel_create_table(query, SQL_DECLARED_TABLE, sname, name, false, n->next->next->data.sym, n->next->next->next->data.i_val, NULL, NULL, NULL, false, NULL, n->next->next->next->next->next->next->data.i_val); @@ -258,7 +252,7 @@ rel_psm_declare_table(sql_query *query, t = (sql_table*)((atom*)((sql_exp*)baset->exps->t->data)->l)->data.val.pval; if (!frame_push_table(sql, t)) return sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL); - return exp_table(sql->sa, sa_strdup(sql->sa, s->base.name), sa_strdup(sql->sa, name), t, sql->frame); + return exp_table(sql->sa, sa_strdup(sql->sa, t->s->base.name), sa_strdup(sql->sa, name), t, sql->frame); } /* [ label: ] 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 @@ -1000,7 +1000,7 @@ create_partition_definition(mvc *sql, sq } sql_rel * -rel_create_table(sql_query *query, int temp, const char *sname, const char *name, symbol *table_elements_or_subquery, +rel_create_table(sql_query *query, int temp, const char *sname, const char *name, bool global, symbol *table_elements_or_subquery, int commit_action, const char *loc, const char *username, const char *password, bool pw_encrypted, symbol* partition_def, int if_not_exists) { @@ -1031,10 +1031,15 @@ rel_create_table(sql_query *query, int t } } - if (mvc_bind_table(sql, s, name)) { + if (global && find_sql_table(s, name)) { if (if_not_exists) return rel_psm_block(sql->sa, new_exp_list(sql->sa)); return sql_error(sql, 02, SQLSTATE(42S01) "%s TABLE: name '%s' already in use", action, name); + } else if (!global && stack_find_table(sql, s, name)) { + assert(temp == SQL_DECLARED_TABLE); + if (if_not_exists) + return rel_psm_block(sql->sa, new_exp_list(sql->sa)); + return sql_error(sql, 02, SQLSTATE(42S01) "%s TABLE: name '%s' already declared", action, name); } else if (temp != SQL_DECLARED_TABLE && (!mvc_schema_privs(sql, s) && !(isTempSchema(s) && temp == SQL_LOCAL_TEMP))){ return sql_error(sql, 02, SQLSTATE(42000) "CREATE TABLE: insufficient privileges for user '%s' in schema '%s'", sqlvar_get_string(find_global_var(sql, mvc_bind_schema(sql, "sys"), "current_user")), s->base.name); } else if (temp == SQL_PERSIST && isTempSchema(s)){ @@ -2677,7 +2682,7 @@ rel_schemas(sql_query *query, symbol *s) assert(l->h->type == type_int); assert(l->h->next->next->next->type == type_int); - ret = rel_create_table(query, temp, sname, name, + ret = rel_create_table(query, temp, sname, name, true, l->h->next->next->data.sym, /* elements or subquery */ l->h->next->next->next->data.i_val, /* commit action */ l->h->next->next->next->next->data.sval, /* location */ diff --git a/sql/server/rel_schema.h b/sql/server/rel_schema.h --- a/sql/server/rel_schema.h +++ b/sql/server/rel_schema.h @@ -17,7 +17,7 @@ extern sql_rel *rel_schemas(sql_query *q extern sql_rel *rel_table(mvc *sql, int cat_type, const char *sname, sql_table *t, int nr); extern sql_rel *rel_create_table(sql_query *query, int temp, - const char *sname, const char *name, + const char *sname, const char *name, bool global, symbol *table_elements_or_subquery, int commit_action, const char *loc, const char *username, const char *passwd, diff --git a/sql/test/scoping/Tests/scoping01.sql b/sql/test/scoping/Tests/scoping01.sql --- a/sql/test/scoping/Tests/scoping01.sql +++ b/sql/test/scoping/Tests/scoping01.sql @@ -125,6 +125,30 @@ BEGIN END IF; RETURN SELECT a FROM x; END; --error, multiple declarations of table x; +----------------------------------------------------------------------------- +DECLARE TABLE atest (a int); +INSERT INTO atest VALUES (1); + +CREATE OR REPLACE FUNCTION scoping3() RETURNS TABLE(a int) +BEGIN + DECLARE TABLE atest (a int); -- allowed, the table atest from scoping3 is unrelated to "atest" from the global scope + INSERT INTO x VALUES (2); + RETURN x; +END; + +SELECT a FROM atest; + -- 1 +SELECT a FROM scoping3(); + -- 2 + +CREATE OR REPLACE FUNCTION scoping4() RETURNS TABLE(a int) +BEGIN + DECLARE tableydoesntexist int; + RETURN tableydoesntexist; --error, no table named "tableydoesntexist" exists +END; + +DROP TABLE atest; +DROP FUNCTION scoping3; ------------------------------------------------------------------------------ -- A table returning function or view to list the session's variables select "name", schemaname, "type", currentvalue, accessmode from sys.vars(); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list