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