Changeset: b3a0f40d1b58 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b3a0f40d1b58 Modified Files: sql/server/rel_rel.c sql/server/rel_select.c sql/server/rel_unnest.c sql/server/rel_unnest.h sql/test/BugTracker-2009/Tests/count_bug.SF-2604583.stable.out.int128 sql/test/BugTracker-2012/Tests/scalar_subquery_with_alias.Bug-3093.stable.out Branch: subquery Log Message:
fixes for complex in cases diffs (truncated from 1062 to 300 lines): 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 @@ -566,11 +566,15 @@ rel_label( mvc *sql, sql_rel *r, int all r->exps->ht = NULL; for (; ne; ne = ne->next) { - if (all) { - nr = ++sql->label; - cnme = number2name(cname, 16, nr); + sql_exp *e = ne->data; + + if (!e->freevar) { + if (all) { + nr = ++sql->label; + cnme = number2name(cname, 16, nr); + } + exp_setname(sql->sa, e, tnme, cnme ); } - exp_setname(sql->sa, ne->data, tnme, cnme ); } } /* op_projects can have a order by list */ 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 @@ -2008,6 +2008,200 @@ static sql_exp* return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such operator '%s'", fname); } +static sql_exp * +rel_in_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f) +{ + mvc *sql = query->sql; + exp_kind ek = {type_value, card_column, FALSE}; + + dlist *dl = sc->data.lval; + symbol *lo = dl->h->data.sym; + dnode *n = dl->h->next; + sql_rel *left = *rel, *right = NULL; + sql_exp *l = NULL, *r = NULL; + int vals_only = 1, l_is_value = 1, l_init = 0, l_used = 0, l_tuple = 0; + list *vals = NULL, *pexps = NULL; + + (void)l_tuple; + + /* no input, assume single value */ + if (!left) { + left = *rel = rel_project_exp(sql->sa, exp_atom_bool(sql->sa, 1)); + reset_processed(left); + } + if (left && is_sql_sel(f) && !is_processed(left) && is_simple_project(left->op)) { + pexps = left->exps; + if (left->l) { + left = left->l; + } else { + pexps = sa_list(sql->sa); + l_init = 1; + } + } + + l = rel_value_exp(query, &left, lo, f, ek); + if (!l) + return NULL; + if (l && exp_has_freevar(l)) { + l_is_value=0; + } + 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_rel *z = NULL; + + r = rel_value_exp(query, &z, n->data.sym, sql_where /* ie no result project */, ek); + if (z && r) { + sql_subaggr *ea = NULL; + sql_exp *a, *id; + list *exps; + + if (l_init) { + l = rel_project_add_exp(sql, left, l); + l = exp_ref(sql->sa, l); + } + exps = rel_projections(sql, left, NULL, 1/*keep names */, 1); + left = rel_add_identity(sql, left, &id); + id = exp_ref(sql->sa, id); + left = rel_crossproduct(sql->sa, left, z, is_sql_sel(f)?op_left:op_join); + /* TODO only if freevars */ + if (!l_is_value) + set_dependent(left); + + left = rel_groupby(sql, left, exp2list(sql->sa, id)); + left->exps = exps; + /* group by on ? */ + if (rel_convert_types(sql, &l, &r, 1, type_equal_no_any) < 0) + return NULL; + ea = sql_bind_aggr(sql->sa, sql->session->schema, sc->token==SQL_IN?"anyequal":"allnotequal", exp_subtype(r)); + a = exp_aggr1(sql->sa, l, ea, 0, 0, CARD_ATOM, 0); + append(a->l, r); + r = rel_groupby_add_aggr(sql, left, a); + r = exp_ref(sql->sa, r); + + if (is_sql_sel(f)) { + if (pexps) + left = rel_project(sql->sa, left, pexps); + reset_processed(left); + } else { + //rel_join_add_exp(sql->sa, left, r); + left = rel_select(sql->sa, left, r); + } + *rel = left; + return r; + } + if (l && !r) { /* possibly a (not) in function call */ + sql_rel *z; + /* reset error */ + sql->session->status = 0; + sql->errstr[0] = 0; + + query_push_outer(query, left); + z = rel_subquery(query, NULL, n->data.sym, ek, 0); + query_pop_outer(query); + if (z) + r = rel_lastexp(sql, z); + if (z && r) { + sql_subaggr *ea = NULL; + sql_exp *a, *id; + list *exps; + + exps = rel_projections(sql, left, NULL, 1/*keep names */, 1); + left = rel_add_identity(sql, left, &id); + id = exp_ref(sql->sa, id); + left = rel_crossproduct(sql->sa, left, z, is_sql_sel(f)?op_left:op_join); + /* TODO only if freevars */ + set_dependent(left); + + left = rel_groupby(sql, left, exp2list(sql->sa, id)); + left->exps = exps; + /* group by on ? */ + if (rel_convert_types(sql, &l, &r, 1, type_equal_no_any) < 0) + return NULL; + ea = sql_bind_aggr(sql->sa, sql->session->schema, sc->token==SQL_IN?"anyequal":"allnotequal", exp_subtype(r)); + a = exp_aggr1(sql->sa, l, ea, 0, 0, CARD_ATOM, 0); + append(a->l, r); + r = rel_groupby_add_aggr(sql, left, a); + r = exp_ref(sql->sa, r); + + if (is_sql_sel(f)) { + left = rel_project(sql->sa, left, pexps); + reset_processed(left); + } else { + rel_join_add_exp(sql->sa, left, r); + } + *rel = left; + return r; + } + } + if (!l || !r) + return NULL; + append(vals, r); + } + if (vals_only) { + sql_exp *e = NULL, *je = NULL; + node *n; + + for(n=vals->h; n; n = n->next) { + sql_exp *r = n->data, *ne; + + if (rel_convert_types(sql, &l, &r, 1, type_equal) < 0) + return NULL; + if (l_used) { + sql_exp *ne = exp_compare(sql->sa, l, r, cmp_equal ); + if (e) { + je = exp_or(sql->sa, + append(sa_list(sql->sa), je), + append(sa_list(sql->sa), ne), 0); + } else { + je = ne; + } + } + if (sc->token == SQL_NOT_IN) + ne = rel_binop_(query, l, r, NULL, "<>", card_value); + else + ne = rel_binop_(query, l, r, NULL, "=", card_value); + if (!e) { + e = ne; + } else if (sc->token == SQL_NOT_IN) { + e = rel_binop_(query, e, ne, NULL, "and", card_value); + } else { + e = rel_binop_(query, e, ne, NULL, "or", card_value); + } + } + if (l_used) + rel_join_add_exp(sql->sa, left, je); + else if (!is_sql_sel(f)) { + if (!is_select(left->op) || rel_is_ref(left)) + left = rel_select(sql->sa, left, e); + else + rel_select_add_exp(sql->sa, left, e); + } + if (!l_used && l_is_value && sc->token == SQL_NOT_IN) + set_anti(e); + if (pexps) { + if (!l_init) + (*rel)->l = left; + else if (l_used) + *rel = left; + } else { + *rel = left; + } + return e; + } + if (right->processed) + right = rel_label(sql, right, 0); + right = rel_distinct(right); + set_processed(right); + } else { + return sql_error(sql, 02, SQLSTATE(42000) "IN: missing inner query"); + } + return NULL; +} + sql_exp * rel_logical_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f) { @@ -2228,243 +2422,7 @@ rel_logical_value_exp(sql_query *query, /* Set Member ship */ case SQL_IN: case SQL_NOT_IN: - { - dlist *dl = sc->data.lval; - symbol *lo = dl->h->data.sym; - dnode *n = dl->h->next; - sql_rel *left = NULL, *right = NULL, *outer = *rel; - sql_exp /**ol,*/ *l = NULL, *r = NULL; - int needproj = 0, vals_only = 1;//, is_new = 0; - list *vals = NULL, *pexps = NULL; - - /* no input, assume single value */ - if (!*rel) - left = *rel = rel_project_exp(sql->sa, exp_atom_bool(sql->sa, 1)); - - if (outer && is_sql_sel(f) && is_project(outer->op) && !is_processed(outer)) { - needproj = 1; - pexps = outer->exps; - if (!outer->l) { /* list of constants */ - *rel = rel_project(sql->sa, NULL, exps_copy(sql->sa, outer->exps)); - } else - *rel = outer->l; - } - - /*ol =*/ l = rel_value_exp(query, rel, lo, f, ek); - if (!l) - return NULL; - ek.card = card_set; - if (!left) { - left = *rel; - /* - if (!exp_is_atom(l) && outer && !outer->l && !list_empty(outer->exps) && needproj) { - l = rel_project_add_exp(sql, left, l); - l = exp_column(sql->sa, exp_relname(l), exp_name(l), exp_subtype(l), l->card, has_nil(l), is_intern(l)); - } - */ - } - - /* - if (!left || (!left->l && is_sql_sel(f) && list_empty(left->exps))) { - needproj = (left != NULL); - left = rel_project_exp(sql->sa, l); - is_new = 1; - } - */ - if (left && is_project(left->op) && list_empty(left->exps)) - left = left->l; - - if (n->type == type_list) { - sql_subtype *st = exp_subtype(l); - - vals = new_exp_list(sql->sa); - n = n->data.lval->h; - for (; n; n = n->next) { - symbol *sval = n->data.sym; - /* without correlation first */ - sql_rel *z = NULL, *rl; - - r = rel_value_exp(query, &z, sval, f, ek); - r = rel_is_constant(&z, r); - if (l && r && IS_ANY(st->type->eclass)){ - sql_exp *nl = rel_check_type(sql, exp_subtype(r), l, type_equal); - /* - if (nl != l && is_new) - left = rel_project_exp(sql->sa, nl); - */ - l = nl; - if (l) - st = exp_subtype(l); - } - if (l && !r) { /* possibly a (not) in function call */ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list