Changeset: 206926235510 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=206926235510
Modified Files:
sql/common/sql_stack.c
sql/include/sql_stack.h
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/server/rel_updates.c
Branch: subquery
Log Message:
fixing some problems with nested dependent joins
diffs (truncated from 440 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
@@ -24,7 +24,6 @@ sql_stack_new(sql_allocator *sa, int siz
_DELETE(s);
return NULL;
}
- s -> values[s->top++] = NULL;
return s;
}
@@ -44,5 +43,21 @@ sql_stack_push(sql_stack *s, void *v)
void *
sql_stack_pop(sql_stack *s)
{
+ if (s->top == 0)
+ return NULL;
return s->values[--s->top];
}
+
+void *
+sql_stack_peek(sql_stack *s, int p)
+{
+ if (p>=s->top)
+ return NULL;
+ return s->values[(s->top-1)-p];
+}
+
+int
+sql_stack_empty(sql_stack *s)
+{
+ return (s->top == 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,5 +30,7 @@ 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 int sql_stack_empty(sql_stack *s);
#endif /* SQL_STACK_H */
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
@@ -1088,8 +1088,12 @@ rel_column_ref(sql_query *query, sql_rel
if (!exp && rel && *rel)
exp = rel_bind_column(sql, *rel, name, f);
- if (!exp && query && query->outer) {
- exp = rel_bind_column(sql, query->outer, name, f);
+ if (!exp && query && query_has_outer(query)) {
+ int i;
+ sql_rel *outer;
+
+ for (i=0; !exp && (outer = query_fetch_outer(query,i));
i++)
+ exp = rel_bind_column(sql, outer, name, f);
if (exp) {
set_freevar(exp);
exp->card = CARD_ATOM;
@@ -1131,8 +1135,12 @@ rel_column_ref(sql_query *query, sql_rel
if (!exp && rel && *rel)
exp = rel_bind_column2(sql, *rel, tname, cname, f);
- if (!exp && query && query->outer) {
- exp = rel_bind_column2(sql, query->outer, tname, cname,
f);
+ if (!exp && query && query_has_outer(query)) {
+ int i;
+ sql_rel *outer;
+
+ for (i=0; !exp && (outer = query_fetch_outer(query,i));
i++)
+ exp = rel_bind_column2(sql, outer, tname,
cname, f);
if (exp) {
set_freevar(exp);
exp->card = CARD_ATOM;
@@ -1667,8 +1675,10 @@ rel_compare_exp_(sql_query *query, sql_r
if (anti)
set_anti(e);
- if (!rel && query->outer)
- return rel_select(sql->sa, query->outer, e);
+ if (!rel && query_has_outer(query)) {
+ /* for now only top of stack */
+ return rel_select(sql->sa, query_fetch_outer(query, 0), e);
+ }
/* atom or row => select */
if (ls->card > rel->card) {
@@ -1730,7 +1740,7 @@ rel_compare_exp(sql_query *query, sql_re
if (!ls || !rs)
return NULL;
- if (!quantifier && ((!rel && !query->outer) || !reduce)) {
+ if (!quantifier && ((!rel && !query_has_outer(query)) || !reduce)) {
/* TODO to handle filters here */
sql_exp *e;
@@ -1845,9 +1855,9 @@ rel_compare(sql_query *query, sql_rel *r
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
- query->outer = rel;
+ query_push_outer(query, rel);
r = rel_subquery(query, NULL, ro, ek, 0);//
is_sql_sel(f)?APPLY_LOJ:APPLY_JOIN);
- query->outer = NULL;
+ query_pop_outer(query);
/* get inner queries result value, ie
get last expression of r */
@@ -2313,10 +2323,10 @@ rel_logical_value_exp(sql_query *query,
*/
/* expect select ? */
- query->outer = outer;
+ query_push_outer(query, outer);
//r = rel_value_exp(query, &z, sval, f,
ek);
z = rel_subquery(query, NULL, sval, ek,
0);//is_sql_sel(f)?APPLY_LOJ:APPLY_JOIN);
- query->outer = NULL;
+ query_pop_outer(query);
if (z)
r = rel_lastexp(sql, z);
if (z && r) {
@@ -2478,7 +2488,7 @@ rel_logical_value_exp(sql_query *query,
sql_exp *le;
/* no input, assume single value */
- if ((!orel || (is_project(orel->op) && !is_processed(orel) &&
!orel->l && list_empty(orel->exps))) && !query->outer)
+ if ((!orel || (is_project(orel->op) && !is_processed(orel) &&
!orel->l && list_empty(orel->exps))) && !query_has_outer(query))
orel = *rel = rel_project_exp(sql->sa,
exp_atom_bool(sql->sa, 1));
ek.card = card_set;
@@ -2496,9 +2506,9 @@ rel_logical_value_exp(sql_query *query,
sql->session->status = 0;
sql->errstr[0] = 0;
- query->outer = *rel;
+ query_push_outer(query, *rel);
sq = rel_subquery(query, NULL, lo, ek, 0);
- query->outer = NULL;
+ query_pop_outer(query);
if (!sq)
return NULL;
@@ -2888,7 +2898,7 @@ rel_logical_exp(sql_query *query, sql_re
/* if left is a value (possibly NULL) we rewrite to a list of
OR expressions */
/* no input, assume single value */
- if (!rel && !query->outer)
+ if (!rel && !query_has_outer(query))
rel = rel_project_exp(sql->sa, exp_atom_bool(sql->sa,
1));
left = rel;
if (is_sql_sel(f) && !is_processed(left) && left->op ==
op_project) {
@@ -3113,7 +3123,6 @@ rel_logical_exp(sql_query *query, sql_re
sq = rel_subquery(query, NULL, lo, ek, 0);
if (!sq && rel && sql->session->status != -ERR_AMBIGUOUS) { /*
correlation */
- sql_rel *outer = query->outer; /* should join the
outers? */
sql_subaggr *ea = NULL;
sql_exp *le;
@@ -3121,9 +3130,9 @@ rel_logical_exp(sql_query *query, sql_re
sql->session->status = 0;
sql->errstr[0] = '\0';
- query->outer = rel;
+ query_push_outer(query, rel);
sq = rel_subquery(query, NULL, lo, ek, 0);
- query->outer = outer;
+ query_pop_outer(query);
if (!sq)
return NULL;
@@ -3980,7 +3989,7 @@ static sql_exp *
return e;
}
- if (!query->outer && groupby->op != op_groupby) { /*
implicit groupby */
+ if (!query_has_outer(query) && groupby->op != op_groupby) {
/* implicit groupby */
sql_rel *ng = rel_project2groupby(sql, groupby);
if (*rel == groupby) {
@@ -3997,7 +4006,7 @@ static sql_exp *
if (!*rel)
return NULL;
- if (!query->outer && is_sql_where(f)) {
+ if (!query_has_outer(query) && is_sql_where(f)) {
char *uaname = GDKmalloc(strlen(aname) + 1);
sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: not
allowed in WHERE clause",
uaname ? toUpperCopy(uaname, aname) :
aname);
@@ -4183,11 +4192,12 @@ static sql_exp *
sql_exp *e = exp_aggr(sql->sa, exps, a, distinct, no_nil,
CARD_ATOM, have_nil(exps));
/* if aggregate is from outer side, move it over */
- if (freevar && query->outer) {
+ if (freevar && query_has_outer(query)) {
/* add to outer */
- sql_rel *outer = query->outer;
+ sql_rel *outer = query_pop_outer(query);
sql_rel *gb = outer;
+ assert(0);/* added assert for debugging push aggr to
outer side */
exps_reset_freevar(e->l);
if (!is_groupby(gb->op))
gb=outer->l;
@@ -4195,6 +4205,7 @@ static sql_exp *
e = exp_ref(sql->sa, e);
if (gb != outer)
rel_project_add_exp(sql, outer, e);
+ query_push_outer(query, outer);
e = exp_ref(sql->sa, e);
e->card = CARD_ATOM;
set_freevar(e);
@@ -5861,6 +5872,10 @@ rel_value_exp2(sql_query *query, sql_rel
sql_exp *rs = NULL;
sql_rel *outerp = NULL;
+ if (*rel && is_sql_sel(f) && is_project((*rel)->op) &&
!is_processed((*rel))) {
+ outerp = *rel;
+ *rel = (*rel)->l;
+ }
if (!*rel)
return NULL;
@@ -5868,18 +5883,11 @@ rel_value_exp2(sql_query *query, sql_rel
sql->session->status = 0;
sql->errstr[0] = '\0';
- /* add unique */
- //*rel = r = rel_subquery(query, *rel, se, ek,
is_sql_sel(f)?APPLY_LOJ:APPLY_JOIN);
- if (is_sql_sel(f) && is_project((*rel)->op) &&
!is_processed((*rel))) {
- outerp = *rel;
- *rel = (*rel)->l;
- }
- query->outer = *rel;
- r = rel_subquery(query, NULL, se, ek, 0);//
is_sql_sel(f)?APPLY_LOJ:APPLY_JOIN);
- query->outer = NULL;
+ query_push_outer(query, *rel);
+ r = rel_subquery(query, NULL, se, ek, 0);
+ query_pop_outer(query);
if (r) {
rs = _rel_lastexp(sql, r);
- //if (is_sql_sel(f) && exp_card(rs) > CARD_ATOM
&& r->card > CARD_ATOM && r->r) {
if (is_sql_sel(f) && ek.card <= card_column &&
r->card > CARD_ATOM)
{
sql_subaggr *zero_or_one =
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(rs));
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
@@ -588,8 +588,46 @@ rel_general_unnest(mvc *sql, sql_rel *re
return rel;
}
-sql_rel *
-rel_unnest(mvc *sql, sql_rel *rel)
+/* reintroduce selects, for freevar's of other dependent joins */
+static sql_rel *
+push_down_select(mvc *sql, sql_rel *rel)
+{
+ if (!list_empty(rel->exps)) {
+ node *n;
+ list *jexps = sa_list(sql->sa);
+ list *sexps = sa_list(sql->sa);
+ sql_rel *d = rel->l;
+
+ for(n=rel->exps->h; n; n=n->next) {
+ sql_exp *e = n->data;
+ list *v = exp_freevar(sql, e);
+ int found = 1;
+
+ if (v) {
+ node *m;
+ for(m=v->h; m && found; m=m->next) {
+ sql_exp *fv = m->data;
+
+ found = (rel_find_exp(d, fv) != NULL);
+ }
+ }
+ if (found) {
+ append(jexps, e);
+ } else {
+ append(sexps, e);
+ }
+ }
+ if (!list_empty(sexps)) {
+ rel->exps = jexps;
+ rel->r = rel_select(sql->sa, rel->r, NULL);
+ rel->exps = sexps;
+ }
+ }
+ return rel;
+}
+
+static sql_rel *
+rel_unnest_dependent(mvc *sql, sql_rel *rel)
{
sql_rel *nrel = rel;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list