Changeset: 0c865bfdba81 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0c865bfdba81
Modified Files:
        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/test/miscellaneous/Tests/simple_selects.sql
        sql/test/miscellaneous/Tests/simple_selects.stable.err
        sql/test/pg_regress/Tests/alter_table.stable.err
        sql/test/subquery/Tests/subquery4.sql
        sql/test/subquery/Tests/subquery4.stable.err
        sql/test/subquery/Tests/subquery4.stable.out
        tools/merovingian/daemon/argvcmds.c
        tools/merovingian/daemon/controlrunner.c
        tools/merovingian/daemon/discoveryrunner.c
        tools/merovingian/daemon/merovingian.c
        tools/merovingian/daemon/multiplex-funnel.c
        tools/merovingian/daemon/multiplex-funnel.h
Branch: default
Log Message:

Merged with Jun2020


diffs (truncated from 685 to 300 lines):

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
@@ -105,8 +105,11 @@ psm_set_exp(sql_query *query, dnode *n)
 
                if (!rel_val)
                        return NULL;
-               if (!is_project(rel_val->op) || dlist_length(vars) != 
list_length(rel_val->exps))
+               if (!is_project(rel_val->op))
+                       return sql_error(sql, 02, SQLSTATE(42000) "SET: The 
subquery is not a projection");
+               if (dlist_length(vars) != list_length(rel_val->exps))
                        return sql_error(sql, 02, SQLSTATE(42000) "SET: Number 
of variables not equal to number of supplied values");
+               rel_val = rel_zero_or_one(sql, rel_val, ek);
 
                b = sa_list(sql->sa);
                append(b, exp_rel(sql, rel_val));
@@ -125,19 +128,12 @@ psm_set_exp(sql_query *query, dnode *n)
                                tpe = stack_find_type(sql, vname);
                        }
 
-                       if (!exp_name(v))
+                       level = stack_find_frame(sql, vname);
+                       if (!exp_name(v)) 
                                exp_label(sql->sa, v, ++sql->label);
                        v = exp_ref(sql->sa, v);
-
-                       level = stack_find_frame(sql, vname);
-                       v = rel_check_type(sql, tpe, rel_val, v, type_cast);
-                       if (!v)
+                       if (!(v = rel_check_type(sql, tpe, rel_val, v, 
type_cast)))
                                return NULL;
-                       if (v->card > CARD_AGGR) {
-                               sql_subfunc *zero_or_one = 
sql_bind_func(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(v), 
NULL, F_AGGR);
-                               assert(zero_or_one);
-                               v = exp_aggr1(sql->sa, v, zero_or_one, 0, 0, 
CARD_ATOM, has_nil(v));
-                       }
                        append(b, exp_set(sql->sa, vname, v, level));
                }
                res = exp_rel(sql, rel_psm_block(sql->sa, b));
@@ -520,6 +516,11 @@ rel_select_into( sql_query *query, symbo
        r = rel_subquery(query, NULL, sq, ek);
        if (!r) 
                return NULL;
+       if (!is_project(r->op))
+               return sql_error(sql, 02, SQLSTATE(42000) "SELECT INTO: The 
subquery is not a projection");
+       if (list_length(r->exps) != dlist_length(into))
+               return sql_error(sql, 02, SQLSTATE(21S01) "SELECT INTO: number 
of values doesn't match number of variables to set");
+       r = rel_zero_or_one(sql, r, ek);
        nl = sa_list(sql->sa);
        append(nl, exp_rel(sql, r));
        for (m = r->exps->h, n = into->h; m && n; m = m->next, n = n->next) {
@@ -530,15 +531,12 @@ rel_select_into( sql_query *query, symbo
 
                if (!stack_find_var(sql, nme)) 
                        return sql_error(sql, 02, SQLSTATE(42000) "SELECT INTO: 
variable '%s' unknown", nme);
-               /* dynamic check for single values */
-               if (v->card > CARD_AGGR) {
-                       sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", exp_subtype(v), NULL, F_AGGR);
-                       assert(zero_or_one);
-                       v = exp_aggr1(sql->sa, v, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(v));
-               }
                tpe = stack_find_type(sql, nme);
                level = stack_find_frame(sql, nme);
-               if (!v || !(v = rel_check_type(sql, tpe, r, v, type_equal)))
+               if (!exp_name(v)) 
+                       exp_label(sql->sa, v, ++sql->label);
+               v = exp_ref(sql->sa, v);
+               if (!(v = rel_check_type(sql, tpe, r, v, type_equal)))
                        return NULL;
                v = exp_set(sql->sa, nme, v, level);
                list_append(nl, v);
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
@@ -1572,6 +1572,55 @@ rel_in_rel(sql_rel *super, sql_rel *sub)
        return 0;
 }
 
+sql_rel*
+rel_parent(sql_rel *rel)
+{
+       if (rel->l && (is_project(rel->op) || rel->op == op_topn || rel->op == 
op_sample)) {
+               sql_rel *l = rel->l;
+               if (is_project(l->op))
+                       return l;
+       }
+       return rel;
+}
+
+sql_exp *
+lastexp(sql_rel *rel) 
+{
+       if (!is_processed(rel) || is_topn(rel->op) || is_sample(rel->op))
+               rel = rel_parent(rel);
+       assert(list_length(rel->exps));
+       assert(is_project(rel->op));
+       return rel->exps->t->data;
+}
+
+sql_rel *
+rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek)
+{
+       if (is_topn(rel->op))
+               rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 
1, 0));
+       if (ek.card < card_set && rel->card > CARD_ATOM) {
+               assert (is_simple_project(rel->op) || is_set(rel->op));
+               list *exps = rel->exps;
+               rel = rel_groupby(sql, rel, NULL);
+               for(node *n = exps->h; n; n=n->next) {
+                       sql_exp *e = n->data;
+                       if (!has_label(e))
+                               exp_label(sql->sa, e, ++sql->label);
+                       sql_subtype *t = exp_subtype(e); /* parameters don't 
have a type defined, for those use 'void' one */
+                       sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, 
F_AGGR);
+
+                       e = exp_ref(sql->sa, e);
+                       e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(e));
+                       (void)rel_groupby_add_aggr(sql, rel, e);
+               }
+       } else {
+               sql_exp *e = lastexp(rel);
+               if (!has_label(e))
+                       exp_label(sql->sa, e, ++sql->label);
+       }
+       return rel;
+}
+
 static sql_rel *
 refs_find_rel(list *refs, sql_rel *rel)
 {
@@ -1786,8 +1835,6 @@ rel_deps(mvc *sql, sql_rel *r, list *ref
                                return rel_deps(sql, r->l, refs, l);
                        if (r->r)
                                return rel_deps(sql, r->r, refs, l);
-               } else if (r->flag == ddl_psm) {
-                       break;
                } else if (r->flag == ddl_create_seq || r->flag == 
ddl_alter_seq) {
                        if (r->l)
                                return rel_deps(sql, r->l, refs, l);
@@ -1962,8 +2009,6 @@ rel_exp_visitor(mvc *sql, sql_rel *rel, 
                        if (rel->r)
                                if ((rel->r = rel_exp_visitor(sql, rel->r, 
exp_rewriter, topdown)) == NULL)
                                        return NULL;
-               } else if (rel->flag == ddl_psm) {
-                       break;
                }
                break;
        case op_insert:
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
@@ -110,6 +110,9 @@ extern sql_rel *rel_add_identity2(mvc *s
 extern sql_exp * rel_find_column( sql_allocator *sa, sql_rel *rel, const char 
*tname, const char *cname );
 
 extern int rel_in_rel(sql_rel *super, sql_rel *sub);
+extern sql_rel *rel_parent(sql_rel *rel);
+extern sql_exp *lastexp(sql_rel *rel);
+extern sql_rel *rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek);
 
 extern list *rel_dependencies(mvc *sql, sql_rel *r);
 extern sql_exp * exps_find_match_exp(list *l, sql_exp *e);
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
@@ -118,27 +118,6 @@ rel_table_projections( mvc *sql, sql_rel
        }
 }
 
-static sql_rel*
-rel_parent( sql_rel *rel )
-{
-       if (rel->l && (is_project(rel->op) || rel->op == op_topn || rel->op == 
op_sample)) {
-               sql_rel *l = rel->l;
-               if (is_project(l->op))
-                       return l;
-       }
-       return rel;
-}
-
-static sql_exp *
-lastexp(sql_rel *rel) 
-{
-       if (!is_processed(rel) || is_topn(rel->op) || is_sample(rel->op))
-               rel = rel_parent(rel);
-       assert(list_length(rel->exps));
-       assert(is_project(rel->op));
-       return rel->exps->t->data;
-}
-
 static sql_exp *
 rel_lastexp(mvc *sql, sql_rel *rel )
 {
@@ -161,34 +140,6 @@ rel_lastexp(mvc *sql, sql_rel *rel )
 }
 
 static sql_rel *
-rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek)
-{
-       if (is_topn(rel->op))
-               rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 
1, 0));
-       if (ek.card < card_set && rel->card > CARD_ATOM) {
-               assert (is_simple_project(rel->op) || is_set(rel->op));
-               list *exps = rel->exps;
-               rel = rel_groupby(sql, rel, NULL);
-               for(node *n = exps->h; n; n=n->next) {
-                       sql_exp *e = n->data;
-                       if (!has_label(e))
-                               exp_label(sql->sa, e, ++sql->label);
-                       sql_subtype *t = exp_subtype(e); /* parameters don't 
have a type defined, for those use 'void' one */
-                       sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, 
F_AGGR);
-
-                       e = exp_ref(sql->sa, e);
-                       e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(e));
-                       (void)rel_groupby_add_aggr(sql, rel, e);
-               }
-       } else {
-               sql_exp *e = lastexp(rel);
-               if (!has_label(e))
-                       exp_label(sql->sa, e, ++sql->label);
-       }
-       return rel;
-}
-
-static sql_rel *
 rel_orderby(mvc *sql, sql_rel *l)
 {
        sql_rel *rel = rel_create(sql->sa);
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
@@ -1403,112 +1403,23 @@ rel_unnest_dependent(mvc *sql, sql_rel *
 }
 
 static sql_rel *
-_rel_unnest(mvc *sql, sql_rel *rel)
+_rel_unnest(mvc *sql, sql_rel *rel, int *changes)
 {
-       if (THRhighwater())
-               return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: 
running out of stack space");
-       if (!rel)
-               return rel;
-
-       switch (rel->op) {
-       case op_basetable:
-               break;
-       case op_table:
-               if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == 
TABLE_FROM_RELATION)
-                       rel->l = _rel_unnest(sql, rel->l);
-               break;
-       case op_join: 
-       case op_left: 
-       case op_right: 
-       case op_full: 
-
-       case op_semi: 
-       case op_anti: 
-
-       case op_union: 
-       case op_inter: 
-       case op_except: 
-               rel->l = _rel_unnest(sql, rel->l);
-               rel->r = _rel_unnest(sql, rel->r);
-               break;
-       case op_project:
-       case op_select: 
-       case op_groupby: 
-       case op_topn: 
-       case op_sample: 
-               rel->l = _rel_unnest(sql, rel->l);
-               break;
-       case op_ddl:
-               rel->l = _rel_unnest(sql, rel->l);
-               if (rel->r)
-                       rel->r = _rel_unnest(sql, rel->r);
-               break;
-       case op_insert:
-       case op_update:
-       case op_delete:
-       case op_truncate:
-               rel->l = _rel_unnest(sql, rel->l);
-               rel->r = _rel_unnest(sql, rel->r);
-               break;
+       if (is_dependent(rel)) {
+               rel = rel_unnest_dependent(sql, rel);
+               (*changes)++;
        }
-       if (is_dependent(rel)) 
-               rel = rel_unnest_dependent(sql, rel);
        return rel;
 }
 
-static void
-rel_reset_subquery(sql_rel *rel)
+static sql_rel *
+rel_reset_subquery(mvc *sql, sql_rel *rel, int *changes)
 {
-       if (!rel)
-               return;
-
+       (void) sql;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to