Changeset: b31ee636db93 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b31ee636db93
Modified Files:
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/test/miscellaneous/Tests/groupby_error.stable.out
sql/test/subquery/Tests/subquery3.sql
sql/test/subquery/Tests/subquery3.stable.err
sql/test/subquery/Tests/subquery3.stable.out
Branch: linear-hashing
Log Message:
Backported recent IN operator fixes into linear-hashing, plus enforce type
coercion on every element at the list of values case. This fixes the failing
sqlite query
diffs (truncated from 583 to 300 lines):
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
@@ -679,6 +679,61 @@ rel_op_(mvc *sql, sql_schema *s, char *f
}
}
+static sql_exp*
+exp_values_set_supertype(mvc *sql, sql_exp *values)
+{
+ list *vals = values->f, *nexps;
+ sql_subtype *tpe = exp_subtype(vals->h->data);
+
+ if (tpe)
+ values->tpe = *tpe;
+
+ for (node *m = vals->h; m; m = m->next) {
+ sql_exp *e = m->data;
+ sql_subtype super, *ttpe;
+
+ /* if the expression is a parameter set its type */
+ if (tpe && e->type == e_atom && !e->l && !e->r && !e->f &&
!e->tpe.type) {
+ if (set_type_param(sql, tpe, e->flag) == 0)
+ e->tpe = *tpe;
+ else
+ return NULL;
+ }
+ ttpe = exp_subtype(e);
+ if (tpe && ttpe) {
+ supertype(&super, tpe, ttpe);
+ values->tpe = super;
+ tpe = &values->tpe;
+ } else {
+ tpe = ttpe;
+ }
+ }
+
+ if (tpe) {
+ /* if the expression is a parameter set its type */
+ for (node *m = vals->h; m; m = m->next) {
+ sql_exp *e = m->data;
+ if (e->type == e_atom && !e->l && !e->r && !e->f &&
!e->tpe.type) {
+ if (set_type_param(sql, tpe, e->flag) == 0)
+ e->tpe = *tpe;
+ else
+ return NULL;
+ }
+ }
+ values->tpe = *tpe;
+ nexps = sa_list(sql->sa);
+ for (node *m = vals->h; m; m = m->next) {
+ sql_exp *e = m->data;
+ e = rel_check_type(sql, &values->tpe, NULL, e,
type_equal);
+ if (!e)
+ return NULL;
+ append(nexps, e);
+ }
+ values->f = nexps;
+ }
+ return values;
+}
+
static sql_rel *
rel_values(sql_query *query, symbol *tableref)
{
@@ -722,59 +777,9 @@ rel_values(sql_query *query, symbol *tab
}
}
/* loop to check types */
- for (m = exps->h; m; m = m->next) {
- node *n;
- sql_exp *vals = m->data;
- list *vals_list = vals->f;
- list *nexps = sa_list(sql->sa);
- sql_subtype *tpe = exp_subtype(vals_list->h->data);
-
- if (tpe)
- vals->tpe = *tpe;
-
- /* first get super type */
- for (n = vals_list->h; n; n = n->next) {
- sql_exp *e = n->data;
- sql_subtype super, *ttpe;
-
- /* if the expression is a parameter set its type */
- if (tpe && e->type == e_atom && !e->l && !e->r && !e->f
&& !e->tpe.type) {
- if (set_type_param(sql, tpe, e->flag) == 0)
- e->tpe = *tpe;
- else
- return NULL;
- }
- ttpe = exp_subtype(e);
- if (tpe && ttpe) {
- supertype(&super, tpe, ttpe);
- vals->tpe = super;
- tpe = &vals->tpe;
- } else {
- tpe = ttpe;
- }
- }
- if (!tpe)
- continue;
- /* if the expression is a parameter set its type */
- for (n = vals_list->h; n; n = n->next) {
- sql_exp *e = n->data;
- if (e->type == e_atom && !e->l && !e->r && !e->f &&
!e->tpe.type) {
- if (set_type_param(sql, tpe, e->flag) == 0)
- e->tpe = *tpe;
- else
- return NULL;
- }
- }
- vals->tpe = *tpe;
- for (n = vals_list->h; n; n = n->next) {
- sql_exp *e = n->data;
- e = rel_check_type(sql, &vals->tpe, NULL, e,
type_equal);
- if (!e)
- return NULL;
- append(nexps, e);
- }
- vals->f = nexps;
- }
+ for (m = exps->h; m; m = m->next)
+ m->data = exp_values_set_supertype(sql, (sql_exp*) m->data);
+
r = rel_project(sql->sa, NULL, exps);
r->nrcols = list_length(exps);
r->card = dlist_length(rowlist) == 1 ? CARD_ATOM : CARD_MULTI;
@@ -1959,46 +1964,13 @@ rel_exists_exp(sql_query *query, sql_rel
static sql_exp *
rel_in_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f)
{
- exp_kind ek = {type_value, card_column, FALSE};
- mvc *sql = query->sql;
- sql_exp *le, *e = NULL;
- dlist *dl = sc->data.lval;
- symbol *lo = dl->h->data.sym;
- dnode *n = dl->h->next;
- list *vals = NULL;
-
- le = rel_value_exp(query, rel, lo, f, ek);
- if (!le)
- return NULL;
- ek.card = card_set;
- if (n->type == type_list) {
- vals = sa_list(sql->sa);
- n = n->data.lval->h;
- for (; n; n = n->next) {
- sql_exp *r = NULL;
-
- r = rel_value_exp(query, rel, n->data.sym, f, ek);
- if (!r)
- return NULL;
- append( vals, r);
- }
- e = exp_in_func(sql, le, exp_values(sql->sa, vals), (sc->token
== SQL_IN), 0);
- }
- if (e)
- e->card = le->card;
- return e;
-}
-
-static sql_rel *
-rel_in_exp(sql_query *query, sql_rel *rel, symbol *sc, int f)
-{
mvc *sql = query->sql;
exp_kind ek = {type_value, card_column, TRUE};
dlist *dl = sc->data.lval;
symbol *lo = NULL;
dnode *n = dl->h->next, *dn = NULL;
- sql_exp *le, *re;
- list *vals = NULL, *ll = sa_list(sql->sa);
+ sql_exp *le = NULL, *re, *e = NULL;
+ list *ll = sa_list(sql->sa);
int is_tuple = 0;
/* complex case */
@@ -2010,7 +1982,7 @@ rel_in_exp(sql_query *query, sql_rel *re
lo = dl->h->data.sym;
}
for( ; lo; lo = dn?dn->data.sym:NULL, dn = dn?dn->next:NULL ) {
- le = rel_value_exp(query, &rel, lo, f, ek);
+ le = rel_value_exp(query, rel, lo, f, ek);
if (!le)
return NULL;
ek.card = card_set;
@@ -2025,29 +1997,46 @@ rel_in_exp(sql_query *query, sql_rel *re
}
/* list of values or subqueries */
if (n->type == type_list) {
- vals = sa_list(sql->sa);
+ sql_exp *values;
+ list *vals = sa_list(sql->sa);
+
n = dl->h->next;
n = n->data.lval->h;
for (; n; n = n->next) {
- re = rel_value_exp(query, &rel, n->data.sym, f, ek);
+ re = rel_value_exp(query, rel, n->data.sym, f, ek);
if (!re)
return NULL;
if (is_tuple && !exp_is_rel(re))
- return NULL;
+ return sql_error(sql, 02, SQLSTATE(42000)
"Cannot match a tuple to a single value");
if (is_tuple)
re = exp_rel_label(sql, re);
append(vals, re);
}
- }
+
+ values = exp_values(sql->sa, vals);
+ if (!is_tuple) /* if it's not a tuple, enforce coersion on the
type for every element on the list */
+ values = exp_values_set_supertype(sql, values);
+ e = exp_in_func(sql, le, values, (sc->token == SQL_IN),
is_tuple);
+ }
+ if (e && le)
+ e->card = le->card;
+ return e;
+}
+
+static sql_rel *
+rel_in_exp(sql_query *query, sql_rel *rel, symbol *sc, int f)
+{
+ mvc *sql = query->sql;
+ sql_exp *e = rel_in_value_exp(query, &rel, sc, f);
assert(!is_sql_sel(f));
- sql_exp *e = exp_in_func(sql, le, exp_values(sql->sa, vals), (sc->token
== SQL_IN), is_tuple);
+ if (!e || !rel)
+ return NULL;
rel = rel_select_add_exp(sql->sa, rel, e);
return rel;
}
-
sql_exp *
rel_logical_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f)
{
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
@@ -1913,19 +1913,28 @@ rel_union_exps(mvc *sql, sql_exp **l, li
sql_rel *u = NULL;
list *exps = NULL;
- for(node *n=vals->h; n; n = n->next) {
- sql_exp *ve = n->data, *r;
+ for (node *n=vals->h; n; n = n->next) {
+ sql_exp *ve = n->data, *r, *s;
sql_rel *sq = NULL;
if (exp_has_rel(ve))
sq = exp_rel_get_rel(sql->sa, ve); /* get subquery */
else
sq = rel_project(sql->sa, NULL,
append(sa_list(sql->sa), ve));
- /* TODO merge expressions (could x+ cast(y) where y is result
of a sub query) */
- r = sq->exps->t->data;
- if (!is_tuple && rel_convert_types(sql, NULL, NULL, l, &r, 1,
type_equal) < 0)
- return NULL;
- sq->exps->t->data = r;
+ if (is_tuple) { /* cast each one */
+ for (node *m=sq->exps->h, *o = ((list *)(*l)->f)->h; m
&& o; m = m->next, o = o->next) {
+ r = m->data;
+ s = o->data;
+ if (rel_convert_types(sql, NULL, NULL, &s, &r,
1, type_equal) < 0)
+ return NULL;
+ m->data = r;
+ }
+ } else {
+ r = sq->exps->t->data;
+ if (rel_convert_types(sql, NULL, NULL, l, &r, 1,
type_equal) < 0)
+ return NULL;
+ sq->exps->t->data = r;
+ }
if (!u) {
u = sq;
exps = rel_projections(sql, sq, NULL, 1/*keep names */,
1);
@@ -2040,10 +2049,10 @@ rewrite_anyequal(mvc *sql, sql_rel *rel,
if (is_project(rel->op) || depth > 0) {
list *exps = NULL;
- sql_exp *rid, *lid;
+ sql_exp *rid, *lid, *a = NULL;
sql_rel *sq = lsq;
+ sql_subaggr *ea = sql_bind_aggr(sql->sa,
sql->session->schema, is_anyequal(sf)?"anyequal":"allnotequal",
exp_subtype(re));
- assert(!is_tuple);
rsq = rel_add_identity2(sql, rsq, &rid);
rid = exp_ref(sql->sa, rid);
@@ -2062,15 +2071,36 @@ rewrite_anyequal(mvc *sql, sql_rel *rel,
if (sq)
(void)rewrite_inner(sql, rel, lsq,
op_join);
if (rsq)
- (void)rewrite_inner(sql, rel, rsq,
op_join);
-
+ (void)rewrite_inner(sql, rel, rsq,
!is_tuple?op_join:is_anyequal(sf)?op_semi:op_anti);
+
lsq = rel->l = rel_groupby(sql, rel->l,
exp2list(sql->sa, lid));
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list