Changeset: 33b3ac62dc82 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=33b3ac62dc82
Modified Files:
sql/backends/monet5/rel_bin.c
sql/include/sql_relation.h
sql/rel.txt
sql/server/rel_dump.c
sql/server/rel_optimizer.c
sql/server/rel_rel.c
sql/server/rel_unnest.c
sql/test/subquery/Tests/subquery3.sql
sql/test/subquery/Tests/subquery4.sql
sql/test/subquery/Tests/subquery4.stable.err
sql/test/subquery/Tests/subquery4.stable.out
sql/test/sys-schema/Tests/systemfunctions.stable.out
sql/test/sys-schema/Tests/systemfunctions.stable.out.int128
Branch: default
Log Message:
Merged with linear-hashing
diffs (truncated from 335 to 300 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
@@ -1613,7 +1613,7 @@ rel2bin_table(backend *be, sql_rel *rel,
node *en, *n;
sql_exp *op = rel->r;
- if (rel->flag == 2) {
+ if (rel->flag == TRIGGER_WRAPPER) {
trigger_input *ti = rel->l;
l = sa_list(sql->sa);
@@ -1693,11 +1693,7 @@ rel2bin_table(backend *be, sql_rel *rel,
}
}
}
- if (rel->flag == TABLE_PROD_FUNC && sub && sub->nrcols) {
- assert(0);
- list_merge(l, sub->op4.lval, NULL);
- osub = sub;
- }
+ assert(rel->flag != TABLE_PROD_FUNC || !sub || !(sub->nrcols));
sub = stmt_list(be, l);
} else if (rel->l) { /* handle sub query via function */
int i;
@@ -3614,7 +3610,7 @@ sql_stack_add_inserted( mvc *sql, const
append(exps, ne);
}
- r = rel_table_func(sql->sa, NULL, NULL, exps, 2);
+ r = rel_table_func(sql->sa, NULL, NULL, exps, TRIGGER_WRAPPER);
r->l = ti;
return stack_push_rel_view(sql, name, r) ? 1 : 0;
@@ -4561,7 +4557,7 @@ sql_stack_add_updated(mvc *sql, const ch
append(exps, ne);
}
}
- r = rel_table_func(sql->sa, NULL, NULL, exps, 2);
+ r = rel_table_func(sql->sa, NULL, NULL, exps, TRIGGER_WRAPPER);
r->l = ti;
/* put single table into the stack with 2 names, needed for the psm
code */
@@ -4837,7 +4833,7 @@ sql_stack_add_deleted(mvc *sql, const ch
append(exps, ne);
}
- r = rel_table_func(sql->sa, NULL, NULL, exps, 2);
+ r = rel_table_func(sql->sa, NULL, NULL, exps, TRIGGER_WRAPPER);
r->l = ti;
return stack_push_rel_view(sql, name, r) ? 1 : 0;
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -59,8 +59,11 @@ typedef struct expression {
void *p; /* properties for the optimizer */
} sql_exp;
-#define TABLE_PROD_FUNC 0
-#define TABLE_FROM_RELATION 1
+#define TABLE_PROD_FUNC 1
+#define TABLE_FROM_RELATION 2
+#define TRIGGER_WRAPPER 4
+
+#define IS_TABLE_PROD_FUNC(X) ((X & TABLE_PROD_FUNC) == TABLE_PROD_FUNC)
/* or-ed with the above TABLE_PROD_FUNC */
#define UPD_COMP 2
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -5,12 +5,12 @@ BASETABLE
-> l (sql_table)
TABLE (card MULTI)
- -> flags TABLE_PROD_FUNC, TABLE_FROM_RELATION
+ -> flags TABLE_PROD_FUNC, TABLE_FROM_RELATION, TRIGGER_WRAPPER
cases
TABLE_PROD_FUNC) TABLE producing function
TABLE_FROM_RELATION) RELATIONAL subquery which is
dynamically wrapped
into function call (needed of remote calls)
- 2) WRAPPER for triggers inserts, deletes and updates
(new/old values)
+ TRIGGER_WRAPPER) for triggers inserts, deletes and
updates (new/old values)
flags
r is list of stmts
-> exps is list of column expressions (also used for aliases)
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -411,7 +411,7 @@ rel_print_(mvc *sql, stream *fout, sql_
if (rel->r)
exp_print(sql, fout, rel->r, depth, refs, 1, 0);
if (rel->l) {
- if (rel->flag == 2)
+ if (rel->flag == TRIGGER_WRAPPER)
mnstr_printf(fout, "rel_dump not yet
implemented for trigger input");
else
rel_print_(sql, fout, rel->l, depth+1, refs,
decorate);
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -258,7 +258,7 @@ rel_properties(mvc *sql, global_props *g
switch (rel->op) {
case op_basetable:
case op_table:
- if (rel->op == op_table && rel->l && rel->flag != 2)
+ if (rel->op == op_table && rel->l && rel->flag !=
TRIGGER_WRAPPER)
rel_properties(sql, gp, rel->l);
break;
case op_join:
@@ -6606,7 +6606,7 @@ rel_mark_used(mvc *sql, sql_rel *rel, in
case op_basetable:
case op_table:
- if (rel->op == op_table && rel->l && rel->flag != 2) {
+ if (rel->op == op_table && rel->l && rel->flag !=
TRIGGER_WRAPPER) {
rel_used(rel);
if (rel->r)
exp_mark_used(rel->l, rel->r, 0);
@@ -6824,7 +6824,7 @@ rel_dce_refs(mvc *sql, sql_rel *rel, lis
case op_groupby:
case op_select:
- if (rel->l && (rel->op != op_table || rel->flag != 2))
+ if (rel->l && (rel->op != op_table || rel->flag !=
TRIGGER_WRAPPER))
rel_dce_refs(sql, rel->l, refs);
break;
@@ -6876,7 +6876,7 @@ rel_dce_down(mvc *sql, sql_rel *rel, int
case op_basetable:
case op_table:
- if (skip_proj && rel->l && rel->op == op_table && rel->flag !=
2)
+ if (skip_proj && rel->l && rel->op == op_table && rel->flag !=
TRIGGER_WRAPPER)
rel->l = rel_dce_down(sql, rel->l, 0);
if (!skip_proj)
rel_dce_sub(sql, rel);
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -945,6 +945,7 @@ rel_table_func(sql_allocator *sa, sql_re
if(!rel)
return NULL;
+ assert(kind > 0);
rel->flag = kind;
rel->l = l; /* relation before call */
rel->r = f; /* expression (table func call) */
@@ -1704,7 +1705,7 @@ rel_deps(mvc *sql, sql_rel *r, list *ref
}
} break;
case op_table: {
- if ((r->flag == 0 || r->flag == 1) && r->r) { /* table
producing function, excluding rel_relational_func cases */
+ if ((IS_TABLE_PROD_FUNC(r->flag) || r->flag ==
TABLE_FROM_RELATION) && r->r) { /* table producing function, excluding
rel_relational_func cases */
sql_exp *op = r->r;
sql_subfunc *f = op->f;
cond_append(l, &f->func->base.id);
@@ -1899,8 +1900,14 @@ rel_exp_visitor(mvc *sql, sql_rel *rel,
switch(rel->op){
case op_basetable:
+ break;
case op_table:
- return rel;
+ if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag ==
TABLE_FROM_RELATION) {
+ if (rel->l)
+ if ((rel->l = rel_exp_visitor(sql, rel->l,
exp_rewriter)) == NULL)
+ return NULL;
+ }
+ break;
case op_ddl:
if (rel->flag == ddl_output || rel->flag == ddl_create_seq ||
rel->flag == ddl_alter_seq) {
if (rel->l)
@@ -1916,8 +1923,7 @@ rel_exp_visitor(mvc *sql, sql_rel *rel,
} else if (rel->flag == ddl_psm) {
break;
}
- return rel;
-
+ break;
case op_insert:
case op_update:
case op_delete:
@@ -2066,10 +2072,13 @@ rel_visitor(mvc *sql, sql_rel *rel, rel_
switch(rel->op){
case op_basetable:
+ break;
case op_table:
- if (rel->op == op_table && rel->l && rel->flag != 2)
- if ((rel->l = func(sql, rel->l, rel_rewriter, changes))
== NULL)
- return NULL;
+ if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag ==
TABLE_FROM_RELATION) {
+ if (rel->l)
+ if ((rel->l = func(sql, rel->l, rel_rewriter,
changes)) == NULL)
+ return NULL;
+ }
break;
case op_ddl:
if (rel->flag == ddl_output || rel->flag == ddl_create_seq ||
rel->flag == ddl_alter_seq) {
@@ -2087,8 +2096,7 @@ rel_visitor(mvc *sql, sql_rel *rel, rel_
if ((rel->exps = exps_rel_visitor(sql, rel->exps,
rel_rewriter, changes, topdown)) == NULL)
return NULL;
}
- return rel;
-
+ break;
case op_insert:
case op_update:
case op_delete:
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -288,9 +288,9 @@ rel_freevar(mvc *sql, sql_rel *rel)
return NULL;
case op_table: {
sql_exp *call = rel->r;
- if (rel->flag != 2 && rel->l)
+ if (rel->flag != TRIGGER_WRAPPER && rel->l)
lexps = rel_freevar(sql, rel->l);
- exps = (rel->flag != 2 && call)?exps_freevar(sql, call->l):NULL;
+ exps = (rel->flag != TRIGGER_WRAPPER && call)?exps_freevar(sql,
call->l):NULL;
return merge_freevar(exps, lexps);
}
case op_union:
diff --git a/sql/test/subquery/Tests/subquery3.sql
b/sql/test/subquery/Tests/subquery3.sql
--- a/sql/test/subquery/Tests/subquery3.sql
+++ b/sql/test/subquery/Tests/subquery3.sql
@@ -523,6 +523,18 @@ SELECT
FROM integers i1;
-- 1
+SELECT
+ (SELECT i2.i FROM (VALUES (i1.i)) as i2(i))
+FROM integers i1;
+ -- 1
+ -- 2
+ -- 3
+ -- NULL
+
+SELECT
+ (SELECT i2.i FROM (VALUES (i1.i), (i1.i)) as i2(i))
+FROM integers i1; --error, more than one row returned by a subquery used as an
expression
+
/* We shouldn't allow the following internal functions/procedures to be called
from regular queries */
--SELECT "identity"(col1) FROM another_T;
--SELECT "rowid"(col1) FROM another_T;
diff --git a/sql/test/subquery/Tests/subquery4.sql
b/sql/test/subquery/Tests/subquery4.sql
--- a/sql/test/subquery/Tests/subquery4.sql
+++ b/sql/test/subquery/Tests/subquery4.sql
@@ -48,6 +48,15 @@ FROM integers i1;
-- 4
-- NULL
+SELECT 1 FROM evilfunction((SELECT MAX(1) OVER ()));
+ -- 1
+
+SELECT 1 FROM evilfunction((SELECT MAX(1) OVER () UNION ALL SELECT 1));
--error, more than one row returned by a subquery used as an expression
+
+SELECT
+ (SELECT 1 FROM evilfunction((SELECT MAX(1) OVER () UNION ALL SELECT 1)))
+FROM integers i1; --error, more than one row returned by a subquery used as an
expression
+
SELECT i2.i FROM evilfunction((SELECT MAX(1) OVER ())) as i2(i);
-- 1
diff --git a/sql/test/subquery/Tests/subquery4.stable.err
b/sql/test/subquery/Tests/subquery4.stable.err
--- a/sql/test/subquery/Tests/subquery4.stable.err
+++ b/sql/test/subquery/Tests/subquery4.stable.err
@@ -42,7 +42,13 @@ QUERY = SELECT
FROM integers i1; -- error, window functions are not allowed in
functions in FROM
ERROR = !MAX: window function 'max' not allowed in functions in FROM
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-120241/.s.monetdb.31512
+MAPI = (monetdb) /var/tmp/mtest-448822/.s.monetdb.39899
+QUERY = SELECT
+ (SELECT 1 FROM evilfunction((SELECT MAX(1) OVER () UNION ALL
SELECT 1)))
+ FROM integers i1; --error, more than one row returned by a subquery
used as an expression
+ERROR = !Cardinality violation, scalar value expected
+CODE = 21000
+MAPI = (monetdb) /var/tmp/mtest-448822/.s.monetdb.39899
QUERY = UPDATE another_T SET col1 = MIN(col1); --error, aggregates not allowed
in update set clause
ERROR = !MIN: aggregate functions not allowed in SET clause (use subquery)
CODE = 42000
diff --git a/sql/test/subquery/Tests/subquery4.stable.out
b/sql/test/subquery/Tests/subquery4.stable.out
--- a/sql/test/subquery/Tests/subquery4.stable.out
+++ b/sql/test/subquery/Tests/subquery4.stable.out
@@ -77,6 +77,18 @@ stdout of test 'subquery4` in directory
[ 1 ]
[ 1 ]
[ 1 ]
+#SELECT 1 FROM evilfunction((SELECT MAX(1) OVER ()));
+% . # table_name
+% single_value # name
+% tinyint # type
+% 1 # length
+[ 1 ]
+#SELECT i2.i FROM evilfunction((SELECT MAX(1) OVER ())) as i2(i);
+% .i2 # table_name
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list