Changeset: 8afa1b319011 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8afa1b319011
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/common/sql_types.c
        sql/include/sql_relation.h
        sql/rel.txt
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_psm.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/rel_select.h
        sql/server/rel_unnest.c
        sql/server/rel_updates.c
        sql/server/rel_xml.c
        sql/server/sql_semantic.c
Branch: sq2
Log Message:

moved the in handling down into the unnest step


diffs (truncated from 2359 to 300 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -2992,7 +2992,7 @@ rel2bin_select(backend *be, sql_rel *rel
                        }
                        sel = stmt_uselect(be, predicate, s, cmp_equal, sel, 0);
                } else if (e->type != e_cmp) {
-                       sel = stmt_uselect(be, s, stmt_bool(be, 1), cmp_equal, 
NULL, 0);
+                       sel = stmt_uselect(be, s, stmt_bool(be, 1), cmp_equal, 
sel, 0);
                } else {
                        sel = s;
                }
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -1569,6 +1569,8 @@ sqltypeinit( sql_allocator *sa)
        sql_create_func3(sa, "all", "sql", "all", BIT, BIT, BIT, BIT, 
SCALE_NONE);
        sql_create_aggr(sa, "anyequal", "aggr", "anyequal", ANY, BIT); /* needs 
3 arguments (l,r,nil)(ugh) */
        sql_create_aggr(sa, "allnotequal", "aggr", "allnotequal", ANY, BIT); /* 
needs 3 arguments (l,r,nil)(ugh) */
+       sql_create_func(sa, "sql_anyequal", "aggr", "anyequal", ANY, ANY, BIT, 
SCALE_NONE);
+       sql_create_func(sa, "sql_not_anyequal", "aggr", "not_anyequal", ANY, 
ANY, BIT, SCALE_NONE);
        sql_create_aggr(sa, "exist", "aggr", "exist", ANY, BIT);
        sql_create_aggr(sa, "not_exist", "aggr", "not_exist", ANY, BIT);
        sql_create_func(sa, "sql_exists", "aggr", "exist", ANY, NULL, BIT, 
SCALE_NONE);
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -160,7 +160,9 @@ typedef enum operator_type {
        (et == e_atom)
 /* a simple atom is a literal or on the query stack */
 #define is_simple_atom(e) \
-       (is_atom(e->flag) && !e->r && !e->f)
+       (is_atom(e->type) && !e->r && !e->f)
+#define is_values(e) \
+       ((e)->type == e_atom && (e)->f)
 #define is_func(et) \
        (et == e_func)
 #define is_aggr(et) \
@@ -169,6 +171,8 @@ typedef enum operator_type {
        (et == e_convert)
 #define is_map_op(et) \
        (et == e_func || et == e_convert)
+#define is_compare(et) \
+       (et == e_cmp)
 #define is_column(et) \
        (et != e_cmp)
 #define is_alias(et) \
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -164,5 +164,5 @@ e_psm
                                ->r loop_exp_list
                psm_return      ->l return_exp
                psm_rel         ->l relation
-               psm_exception ->l cond_exp
-                                         ->r error_string
+               psm_exception   ->l cond_exp
+                               ->r error_string
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -360,7 +360,6 @@ rel_print_(mvc *sql, stream  *fout, sql_
                mnstr_printf(fout, "\n%cREF %d (%d)", decorate?'=':' ', nr, 
cnt);
        }
 
-
        switch (rel->op) {
        case op_basetable: {
                sql_table *t = rel->l;
@@ -551,6 +550,7 @@ rel_print_(mvc *sql, stream  *fout, sql_
                        GDKfree(pv);
                }
        }
+       //mnstr_printf(fout, " %p ", rel);
 }
 
 void
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -187,6 +187,26 @@ exp_in(sql_allocator *sa, sql_exp *l, li
        return e;
 }
 
+sql_exp *
+exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
+{
+       sql_subfunc *a_func = NULL;
+       sql_exp *e = le;
+                       
+       if (is_tuple) {
+               list *l = exp_get_values(e);
+               e = l->h->data;
+       }
+       if (anyequal)
+               a_func = sql_bind_func(sql->sa, sql->session->schema, 
"sql_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
+       else
+               a_func = sql_bind_func(sql->sa, sql->session->schema, 
"sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
+
+       if (!a_func) 
+               return sql_error(sql, 02, SQLSTATE(42000) "(NOT) IN operator on 
type %s missing", exp_subtype(le)->type->sqlname);
+       return exp_binop(sql->sa, le, vals, a_func);
+}
+
 static sql_subtype*
 dup_subtype(sql_allocator *sa, sql_subtype *st)
 {
@@ -222,7 +242,7 @@ exp_op( sql_allocator *sa, list *l, sql_
        e->card = exps_card(l);
        if (!l || list_length(l) == 0) 
                e->card = CARD_ATOM; /* unop returns a single atom */
-       /* 
+       /*
        if (f->func->side_effect)
                e->card = CARD_MULTI;
                */
@@ -456,11 +476,19 @@ exp_values(sql_allocator *sa, list *exps
        sql_exp *e = exp_create(sa, e_atom);
        if (e == NULL)
                return NULL;
-       e->card = CARD_MULTI;
+       e->card = exps_card(exps);
        e->f = exps;
        return e;
 }
 
+list *
+exp_get_values(sql_exp *e)
+{
+       if (is_atom(e->type) && e->f)
+               return e->f;
+       return NULL;
+}
+
 list * 
 exp_types(sql_allocator *sa, list *exps) 
 {
@@ -1546,10 +1574,48 @@ exp_is_atom( sql_exp *e )
 int
 exp_is_rel( sql_exp *e )
 {
-       return (e && e->type == e_psm && e->flag == PSM_REL && e->l);
+       if (!e)
+               return 0;
+       switch(e->type){
+       case e_func:
+       case e_aggr:
+               return exps_have_rel_exp(e->l);
+       case e_cmp:
+               if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
+                       return (exps_have_rel_exp(e->l) || 
exps_have_rel_exp(e->r));
+               } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+                       return (exp_is_rel(e->l) || exps_have_rel_exp(e->r));
+               } else {
+                       return (exp_is_rel(e->l) || exp_is_rel(e->r) || (e->f 
&& exp_is_rel(e->f)));
+               }
+       case e_convert:
+               return exp_is_rel(e->l);
+       case e_psm:
+               return (e->flag == PSM_REL && e->l);
+       case e_atom:
+               return (e->f && exps_have_rel_exp(e->f));
+       case e_column:
+               return 0;
+       }
+       return 0;
 }
 
 int
+exps_have_rel_exp( list *exps)
+{
+       if (list_empty(exps))
+               return 0;
+       for(node *n=exps->h; n; n=n->next) {
+               sql_exp *e = n->data;
+
+               if (exp_is_rel(e))
+                       return 1;
+       }
+       return 0;
+}
+
+
+int
 exps_are_atoms( list *exps)
 {
        node *n;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -26,6 +26,7 @@ extern sql_exp *exp_compare2(sql_allocat
 extern sql_exp *exp_filter(sql_allocator *sa, list *l, list *r, sql_subfunc 
*f, int anti);
 extern sql_exp *exp_or(sql_allocator *sa, list *l, list *r, int anti);
 extern sql_exp *exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype);
+extern sql_exp *exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int 
anyequal, int is_tuple);
 
 #define exp_fromtype(e)        ((list*)e->r)->h->data
 #define exp_totype(e)  ((list*)e->r)->h->next->data
@@ -66,6 +67,7 @@ extern sql_exp * exp_null(sql_allocator 
 extern sql_exp * exp_param(sql_allocator *sa, const char *name, sql_subtype 
*tpe, int frame);
 extern atom * exp_value(mvc *sql, sql_exp *e, atom **args, int maxarg);
 extern sql_exp * exp_values(sql_allocator *sa, list *exps);
+extern list * exp_get_values(sql_exp *e); /* get expression list from the 
values expression */
 extern list * exp_types(sql_allocator *sa, list *exps);
 extern int have_nil(list *exps);
 
@@ -131,6 +133,7 @@ extern int exp_is_zero(mvc *sql, sql_exp
 extern int exp_is_not_null(mvc *sql, sql_exp *e);
 extern int exp_is_null(mvc *sql, sql_exp *e);
 extern int exp_is_rel(sql_exp *e);
+extern int exps_have_rel_exp(list *exps);
 extern int exps_are_atoms(list *exps);
 extern int exp_has_func(sql_exp *e);
 extern int exp_unsafe(sql_exp *e, int allow_identity);
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -3006,7 +3006,10 @@ rel_case_fixup(int *changes, mvc *sql, s
                /* get proper output first, then rewrite lower project (such 
that it can split expressions) */
                push_down = is_simple_project(rel->op) && !rel->r && 
!rel_is_ref(rel);
                if (push_down) {
-                       res = rel_project(sql->sa, rel, rel_projections(sql, 
rel, NULL, 1, 2));
+                       if (top)
+                               res = rel_safe_project(sql, rel);
+                       else
+                               res = rel_project(sql->sa, rel, 
rel_projections(sql, rel, NULL, 1, 2));
                        if (need_distinct(rel))
                                set_distinct(res);
                }
@@ -7336,10 +7339,12 @@ rel_simplify_predicates(int *changes, mv
 
                                                assert(list_length(args) == 1);
                                                l = args->h->data;
-                                               r = exp_atom(sql->sa, 
atom_general(sql->sa, exp_subtype(l), NULL));
-                                               e = exp_compare2(sql->sa, l, r, 
r, 3);
-                                               if (e && !flag)
-                                                       set_anti(e);
+                                               if (exp_subtype(l)) {
+                                                       r = exp_atom(sql->sa, 
atom_general(sql->sa, exp_subtype(l), NULL));
+                                                       e = 
exp_compare2(sql->sa, l, r, r, 3);
+                                                       if (e && !flag)
+                                                               set_anti(e);
+                                               }
                                        } else if (!f->func->s && 
!strcmp(f->func->base.name, "not")) {
                                                if (is_atom(r->type) && r->l) { 
/* direct literal */
                                                        atom *a = r->l;
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -395,7 +395,7 @@ rel_psm_case( sql_query *query, sql_subt
                        sql_exp *case_stmt = NULL;
 
                        if (!when_value || rel ||
-                          (cond = rel_binop_(query, rel, v, when_value, NULL, 
"=", card_value)) == NULL ||
+                          (cond = rel_binop_(sql, rel, v, when_value, NULL, 
"=", card_value)) == NULL ||
                           (if_stmts = sequential_block( query, res, 
restypelist, m->next->data.lval, NULL, is_func)) == NULL ) {
                                if (rel)
                                        return sql_error(sql, 02, 
SQLSTATE(42000) "CASE: No SELECT statements allowed within the CASE condition");
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
@@ -606,17 +606,22 @@ rel_project_add_exp( mvc *sql, sql_rel *
        return e;
 }
 
-void
+sql_rel *
 rel_select_add_exp(sql_allocator *sa, sql_rel *l, sql_exp *e)
 {
-       assert(l->op == op_select || is_outerjoin(l->op));
+       if ((l->op != op_select && !is_outerjoin(l->op)) || rel_is_ref(l))
+               return rel_select(sa, l, e);
+
+/*     allow during AST->relational for bool expresssions as well 
        if (e->type != e_cmp && e->card > CARD_ATOM) {
                sql_exp *t = exp_atom_bool(sa, 1);
                e = exp_compare(sa, e, t, cmp_equal);
        }
+*/
        if (!l->exps)
                l->exps = new_exp_list(sa);
        append(l->exps, e);
+       return l;
 }
 
 void
@@ -1069,6 +1074,27 @@ rel_projections(mvc *sql, sql_rel *rel, 
        return _rel_projections(sql, rel, tname, settname, intern, 0);
 }
 
+/* add a project around a project where each inner expression gets a unique 
label */
+sql_rel *
+rel_safe_project(mvc *sql, sql_rel *rel)
+{
+       list *nexps = sa_list(sql->sa);
+
+       assert(!list_empty(rel->exps));
+       for(node *n = rel->exps->h; n; n=n->next) {
+               sql_exp *e = n->data, *ne;
+               const char *cname = exp_name(e);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to