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