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

Reply via email to