Changeset: b878c661ab99 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b878c661ab99
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_statement.c
        sql/include/sql_catalog.h
        sql/server/rel_psm.c
        sql/server/rel_schema.c
        sql/server/rel_schema.h
        sql/server/rel_select.c
        sql/server/sql_var.c
        sql/storage/sql_storage.h
        sql/test/scoping/Tests/scoping01.sql
Branch: scoping
Log Message:

Fixed handle of declared tables on UDFs. Also fixed bug where a declared table 
on the global scope couldn't be returned on a table producing function


diffs (234 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -1127,7 +1127,7 @@ stmt_col( backend *be, sql_column *c, st
 
        if (isTable(c->t) && c->t->access != TABLE_READONLY &&
           (!isNew(c) || !isNew(c->t) /* alter */) &&
-          (c->t->persistence == SQL_PERSIST || isDeclaredTable(c->t)) && 
!c->t->commit_action) {
+          (c->t->persistence == SQL_PERSIST || !isDeclaredTableOnStack(c->t)) 
&& !c->t->commit_action) {
                stmt *i = stmt_bat(be, c, RD_INS, 0);
                stmt *u = stmt_bat(be, c, RD_UPD_ID, part);
                sc = stmt_project_delta(be, sc, u, i);
@@ -1146,7 +1146,7 @@ stmt_idx( backend *be, sql_idx *i, stmt 
 
        if (isTable(i->t) && i->t->access != TABLE_READONLY &&
           (!isNew(i) || !isNew(i->t) /* alter */) &&
-          (i->t->persistence == SQL_PERSIST || isDeclaredTable(i->t)) && 
!i->t->commit_action) {
+          (i->t->persistence == SQL_PERSIST || !isDeclaredTableOnStack(i->t)) 
&& !i->t->commit_action) {
                stmt *ic = stmt_idxbat(be, i, RD_INS, 0);
                stmt *u = stmt_idxbat(be, i, RD_UPD_ID, part);
                sc = stmt_project_delta(be, sc, u, ic);
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -513,7 +513,7 @@ stmt_tid(backend *be, sql_table *t, int 
        MalBlkPtr mb = be->mb;
        InstrPtr q;
 
-       if (isDeclaredTable(t) && stack_find_table(be->mvc, t->s, t->base.name) 
&& t->data) { /* declared table */
+       if (isDeclaredTableOnStack(t) && t->data) { /* declared table */
                stmt *s = stmt_create(be->mvc->sa, st_tid);
                int *l = t->data;
 
@@ -564,7 +564,7 @@ stmt_bat(backend *be, sql_column *c, int
        InstrPtr q;
 
        /* for read access tid.project(col) */
-       if (isDeclaredTable(c->t) && stack_find_table(be->mvc, c->t->s, 
c->t->base.name) && c->t->data) { /* declared table */
+       if (isDeclaredTableOnStack(c->t) && c->t->data) { /* declared table */
                stmt *s = stmt_create(be->mvc->sa, st_bat);
                int *l = c->t->data;
 
@@ -693,7 +693,7 @@ stmt_append_col(backend *be, sql_column 
        if (b->nr < 0)
                return NULL;
 
-       if (isDeclaredTable(c->t) && stack_find_table(be->mvc, c->t->s, 
c->t->base.name) && c->t->data) { /* declared table */
+       if (isDeclaredTableOnStack(c->t) && c->t->data) { /* declared table */
                int *l = c->t->data;
 
                if (c->colnr == 0) { /* append to tid column */
@@ -784,7 +784,7 @@ stmt_update_col(backend *be, sql_column 
        if (tids->nr < 0 || upd->nr < 0)
                return NULL;
 
-       if (isDeclaredTable(c->t) && stack_find_table(be->mvc, c->t->s, 
c->t->base.name) && c->t->data) { /* declared table */
+       if (isDeclaredTableOnStack(c->t) && c->t->data) { /* declared table */
                int *l = c->t->data;
 
                q = newStmt(mb, batRef, updateRef);
@@ -872,7 +872,7 @@ stmt_delete(backend *be, sql_table *t, s
        if (tids->nr < 0)
                return NULL;
 
-       if (isDeclaredTable(t) && stack_find_table(be->mvc, t->s, t->base.name) 
&& t->data) { /* declared table */
+       if (isDeclaredTableOnStack(t) && t->data) { /* declared table */
                int *l = t->data;
 
                q = newStmt(mb, batRef, deleteRef);
@@ -2763,7 +2763,7 @@ stmt_table_clear(backend *be, sql_table 
        MalBlkPtr mb = be->mb;
        InstrPtr q = NULL;
 
-       if (isDeclaredTable(t) && stack_find_table(be->mvc, t->s, t->base.name) 
&& t->data) { /* declared table */
+       if (isDeclaredTableOnStack(t) && t->data) { /* declared table */
                int *l = t->data; 
                int cnt = list_length(t->columns.set)+1, i;
 
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -125,6 +125,7 @@ typedef enum sql_dependency {
 #define PARTITION_LIST        2
 #define PARTITION_COLUMN      4
 #define PARTITION_EXPRESSION  8
+#define DECLARED_TABLE_ON_STACK  16
 
 #define STORAGE_MAX_VALUE_LENGTH 2048
 
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
@@ -476,20 +476,48 @@ rel_psm_return( sql_query *query, sql_su
                ek.card = card_relation;
        else if (return_sym->token == SQL_TABLE)
                return sql_error(sql, 02, SQLSTATE(42000) "RETURN: TABLE return 
not allowed for non table returning functions");
-       res = rel_value_exp2(query, &rel, return_sym, sql_sel, ek);
-       if (!res)
-               return NULL;
-       if (!rel && exp_is_rel(res)) {
-               rel = exp_rel_get_rel(sql->sa, res);
-               if (rel && !restypelist && !is_groupby(rel->op)) { /* On 
regular functions return zero or 1 rows for every row */
-                       rel->card = CARD_MULTI; 
-                       rel = rel_zero_or_one(sql, rel, ek);
-                       if (list_length(rel->exps) != 1)
-                               return sql_error(sql, 02, SQLSTATE(42000) 
"RETURN: must return a single column");
-                       res = exp_ref(sql->sa, (sql_exp*) rel->exps->t->data);
-                       requires_proj = true;
+       if (return_sym->token == SQL_COLUMN && restypelist) { /* RETURN x; 
where x is a reference to a table */
+               dlist *l = return_sym->data.lval;
+               const char *sname = qname_schema(l);
+               const char *tname = qname_schema_object(l);
+               sql_schema *s = cur_schema(sql);
+               sql_table *t;
+
+               if (sname && !(s = mvc_bind_schema(sql, sname)))
+                       return sql_error(sql, 02, SQLSTATE(3F000) "RETURN: no 
such schema '%s'", sname);
+
+               if ((t = stack_find_table(sql, s, tname))) {
+                       rel = rel_table(sql, ddl_create_table, s->base.name, t, 
SQL_DECLARED_TABLE);
+               } else if ((t = find_sql_table(s, tname))) {
+                       rel = rel_basetable(sql, t, t->base.name);
+                       for (node *n = rel->exps->h ; n ; n = n->next) {
+                               sql_exp *e = (sql_exp *) n->data;       
+                               const char *oname = e->r;
+
+                               if (!strcmp(oname, TID)) {
+                                       list_remove_node(rel->exps, n);
+                                       break;
+                               }
+                       }
+               } else
+                       return sql_error(sql, 02, SQLSTATE(42S02) "RETURN: no 
such table '%s'", tname);
+       } else { /* other cases */
+               res = rel_value_exp2(query, &rel, return_sym, sql_sel, ek);
+               if (!res)
+                       return NULL;
+               if (!rel && exp_is_rel(res)) {
+                       rel = exp_rel_get_rel(sql->sa, res);
+                       if (rel && !restypelist && !is_groupby(rel->op)) { /* 
On regular functions return zero or 1 rows for every row */
+                               rel->card = CARD_MULTI;
+                               rel = rel_zero_or_one(sql, rel, ek);
+                               if (list_length(rel->exps) != 1)
+                                       return sql_error(sql, 02, 
SQLSTATE(42000) "RETURN: must return a single column");
+                               res = exp_ref(sql->sa, (sql_exp*) 
rel->exps->t->data);
+                               requires_proj = true;
+                       }
                }
        }
+
        if (ek.card != card_relation && (!restype || (res = rel_check_type(sql, 
restype, rel, res, type_equal)) == NULL))
                return (!restype)?sql_error(sql, 02, SQLSTATE(42000) "RETURN: 
return type does not match"):NULL;
        else if (ek.card == card_relation && !rel)
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
@@ -36,7 +36,7 @@ static sql_table *
        return tt;
 }
 
-static sql_rel *
+sql_rel *
 rel_table(mvc *sql, int cat_type, const char *sname, sql_table *t, int nr)
 {
        sql_rel *rel = rel_create(sql->sa);
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
@@ -14,6 +14,8 @@
 
 extern sql_rel *rel_schemas(sql_query *query, symbol *sym);
 
+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,
                                 symbol *table_elements_or_subquery,
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1212,13 +1212,6 @@ rel_column_ref(sql_query *query, sql_rel
                        if (exp && outer && is_join(outer->op))
                                set_dependent(outer);
                }
-               if (!exp) { /* Try a CTE */
-                       sql_rel *r = stack_find_rel_view(sql, name); /* find 
one */
-                       if (r) {
-                               *rel = r;
-                               return exp_rel(sql, r);
-                       }
-               }
                if (!exp) { /* If no column was found, try a variable or 
parameter */
                        sql_arg *a = NULL;
                        sql_var *var = NULL;
diff --git a/sql/server/sql_var.c b/sql/server/sql_var.c
--- a/sql/server/sql_var.c
+++ b/sql/server/sql_var.c
@@ -155,6 +155,7 @@ frame_push_table(mvc *sql, sql_table *t)
        if (!slt)
                return NULL;
        slt->table = t;
+       t->properties |= DECLARED_TABLE_ON_STACK;
        if (!f->tables && !(f->tables = list_create(destroy_sql_local_table))) {
                _DELETE(slt);
                return NULL;
diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -23,6 +23,7 @@
 #define isGlobalTemp(x)  ((x)->persistence==SQL_GLOBAL_TEMP)
 #define isTempSchema(x)  (strcmp((x)->base.name, "tmp") == 0)
 #define isDeclaredTable(x)  ((x)->persistence==SQL_DECLARED_TABLE)
+#define isDeclaredTableOnStack(x)  (isDeclaredTable(x) && ((x)->properties & 
DECLARED_TABLE_ON_STACK) == DECLARED_TABLE_ON_STACK)
 
 extern int catalog_version;
 
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
@@ -80,6 +80,14 @@ SELECT tests_scopes3(0), tests_scopes3(1
 SET "optimizer" = (SELECT "aux");
 DROP FUNCTION tests_scopes3(INT);
 ------------------------------------------------------------------------------
+create function tests_scopes4() returns int begin declare table y (a int, b 
int); return select y; end; --error
+create function tests_scopes4() returns table (i integer, s string) begin 
return select tmp2; end; --error
+
+create function tests_scopes4() returns table (i integer, s string) begin 
return tmp2; end; --possible, return the contents of tmp2
+select * from tests_scopes4();
+
+DROP FUNCTION tests_scopes4;
+------------------------------------------------------------------------------
 CREATE OR REPLACE FUNCTION scoping(input INT) RETURNS INT 
 BEGIN
        DECLARE x int;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to