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