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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to