Changeset: 77ff6e9bae1e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=77ff6e9bae1e
Added Files:
        sql/test/miscellaneous/Tests/vessels.sql
        sql/test/miscellaneous/Tests/vessels.stable.err
        sql/test/miscellaneous/Tests/vessels.stable.out
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_psm.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/server/sql_parser.y
        sql/test/BugTracker-2015/Tests/window_function_crash.Bug-3861.stable.err
        sql/test/miscellaneous/Tests/All
        sql/test/pg_regress/Tests/arrays.stable.err
        sql/test/subquery/Tests/subquery4.stable.err
        sql/test/subquery/Tests/subquery6.sql
        sql/test/subquery/Tests/subquery6.stable.err
        sql/test/subquery/Tests/subquery6.stable.out
Branch: default
Log Message:

Merged with Jun2020


diffs (truncated from 968 to 300 lines):

diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -155,8 +155,6 @@ exp_compare(sql_allocator *sa, sql_exp *
        if (e == NULL)
                return NULL;
        e->card = MAX(l->card,r->card);
-       if (e->card == CARD_ATOM && !exp_is_atom(l))
-               e->card = CARD_AGGR;
        e->l = l;
        e->r = r;
        e->flag = cmptype;
@@ -169,12 +167,10 @@ exp_compare2(sql_allocator *sa, sql_exp 
        sql_exp *e = exp_create(sa, e_cmp);
        if (e == NULL)
                return NULL;
+       assert(f);
        e->card = MAX(MAX(l->card,r->card),f->card);
-       if (e->card == CARD_ATOM && !exp_is_atom(l))
-               e->card = CARD_AGGR;
        e->l = l;
        e->r = r;
-       assert(f);
        e->f = f;
        e->flag = cmptype;
        return e;
@@ -252,30 +248,19 @@ exp_in_func(mvc *sql, sql_exp *le, sql_e
 }
 
 sql_exp *
-exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp *oe, const char 
*compareop, int quantifier)
+exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, 
int quantifier)
 {
-       sql_subfunc *cmp_func = NULL;
+       sql_subfunc *cmp_func = sql_bind_func(sql->sa, NULL, compareop, 
exp_subtype(le), exp_subtype(le), F_FUNC);
        sql_exp *e;
-
-       if (!oe) {
-               cmp_func = sql_bind_func(sql->sa, NULL, compareop, 
exp_subtype(le), exp_subtype(le), F_FUNC);
-               assert(cmp_func);
-               e = exp_binop(sql->sa, le, re, cmp_func);
-       } else {
-               list *types = sa_list(sql->sa), *args = sa_list(sql->sa);
-               append(types, exp_subtype(le));
-               append(types, exp_subtype(le));
-               append(types, exp_subtype(le));
-               append(args, le);
-               append(args, re);
-               append(args, oe);
-               cmp_func = sql_bind_func_(sql->sa, NULL, compareop, types, 
F_FUNC);
-               assert(cmp_func);
-               e = exp_op(sql->sa, args, cmp_func);
-       }
+ 
+       assert(cmp_func);
+       e = exp_binop(sql->sa, le, re, cmp_func);
        if (e) {
                e->flag = quantifier;
-               e->card = le->card;
+               if (quantifier)
+                       e->card = le->card; /* At ANY and ALL operators, the 
cardinality on the right side is ignored */
+               else
+                       e->card = MAX(le->card, re->card);
        }
        return e;
 }
@@ -314,8 +299,6 @@ exp_op( sql_allocator *sa, list *l, sql_
        if (e == NULL)
                return NULL;
        e->card = exps_card(l);
-       if (!l || list_length(l) == 0)
-               e->card = CARD_ATOM; /* unop returns a single atom */
        e->l = l;
        e->f = f;
        e->semantics = f->func->semantics;
@@ -336,8 +319,6 @@ exp_rank_op( sql_allocator *sa, list *l,
        if (e == NULL)
                return NULL;
        e->card = exps_card(l);
-       if (!l || list_length(l) == 0)
-               e->card = CARD_ATOM; /* unop returns a single atom */
        e->l = l;
        e->r = append(append(sa_list(sa), gbe), obe);
        e->f = f;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -36,7 +36,7 @@ extern sql_exp *exp_filter(sql_allocator
 extern sql_exp *exp_or(sql_allocator *sa, list *l, list *r, int anti);
 extern sql_exp *exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype);
 extern sql_exp *exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int 
anyequal, int is_tuple);
-extern sql_exp *exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp 
*oe, const char *compareop, int quantifier);
+extern sql_exp *exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const 
char *compareop, int quantifier);
 
 #define exp_fromtype(e)        ((list*)e->r)->h->data
 #define exp_totype(e)  ((list*)e->r)->h->next->data
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
@@ -16,6 +16,15 @@
 #include "rel_updates.h"
 #include "sql_privileges.h"
 
+#define psm_zero_or_one(exp) \
+       do { \
+               if (exp && exp->card > CARD_AGGR) { \
+                       sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", exp_subtype(exp), NULL, F_AGGR); \
+                       assert(zero_or_one); \
+                       exp = exp_aggr1(sql->sa, exp, zero_or_one, 0, 0, 
CARD_ATOM, has_nil(exp)); \
+               } \
+       } while(0)
+
 static list *sequential_block(sql_query *query, sql_subtype *restype, list 
*restypelist, dlist *blk, char *opt_name, int is_func);
 
 sql_rel *
@@ -94,13 +103,9 @@ psm_set_exp(sql_query *query, dnode *n)
 
                if (!resolve_variable_on_scope(sql, s, sname, vname, &var, &a, 
&tpe, &level, "SET"))
                        return NULL;
-               if (!(e = rel_value_exp2(query, &rel, val, sql_sel | 
sql_psm_set, ek)))
+               if (!(e = rel_value_exp2(query, &rel, val, sql_sel | sql_psm, 
ek)))
                        return NULL;
-               if (e->card > CARD_AGGR) {
-                       sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", exp_subtype(e), NULL, F_AGGR);
-                       assert(zero_or_one);
-                       e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(e));
-               }
+               psm_zero_or_one(e);
 
                if (!(e = rel_check_type(sql, tpe, rel, e, type_cast)))
                        return NULL;
@@ -255,14 +260,14 @@ rel_psm_while_do( sql_query *query, sql_
                sql_rel *rel = NULL;
                exp_kind ek = {type_value, card_value, FALSE};
 
-               cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel, 
ek);
+               cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel 
| sql_psm, ek);
+               psm_zero_or_one(cond);
                n = n->next;
                whilestmts = sequential_block(query, res, restypelist, 
n->data.lval, n->next->data.sval, is_func);
 
                if (sql->session->status || !cond || !whilestmts)
                        return NULL;
 
-               assert(!rel);
                return exp_while( sql->sa, cond, whilestmts );
        }
        return NULL;
@@ -287,7 +292,8 @@ psm_if_then_else( sql_query *query, sql_
                sql_rel *rel = NULL;
                exp_kind ek = {type_value, card_value, FALSE};
 
-               cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel, 
ek);
+               cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel 
| sql_psm, ek);
+               psm_zero_or_one(cond);
                n = n->next;
                ifstmts = sequential_block(query, res, restypelist, 
n->data.lval, NULL, is_func);
                n = n->next;
@@ -296,7 +302,6 @@ psm_if_then_else( sql_query *query, sql_
                if (sql->session->status || !cond || !ifstmts)
                        return NULL;
 
-               assert(!rel);
                return append(sa_list(sql->sa), exp_if( sql->sa, cond, ifstmts, 
elsestmts));
        } else { /* else */
                symbol *e = elseif->data.sym;
@@ -320,7 +325,8 @@ rel_psm_if_then_else( sql_query *query, 
                sql_rel *rel = NULL;
                exp_kind ek = {type_value, card_value, FALSE};
 
-               cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel, 
ek);
+               cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel 
| sql_psm, ek);
+               psm_zero_or_one(cond);
                n = n->next;
                ifstmts = sequential_block(query, res, restypelist, 
n->data.lval, NULL, is_func);
                n = n->next;
@@ -328,7 +334,6 @@ rel_psm_if_then_else( sql_query *query, 
                if (sql->session->status || !cond || !ifstmts)
                        return NULL;
 
-               assert(!rel);
                return exp_if( sql->sa, cond, ifstmts, elsestmts);
        }
        return NULL;
@@ -366,30 +371,28 @@ rel_psm_case( sql_query *query, sql_subt
                list *else_stmt = NULL;
                sql_rel *rel = NULL;
                exp_kind ek = {type_value, card_value, FALSE};
-               sql_exp *v = rel_value_exp(query, &rel, case_value, sql_sel, 
ek);
+               sql_exp *v = rel_value_exp(query, &rel, case_value, sql_sel | 
sql_psm, ek);
 
+               psm_zero_or_one(v);
                if (!v)
                        return NULL;
-               if (rel)
-                       return sql_error(sql, 02, SQLSTATE(42000) "CASE: No 
SELECT statements allowed within the CASE condition");
-               if (else_statements) {
-                       if (!(else_stmt = sequential_block(query, res, 
restypelist, else_statements, NULL, is_func)))
-                               return NULL;
-               }
+               if (else_statements && !(else_stmt = sequential_block(query, 
res, restypelist, else_statements, NULL, is_func)))
+                       return NULL;
+
                n = when_statements->h;
                while(n) {
                        dnode *m = n->data.sym->data.lval->h;
-                       sql_exp *cond=0, *when_value = rel_value_exp(query, 
&rel, m->data.sym, sql_sel, ek);
+                       sql_exp *cond=0, *when_value = rel_value_exp(query, 
&rel, m->data.sym, sql_sel | sql_psm, ek);
                        list *if_stmts = NULL;
                        sql_exp *case_stmt = NULL;
 
-                       if (!when_value || rel ||
+                       psm_zero_or_one(when_value);
+                       if (!when_value ||
                           (cond = rel_binop_(sql, rel, v, when_value, NULL, 
"=", card_value)) == NULL ||
                           (if_stmts = sequential_block(query, res, 
restypelist, m->next->data.lval, NULL, is_func)) == NULL ) {
-                               if (rel)
-                                       return sql_error(sql, 02, 
SQLSTATE(42000) "CASE: No SELECT statements allowed within the CASE condition");
                                return NULL;
                        }
+                       psm_zero_or_one(cond);
                        case_stmt = exp_if(sql->sa, cond, if_stmts, NULL);
                        list_append(case_stmts, case_stmt);
                        n = n->next;
@@ -404,23 +407,21 @@ rel_psm_case( sql_query *query, sql_subt
                dlist *else_statements = n->next->data.lval;
                list *else_stmt = NULL;
 
-               if (else_statements) {
-                       if (!(else_stmt = sequential_block(query, res, 
restypelist, else_statements, NULL, is_func)))
-                               return NULL;
-               }
+               if (else_statements && !(else_stmt = sequential_block(query, 
res, restypelist, else_statements, NULL, is_func)))
+                       return NULL;
+
                n = whenlist->h;
                while(n) {
                        dnode *m = n->data.sym->data.lval->h;
                        sql_rel *rel = NULL;
                        exp_kind ek = {type_value, card_value, FALSE};
-                       sql_exp *cond = rel_logical_value_exp(query, &rel, 
m->data.sym, sql_sel, ek);
+                       sql_exp *cond = rel_logical_value_exp(query, &rel, 
m->data.sym, sql_sel | sql_psm, ek);
                        list *if_stmts = NULL;
                        sql_exp *case_stmt = NULL;
 
-                       if (!cond || rel ||
+                       psm_zero_or_one(cond);
+                       if (!cond ||
                           (if_stmts = sequential_block(query, res, 
restypelist, m->next->data.lval, NULL, is_func)) == NULL ) {
-                               if (rel)
-                                       return sql_error(sql, 02, 
SQLSTATE(42000) "CASE: No SELECT statements allowed within the CASE condition");
                                return NULL;
                        }
                        case_stmt = exp_if(sql->sa, cond, if_stmts, NULL);
@@ -1447,7 +1448,9 @@ psm_analyze(sql_query *query, char *anal
        append(exps, mm_exp = exp_atom_int(sql->sa, minmax));
        append(tl, exp_subtype(mm_exp));
        if (sample) {
-               sample_exp = rel_value_exp(query, NULL, sample, 0, ek);
+               sql_rel *rel = NULL;
+               sample_exp = rel_value_exp(query, &rel, sample, sql_sel | 
sql_psm, ek);
+               psm_zero_or_one(sample_exp);
                if (!sample_exp || !(sample_exp = rel_check_type(sql, 
sql_bind_localtype("lng"), NULL, sample_exp, type_cast)))
                        return NULL;
        } else {
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
@@ -2307,3 +2307,25 @@ rel_visitor_bottomup(mvc *sql, sql_rel *
 {
        return rel_visitor(sql, rel, rel_rewriter, changes, false);
 }
+
+static sql_exp *
+exp_check_has_analytics(mvc *sql, sql_rel *rel, sql_exp *e, int depth, int 
*changes)
+{
+       (void)sql; (void)rel; (void)depth;
+       if (e && e->type == e_func) {
+               sql_subfunc *f = e->f;
+
+               if (f && f->func && f->func->type == F_ANALYTIC)
+                       (*changes)++;
+       }
+       return e;
+}
+
+int
+exps_have_analytics(mvc *sql, list *exps)
+{
+       int changes = 0;
+    (void)exps_exp_visitor(sql, NULL, exps, 0, &exp_check_has_analytics, 
&changes, 1);
+       return changes;
+}
+
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -26,7 +26,7 @@
 #define sql_outer        (1 << 10) //ORed
 #define sql_group_totals (1 << 11) //ORed
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to