Changeset: 165f12ae0542 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=165f12ae0542
Modified Files:
        sql/common/sql_stack.c
        sql/include/sql_relation.h
        sql/include/sql_stack.h
        sql/server/rel_exp.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/server/sql_query.c
        sql/server/sql_query.h
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.stable.out
        sql/test/emptydb/Tests/load.stable.out
        sql/test/subquery/Tests/All
        sql/test/subquery/Tests/correlated.sql
        sql/test/subquery/Tests/correlated.stable.out
Branch: sq2
Log Message:

more correlated queries and clennup


diffs (truncated from 690 to 300 lines):

diff --git a/sql/common/sql_stack.c b/sql/common/sql_stack.c
--- a/sql/common/sql_stack.c
+++ b/sql/common/sql_stack.c
@@ -56,6 +56,20 @@ sql_stack_peek(sql_stack *s, int p)
        return s->values[(s->top-1)-p];
 }
 
+void *
+sql_stack_fetch(sql_stack *s, int p)
+{
+       if (p>=s->top)
+               return NULL;
+       return s->values[p];
+}
+
+int
+sql_stack_top(sql_stack *s)
+{
+       return s->top;
+}
+
 int
 sql_stack_empty(sql_stack *s)
 {
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
@@ -40,7 +40,7 @@ typedef struct expression {
        unsigned int
         flag:18,       /* EXP_DISTINCT, NO_NIL, ASCENDING, NULLS_LAST, cmp 
types */
         card:2,        /* card (0 truth value!) (1 atoms) (2 aggr) (3 multi 
value) */
-        freevar:1,     /* free variable, ie binds to the upper dependent join 
*/
+        freevar:4,     /* free variable, ie binds to the upper dependent join 
*/
         intern:1,
         anti:1,
         base:1,
@@ -300,8 +300,8 @@ typedef enum operator_type {
 
 #define is_freevar(e) \
        ((e)->freevar)
-#define set_freevar(e) \
-       (e)->freevar = 1
+#define set_freevar(e,level) \
+       (e)->freevar = level+1
 #define reset_freevar(e) \
        (e)->freevar = 0
 
diff --git a/sql/include/sql_stack.h b/sql/include/sql_stack.h
--- a/sql/include/sql_stack.h
+++ b/sql/include/sql_stack.h
@@ -30,7 +30,9 @@ typedef struct sql_stack {
 extern sql_stack *sql_stack_new(sql_allocator *sa, int size);
 extern void sql_stack_push(sql_stack *s, void *v);
 extern void *sql_stack_pop(sql_stack *s);
-extern void *sql_stack_peek(sql_stack *s, int pos);
+extern void *sql_stack_peek(sql_stack *s, int pos); /* top == pos 0 */
+extern void *sql_stack_fetch(sql_stack *s, int pos); /* pos 0 is bottom of the 
stack */
+extern int sql_stack_top(sql_stack *s); 
 extern int sql_stack_empty(sql_stack *s);
 
 #endif /* SQL_STACK_H */
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
@@ -2011,7 +2011,7 @@ exp_copy( sql_allocator *sa, sql_exp * e
                exp_prop_alias(ne, e);
        ne = exp_propagate(sa, ne, e);
        if (is_freevar(e))
-               set_freevar(ne);
+               set_freevar(ne, is_freevar(e)-1);
        return ne;
 }
 
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
@@ -1069,7 +1069,7 @@ rel_column_ref(sql_query *query, sql_rel
                        int i;
                        sql_rel *outer;
 
-                       for (i=0; !exp && (outer = query_fetch_outer(query,i)); 
i++) {
+                       for (i=query_has_outer(query)-1; i>= 0 && !exp && 
(outer = query_fetch_outer(query,i)); i--) {
                                int sql_state = 
query_fetch_outer_state(query,i);
 
                                exp = rel_bind_column(sql, outer, name, f);
@@ -1082,6 +1082,8 @@ rel_column_ref(sql_query *query, sql_rel
                                if (exp && is_sql_aggr(f) && 
is_sql_aggr(sql_state)) {
                                        return sql_error(sql, 05, 
SQLSTATE(42000) "SELECT: aggregate function calls cannot be nested");
                                }
+                               if (exp)
+                                       break;
                        }
                        if (exp && outer && outer->card <= CARD_AGGR && 
exp->card > CARD_AGGR && !is_sql_aggr(f))
                                return sql_error(sql, 05, SQLSTATE(42000) 
"SELECT: cannot use non GROUP BY column '%s' in query results without an 
aggregate function", name);
@@ -1093,7 +1095,7 @@ rel_column_ref(sql_query *query, sql_rel
                                        exp = exp_ref(sql->sa, exp);
                                else
                                        exp->card = CARD_ATOM;
-                               set_freevar(exp);
+                               set_freevar(exp, i);
                        }
                }
                if (exp) {
@@ -1146,7 +1148,7 @@ rel_column_ref(sql_query *query, sql_rel
                        int i;
                        sql_rel *outer;
 
-                       for (i=0; !exp && (outer = query_fetch_outer(query,i)); 
i++) {
+                       for (i=query_has_outer(query)-1; i>= 0 && !exp && 
(outer = query_fetch_outer(query,i)); i--) {
                                int sql_state = 
query_fetch_outer_state(query,i);
 
                                exp = rel_bind_column2(sql, outer, tname, 
cname, f | sql_outer);
@@ -1159,6 +1161,8 @@ rel_column_ref(sql_query *query, sql_rel
                                if (exp && is_sql_aggr(f) && 
is_sql_aggr(sql_state)) {
                                        return sql_error(sql, 05, 
SQLSTATE(42000) "SELECT: aggregate function calls cannot be nested");
                                }
+                               if (exp)
+                                       break;
                        }
                        if (exp && outer && outer->card <= CARD_AGGR && 
exp->card > CARD_AGGR && !is_sql_aggr(f))
                                return sql_error(sql, 05, SQLSTATE(42000) 
"SELECT: cannot use non GROUP BY column '%s.%s' in query results without an 
aggregate function", tname, cname);
@@ -1170,7 +1174,7 @@ rel_column_ref(sql_query *query, sql_rel
                                        exp = exp_ref(sql->sa, exp);
                                else
                                        exp->card = CARD_ATOM;
-                               set_freevar(exp);
+                               set_freevar(exp, i);
                        }
                }
 
@@ -1702,12 +1706,6 @@ rel_compare_exp_(sql_query *query, sql_r
 
        if (!rel)
                return rel_select(sql->sa, rel_project_exp(sql->sa, 
exp_atom_bool(sql->sa, 1)), e);
-#if 0
-       if (!rel && query_has_outer(query)) {
-               /* for now only top of stack */
-               return rel_select(sql->sa, query_fetch_outer(query, 0), e);
-       }
-#endif
 
        /* atom or row => select */
        if (ls->card > rel->card) {
@@ -1822,6 +1820,67 @@ compare_aggr_op( char *compare, int quan
 }
 
 static sql_rel *
+rel_compare_selects(sql_query *query, sql_rel *rel, symbol *lo, symbol *ro, 
char *compare_op, 
+               int f, exp_kind k, int quantifier, int need_not)
+{
+       mvc *sql = query->sql;
+       sql_exp *rs = NULL, *ls = NULL;
+       exp_kind ek = {type_value, card_column, FALSE};
+       sql_rel *l, *r;
+       int ldependent = 0, rdependent = 0;
+       
+       assert(is_sql_where(f)); /* for now just where part */
+       l = rel_subquery(query, NULL, lo, ek);
+       if (!l && sql->session->status != -ERR_AMBIGUOUS) {
+               /* reset error */
+               sql->session->status = 0;
+               sql->errstr[0] = 0;
+               query_push_outer(query, rel, f);
+               l = rel_subquery(query, NULL, lo, ek);
+               if (l)
+                       set_subquery(l);
+               rel = query_pop_outer(query);
+               ldependent = 1;
+       }
+       r = rel_subquery(query, NULL, ro, ek);
+       if (!r && sql->session->status != -ERR_AMBIGUOUS) {
+               /* reset error */
+               sql->session->status = 0;
+               sql->errstr[0] = 0;
+               query_push_outer(query, rel, f);
+               r = rel_subquery(query, NULL, ro, ek);
+               if (r)
+                       set_subquery(r);
+               rel = query_pop_outer(query);
+               rdependent = 1;
+       }
+       if (!l || !r)
+               return NULL;
+       ls = rel_lastexp(sql, l);
+       rs = rel_lastexp(sql, r);
+       if (rel) {
+               r = rel_crossproduct(sql->sa, l, r, op_join);
+               set_subquery(r);
+               if (rel && is_left(rel->op)) {
+                       r = rel->r = rel_crossproduct(sql->sa, rel->r, r, 
/*(!quantifier)?op_semi:*/op_join);
+                       if (rdependent)
+                               set_dependent(r);
+               } else if (rel && is_right(rel->op)) {
+                       l = rel->l = rel_crossproduct(sql->sa, rel->l, r, 
(!quantifier)?op_semi:op_join);
+                       if (ldependent)
+                               set_dependent(l);
+               } else {
+                       rel = rel_crossproduct(sql->sa, rel, r, 
(!quantifier)?op_semi:op_join);
+               }
+       } else {
+               rel = rel_crossproduct(sql->sa, l, r, 
(!quantifier)?op_semi:op_join);
+       }
+       if (rel && ldependent && rdependent)
+               set_dependent(rel);
+       return rel_compare_exp(query, rel, ls, rs, compare_op, NULL, k.reduce, 
quantifier, need_not);
+}
+
+static sql_rel *
 rel_compare(sql_query *query, sql_rel *rel, symbol *sc, symbol *lo, symbol 
*ro, symbol *ro2,
                char *compare_op, int f, exp_kind k, int quantifier)
 {
@@ -1853,6 +1912,9 @@ rel_compare(sql_query *query, sql_rel *r
                compare_op[1] = 0;
        }
 
+       if (0 && !ro2 && lo->token == SQL_SELECT && ro->token == SQL_SELECT)
+               return rel_compare_selects(query, rel, lo, ro, compare_op, f, 
k, quantifier, need_not);
+
        if (!ro2 && lo->token == SQL_SELECT) { /* swap subquery to the right 
hand side */
                symbol *tmp = lo;
 
@@ -3102,7 +3164,7 @@ rel_in_exp(sql_query *query, sql_rel *re
                                        } else if (!exp_is_atom(l) && 
exp_name(l)) {
                                                l = exp_ref(sql->sa, l);
                                        }
-                                       set_freevar(l);
+                                       set_freevar(l, 0); /* TODO: which outer 
? */
                                        /* label to solve name conflicts with 
outer query */
                                        z = rel_add_identity2(sql, z, &tid);
                                        tid = exp_ref(sql->sa, tid);
@@ -4226,9 +4288,14 @@ static sql_exp *
        }
 
        if (all_freevar) { //* case 2, ie use outer 
-               //assert(query->outer->top == 1);
-               /* TODO find proper relation */
-               res = groupby = query_fetch_outer(query, 0);
+               /* find proper relation, base on freevar (stack hight) */
+               for (node *n = exps->h; n; n = n->next) {
+                       sql_exp *e = n->data;
+
+                       if (all_freevar<is_freevar(e))
+                               all_freevar = is_freevar(e);
+               }
+               res = groupby = query_fetch_outer(query, all_freevar-1);
        }
 
        /* find having select */
@@ -4339,7 +4406,7 @@ static sql_exp *
                                e = exp_ref(sql->sa, e);
                        }
                        e->card = CARD_ATOM;
-                       set_freevar(e);
+                       set_freevar(e, all_freevar-1);
                        return e;
                }
                return e;
@@ -4466,7 +4533,7 @@ static sql_exp *
                                e = exp_ref(sql->sa, e);
                        }
                        e->card = CARD_ATOM;
-                       set_freevar(e);
+                       set_freevar(e, all_freevar-1);
                        return e;
                }
                return e;
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
@@ -46,7 +46,7 @@ exp_set_freevar(mvc *sql, sql_exp *e, sq
                if ((e->l && rel_bind_column2(sql, r, e->l, e->r, 0)) ||
                    (!e->l && rel_bind_column(sql, r, e->r, 0)))
                     return;
-               set_freevar(e);
+               set_freevar(e, 0);
                break;
        case e_atom: 
        case e_psm: 
@@ -485,7 +485,10 @@ exp_rewrite(mvc *sql, sql_rel *rel, sql_
        e->l = exps_rewrite(sql, rel, e->l, ad, isleftouter);
                sf = e->f;
        /* window functions need to be run per freevars */
-       if (sf->func->type == F_ANALYTIC && list_length(sf->func->ops) > 2) {
+       if (sf->func->type == F_ANALYTIC && list_length(sf->func->ops) > 2 && 
+                       (strcmp(sf->func->base.name, "diff") == 0 ||
+                        strcmp(sf->func->base.name, "rank") == 0 ||
+                        strcmp(sf->func->base.name, "row_number") == 0)) {
                sql_subtype *bt = sql_bind_localtype("bit");
                node *d;
                list *rankopargs = e->l;
@@ -578,7 +581,7 @@ push_up_project(mvc *sql, sql_rel *rel, 
                                        if (exp_has_freevar(sql, e)) 
                                                rel_bind_var(sql, rel->l, e);
                                }
-                               e = exp_rewrite(sql, r->l, e, ad, 
is_left(rel->op)|is_semi(rel->op));
+                               e = exp_rewrite(sql, r->l, e, ad, 
is_left(rel->op));
                                append(n->exps, e);
                        }
                        if (r->r) {
@@ -628,9 +631,17 @@ push_up_project(mvc *sql, sql_rel *rel, 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to