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

Reply via email to