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