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