Changeset: 64f9885a0086 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=64f9885a0086
Modified Files:
sql/server/rel_exp.c
sql/server/rel_select.c
sql/server/rel_select.h
sql/server/rel_unnest.c
sql/server/rel_updates.c
sql/test/BugTracker-2016/Tests/LEFT-JOIN_with_OR_conditions_triggers_assertion.Bug-3908.stable.out
sql/test/BugTracker-2017/Tests/aggr_udf_with_more_than_2params.Bug-6385.stable.err
sql/test/BugTracker-2017/Tests/exist-bigint-missing.Bug-6315.stable.out
sql/test/BugTracker-2017/Tests/exists.Bug-6392.stable.out
sql/test/BugTracker-2017/Tests/udf_crash_subquery_scalar_paramters.Bug-6399.stable.err
Branch: subquery
Log Message:
fixing more corner cases
diffs (truncated from 502 to 300 lines):
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
@@ -1981,6 +1981,7 @@ exp_copy( sql_allocator *sa, sql_exp * e
ne->p = prop_copy(sa, e->p);
if (e->name)
exp_setname(sa, ne, exp_find_rel_name(e), exp_name(e));
+ ne->freevar = e->freevar;
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
@@ -550,13 +550,13 @@ find_table_function(mvc *sql, sql_schema
}
static sql_rel *
-rel_named_table_function(sql_query *query, sql_rel *rel, symbol *ast)
+rel_named_table_function(sql_query *query, sql_rel *rel, symbol *ast, int
lateral)
{
mvc *sql = query->sql;
list *exps = NULL, *tl;
node *m;
exp_kind ek = {type_value, card_relation, TRUE};
- sql_rel *sq = NULL;
+ sql_rel *sq = NULL, *outer = NULL;
sql_exp *e = NULL;
sql_subfunc *sf = NULL;
symbol *sym = ast->data.lval->h->data.sym;
@@ -573,7 +573,6 @@ rel_named_table_function(sql_query *quer
if (l->next->type == type_symbol && l->next->data.sym->token ==
SQL_SELECT) {
if (l->next->next != NULL)
return sql_error(sql, 02, SQLSTATE(42000)
"SELECT: '%s' requires a single sub query", fname);
- assert(!rel);
sq = rel_subquery(query, NULL, l->next->data.sym, ek);
} else if (l->next->type == type_symbol || l->next->type ==
type_list) {
dnode *n;
@@ -585,21 +584,23 @@ rel_named_table_function(sql_query *quer
else
n = l->next->data.lval->h;
for ( ; n; n = n->next) {
- sql_rel *z = NULL;
-
- sql_exp *e = rel_value_exp(query, &z,
n->data.sym, sql_sel, iek);
+ sql_exp *e = rel_value_exp(query, &outer,
n->data.sym, sql_sel, iek);
if (!e)
return NULL;
append(exps, e);
}
sq = rel_project(sql->sa, NULL, exps);
+ if (lateral && outer) {
+ sq = rel_crossproduct(sql->sa, sq, outer,
op_join);
+ set_dependent(sq);
+ }
}
/* reset error */
sql->session->status = 0;
sql->errstr[0] = '\0';
- if (!sq)
+ if (!sq || (!lateral && outer))
return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no
such operator '%s'", fname);
for (en = sq->exps->h; en; en = en->next) {
sql_exp *e = en->data;
@@ -808,7 +809,7 @@ check_is_lateral(symbol *tableref)
}
sql_rel *
-table_ref(sql_query *query, sql_rel *rel, symbol *tableref)
+table_ref(sql_query *query, sql_rel *rel, symbol *tableref, int lateral)
{
mvc *sql = query->sql;
char *tname = NULL;
@@ -892,7 +893,7 @@ table_ref(sql_query *query, sql_rel *rel
} else if (tableref->token == SQL_VALUES) {
return rel_values(query, tableref);
} else if (tableref->token == SQL_TABLE) {
- return rel_named_table_function(query, rel, tableref);
+ return rel_named_table_function(query, rel, tableref, lateral);
} else if (tableref->token == SQL_TABLE_OPERATOR) {
return rel_named_table_operator(query, rel, tableref);
} else if (tableref->token == SQL_SELECT) {
@@ -1940,7 +1941,7 @@ rel_in_value_exp(sql_query *query, sql_r
sql->errstr[0] = 0;
r = rel_value_exp(query, &left, n->data.sym,
sql_where /* ie no result project */, ek);
- if (r)
+ if (r && !pexps)
*rel = left;
}
if (z && r) {
@@ -3624,6 +3625,16 @@ rel_binop_(sql_query *query, sql_exp *l,
return res;
}
+static int
+rel_check_card(sql_rel *rel, sql_exp *l , sql_exp *r)
+{
+ if (rel && rel->card == CARD_AGGR && l->card != r->card && l->card >
CARD_ATOM && r->card > CARD_ATOM) {
+ if(l->card == CARD_AGGR || r->card == CARD_AGGR)
+ return 1;
+ }
+ return 0;
+}
+
static sql_exp *
rel_binop(sql_query *query, sql_rel **rel, symbol *se, int f, exp_kind ek)
{
@@ -3679,6 +3690,8 @@ rel_binop(sql_query *query, sql_rel **re
if (!l || !r)
return NULL;
+ if (rel_check_card(*rel, l, r))
+ return NULL;
return rel_binop_(query, l, r, s, fname, ek.card);
}
@@ -5844,7 +5857,7 @@ rel_table_exp(sql_query *query, sql_rel
if (!is_project((*rel)->op))
return NULL;
- r = rel_named_table_function( query, (*rel)->l, column_e);
+ r = rel_named_table_function( query, (*rel)->l, column_e, 0);
if (!r)
return NULL;
@@ -6223,7 +6236,7 @@ rel_query(sql_query *query, sql_rel *rel
assert(!rel);
if (sq->token != SQL_SELECT)
- return table_ref(query, rel, sq);
+ return table_ref(query, rel, sq, 0);
/* select ... into is currently not handled here ! */
sn = (SelectNode *) sq;
@@ -6257,14 +6270,14 @@ rel_query(sql_query *query, sql_rel *rel
int lateral = check_is_lateral(n->data.sym);
/* just used current expression */
- fnd = table_ref(query, NULL, n->data.sym);
+ fnd = table_ref(query, NULL, n->data.sym, lateral);
if (!fnd && res && lateral && sql->session->status !=
-ERR_AMBIGUOUS) {
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
query_push_outer(query, res);
- fnd = table_ref(query, NULL, n->data.sym);
+ fnd = table_ref(query, NULL, n->data.sym,
lateral);
query_pop_outer(query);
}
if (!fnd)
@@ -6331,7 +6344,7 @@ rel_setquery(sql_query *query, sql_rel *
sql_rel *t1, *t2;
assert(n->next->type == type_int);
- t1 = table_ref(query, NULL, tab_ref1);
+ t1 = table_ref(query, NULL, tab_ref1, 0);
if (rel && !t1 && sql->session->status != -ERR_AMBIGUOUS) {
sql_rel *r = rel;
@@ -6341,11 +6354,11 @@ rel_setquery(sql_query *query, sql_rel *
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
- t1 = table_ref(query, r, tab_ref1);
+ t1 = table_ref(query, r, tab_ref1, 0);
}
if (!t1)
return NULL;
- t2 = table_ref(query, NULL, tab_ref2);
+ t2 = table_ref(query, NULL, tab_ref2, 0);
if (rel && !t2 && sql->session->status != -ERR_AMBIGUOUS) {
sql_rel *r = rel;
@@ -6356,7 +6369,7 @@ rel_setquery(sql_query *query, sql_rel *
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
- t2 = table_ref(query, r, tab_ref2);
+ t2 = table_ref(query, r, tab_ref2, 0);
}
if (!t2)
return NULL;
@@ -6422,22 +6435,22 @@ rel_joinquery_(sql_query *query, sql_rel
}
lateral = check_is_lateral(tab2);
- t1 = table_ref(query, NULL, tab1);
+ t1 = table_ref(query, NULL, tab1, 0);
if (rel && !t1 && sql->session->status != -ERR_AMBIGUOUS) {
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
- t1 = table_ref(query, NULL, tab1);
+ t1 = table_ref(query, NULL, tab1, 0);
}
if (t1) {
- t2 = table_ref(query, NULL, tab2);
+ t2 = table_ref(query, NULL, tab2, 0);
if (lateral && !t2 && sql->session->status != -ERR_AMBIGUOUS) {
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
query_push_outer(query, t1);
- t2 = table_ref(query, NULL, tab2);
+ t2 = table_ref(query, NULL, tab2, 0);
query_pop_outer(query);
}
}
@@ -6567,11 +6580,11 @@ rel_crossquery(sql_query *query, sql_rel
dnode *n = q->data.lval->h;
symbol *tab1 = n->data.sym;
symbol *tab2 = n->next->data.sym;
- sql_rel *t1 = table_ref(query, rel, tab1);
+ sql_rel *t1 = table_ref(query, rel, tab1, 0);
sql_rel *t2 = NULL;
if (t1)
- t2 = table_ref(query, rel, tab2);
+ t2 = table_ref(query, rel, tab2, 0);
if (!t1 || !t2)
return NULL;
@@ -6584,7 +6597,7 @@ rel_unionjoinquery(sql_query *query, sql
{
mvc *sql = query->sql;
dnode *n = q->data.lval->h;
- sql_rel *lv = table_ref(query, rel, n->data.sym);
+ sql_rel *lv = table_ref(query, rel, n->data.sym, 0);
sql_rel *rv = NULL;
int all = n->next->data.i_val;
list *lexps, *rexps;
@@ -6592,7 +6605,7 @@ rel_unionjoinquery(sql_query *query, sql
int found = 0;
if (lv)
- rv = table_ref(query, rel, n->next->next->data.sym);
+ rv = table_ref(query, rel, n->next->next->data.sym, 0);
assert(n->next->type == type_int);
if (!lv || !rv)
return NULL;
diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h
--- a/sql/server/rel_select.h
+++ b/sql/server/rel_select.h
@@ -30,7 +30,7 @@ extern sql_exp *rel_unop_(sql_query *que
extern sql_exp *rel_binop_(sql_query *query, sql_exp *l, sql_exp *r,
sql_schema *s, char *fname, int card);
extern sql_exp *rel_nop_(sql_query *query, sql_exp *l, sql_exp *r, sql_exp
*r2, sql_exp *r3, sql_schema *s, char *fname, int card);
extern sql_rel *rel_with_query(sql_query *query, symbol *q);
-extern sql_rel *table_ref(sql_query *query, sql_rel *rel, symbol *tableref);
+extern sql_rel *table_ref(sql_query *query, sql_rel *rel, symbol *tableref,
int lateral);
extern sql_rel *rel_loader_function(sql_query* query, symbol* s, list *fexps,
sql_subfunc **loader_function);
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
@@ -260,6 +260,79 @@ rel_bind_var(mvc *sql, sql_rel *rel, sql
}
}
+static sql_exp * push_up_project_exp(mvc *sql, sql_rel *rel, sql_exp *e);
+
+static list *
+push_up_project_exps(mvc *sql, sql_rel *rel, list *exps)
+{
+ node *n;
+
+ if (!exps)
+ return exps;
+
+ for(n=exps->h; n; n=n->next) {
+ sql_exp *e = n->data;
+
+ n->data = push_up_project_exp(sql, rel, e);
+ }
+ return exps;
+}
+
+static sql_exp *
+push_up_project_exp(mvc *sql, sql_rel *rel, sql_exp *e)
+{
+ switch(e->type) {
+ case e_cmp:
+ if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
+ e->l = push_up_project_exps(sql, rel, e->l);
+ e->r = push_up_project_exps(sql, rel, e->r);
+ return e;
+ } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+ e->l = push_up_project_exp(sql, rel, e->l);
+ e->r = push_up_project_exps(sql, rel, e->r);
+ return e;
+ } else {
+ e->l = push_up_project_exp(sql, rel, e->l);
+ e->r = push_up_project_exp(sql, rel, e->r);
+ if (e->f)
+ e->f = push_up_project_exp(sql, rel, e->f);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list