Changeset: 180f3e64fd15 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=180f3e64fd15
Modified Files:
sql/backends/monet5/rel_bin.c
sql/include/sql_relation.h
sql/server/rel_distribute.c
sql/server/rel_dump.c
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_optimizer.c
sql/server/rel_partition.c
sql/server/rel_rel.c
sql/server/rel_rel.h
sql/server/rel_select.c
sql/server/sql_parser.y
sql/server/sql_scan.c
Branch: graph0
Log Message:
SEMA: unnest operator
diffs (truncated from 730 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
@@ -1226,7 +1226,7 @@ exp2bin_args(backend *be, sql_exp *e, li
if (e->flag == cmp_or || get_cmp(e) == cmp_filter) {
args = exps2bin_args(be, e->l, args);
args = exps2bin_args(be, e->r, args);
- } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+ } else if (e->flag == cmp_in || e->flag == cmp_notin || e->flag
== cmp_unnest) {
args = exp2bin_args(be, e->l, args);
args = exps2bin_args(be, e->r, args);
} else {
@@ -1319,6 +1319,7 @@ rel2bin_args(backend *be, sql_rel *rel,
case op_select:
case op_topn:
case op_sample:
+ case op_unnest:
if (rel->exps)
args = exps2bin_args(be, rel->exps, args);
args = rel2bin_args(be, rel->l, args);
@@ -4771,6 +4772,9 @@ subrel_bin(backend *be, sql_rel *rel, li
s = rel2bin_sample(be, rel, refs);
sql->type = Q_TABLE;
break;
+ case op_unnest:
+ assert("Not handled yet");
+ break;
case op_insert:
s = rel2bin_insert(be, rel, refs);
if (sql->type == Q_TABLE)
@@ -4995,6 +4999,7 @@ rel_deps(sql_allocator *sa, sql_rel *r,
case op_groupby:
case op_topn:
case op_sample:
+ case op_unnest:
if (rel_deps(sa, r->l, refs, l) != 0)
return -1;
break;
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
@@ -60,7 +60,7 @@ typedef struct expression {
#define APPLY_NOTEXISTS 64
/* ASCENDING > 15 else we have problems with cmp types */
-#define ASCENDING 16
+#define ASCENDING 32
#define CMPMASK (ASCENDING-1)
#define get_cmp(e) (e->flag&CMPMASK)
#define ANTISEL 32
@@ -200,8 +200,10 @@ typedef enum operator_type {
(op == op_join || is_outerjoin(op))
#define is_semi(op) \
(op == op_semi || op == op_anti)
+#define is_unnest(op) \
+ (op == op_unnest)
#define is_joinop(op) \
- (is_join(op) || is_semi(op))
+ (is_join(op) || is_semi(op) || is_unnest(op))
#define is_apply(op) \
(op == op_apply)
#define is_select(op) \
@@ -227,6 +229,7 @@ typedef enum operator_type {
#define is_sample(op) \
(op == op_sample)
+
/* NO NIL semantics of aggr operations */
#define need_no_nil(e) \
((e->flag&NO_NIL)==NO_NIL)
diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c
--- a/sql/server/rel_distribute.c
+++ b/sql/server/rel_distribute.c
@@ -52,6 +52,7 @@ has_remote_or_replica( sql_rel *rel )
case op_groupby:
case op_topn:
case op_sample:
+ case op_unnest:
if (has_remote_or_replica( rel->l ))
return 1;
break;
@@ -163,6 +164,7 @@ replica(mvc *sql, sql_rel *rel, char *ur
case op_groupby:
case op_topn:
case op_sample:
+ case op_unnest:
rel->l = replica(sql, rel->l, uri);
break;
case op_ddl:
@@ -252,6 +254,7 @@ distribute(mvc *sql, sql_rel *rel)
case op_groupby:
case op_topn:
case op_sample:
+ case op_unnest:
rel->l = distribute(sql, rel->l);
l = rel->l;
if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) {
@@ -304,6 +307,7 @@ rel_remote_func(mvc *sql, sql_rel *rel)
case op_groupby:
case op_topn:
case op_sample:
+ case op_unnest:
rel->l = rel_remote_func(sql, rel->l);
break;
case op_ddl:
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
@@ -183,6 +183,10 @@ exp_print(mvc *sql, stream *fout, sql_ex
mnstr_printf(fout, " !");
mnstr_printf(fout, " FILTER %s ", f->func->base.name);
exps_print(sql, fout, e->r, depth, alias, 1);
+ } else if (get_cmp(e) == cmp_unnest){
+ exp_print(sql, fout, e->l, depth, 0, alias);
+ mnstr_printf(fout, " => ");
+ exps_print(sql, fout, e->r, depth, alias, 1);
} else if (e->f) {
exp_print(sql, fout, e->r, depth+1, 0, 0);
if (is_anti(e))
@@ -472,6 +476,25 @@ rel_print_(mvc *sql, stream *fout, sql_
if (rel->r && rel->op == op_project) /* order by columns */
exps_print(sql, fout, rel->r, depth, 1, 0);
break;
+ case op_unnest: {
+ print_indent(sql, fout, depth, decorate);
+ mnstr_printf(fout, "unnest (");
+
+ // lhs
+ if (rel_is_ref(rel->l)) {
+ int nr = find_ref(refs, rel->l);
+ print_indent(sql, fout, depth+1, decorate);
+ mnstr_printf(fout, "& REF %d ", nr);
+ } else
+ rel_print_(sql, fout, rel->l, depth+1, refs, decorate);
+ mnstr_printf(fout, ",");
+
+ // rhs
+ exps_print(sql, fout, rel->exps, depth, 1, 0);
+
+ mnstr_printf(fout, ")");
+ break;
+ }
case op_insert:
case op_update:
case op_delete: {
@@ -555,6 +578,7 @@ rel_print_refs(mvc *sql, stream* fout, s
case op_groupby:
case op_topn:
case op_sample:
+ case op_unnest:
rel_print_refs(sql, fout, rel->l, depth, refs, decorate);
if (rel->l && rel_is_ref(rel->l) && !find_ref(refs, rel->l)) {
rel_print_(sql, fout, rel->l, depth, refs, decorate);
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
@@ -12,6 +12,7 @@
#include "rel_prop.h" /* for prop_copy() */
#include "rel_optimizer.h"
#include "rel_distribute.h"
+#include "rel_rel.h"
#ifdef HAVE_HGE
#include "mal.h" /* for have_hge */
#endif
@@ -106,6 +107,17 @@ exp_compare(sql_allocator *sa, sql_exp *
return e;
}
+
+sql_exp*
+exp_unnest(sql_allocator* sa, sql_exp* column, list* attributes){
+ sql_exp *e = exp_create(sa, e_cmp);
+ e->card = CARD_MULTI;
+ e->l = column;
+ e->r = attributes;
+ e->flag = cmp_unnest;
+ return e;
+}
+
sql_exp *
exp_compare2(sql_allocator *sa, sql_exp *l, sql_exp *r, sql_exp *h, int
cmptype)
{
@@ -1188,11 +1200,14 @@ rel_find_exp_( sql_rel *rel, sql_exp *e)
return NULL;
switch(e->type) {
case e_column:
- if (rel->exps && (is_project(rel->op) || is_base(rel->op))) {
+ if (rel->exps && (is_project(rel->op) || is_base(rel->op) ||
is_unnest(rel->op))) {
+ list* exps = rel->exps;
+ if (is_unnest(rel->op))
+ exps = rel_unnest_attributes(rel);
if (e->l) {
- ne = exps_bind_column2(rel->exps, e->l, e->r);
+ ne = exps_bind_column2(exps, e->l, e->r);
} else {
- ne = exps_bind_column(rel->exps, e->r, NULL);
+ ne = exps_bind_column(exps, e->r, NULL);
}
}
return ne;
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
@@ -28,6 +28,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);
extern sql_exp *exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype);
+extern sql_exp* exp_unnest(sql_allocator* sa, sql_exp* column, list*
attributes);
#define exp_fromtype(e) ((list*)e->r)->h->data
#define exp_totype(e) ((list*)e->r)->h->next->data
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
@@ -117,6 +117,7 @@ name_find_column( sql_rel *rel, char *rn
case op_select:
case op_topn:
case op_sample:
+ case op_unnest:
return name_find_column( rel->l, rname, name, pnr, bt);
case op_union:
case op_inter:
@@ -243,6 +244,7 @@ rel_properties(mvc *sql, global_props *g
break;
case op_project:
case op_select:
+ case op_unnest:
case op_groupby:
case op_topn:
case op_sample:
@@ -283,6 +285,7 @@ rel_properties(mvc *sql, global_props *g
case op_topn:
case op_sample:
case op_select:
+ case op_unnest:
break;
case op_insert:
@@ -1080,7 +1083,8 @@ rel_join_order(mvc *sql, sql_rel *rel)
case op_select:
case op_groupby:
case op_topn:
- case op_sample:
+ case op_sample:
+ case op_unnest:
rel->l = rel_join_order(sql, rel->l);
break;
case op_ddl:
@@ -5581,6 +5585,9 @@ exp_mark_used(sql_rel *subrel, sql_exp *
l = e->r;
for (n = l->h; n != NULL; n = n->next)
nr += exp_mark_used(subrel, n->data);
+ } else if (e->flag == cmp_unnest) {
+ nr += exp_mark_used(subrel, e->l);
+ // do not mark the attributes here
} else if (e->flag == cmp_in || e->flag == cmp_notin) {
list *r = e->r;
node *n;
@@ -5775,6 +5782,7 @@ rel_mark_used(mvc *sql, sql_rel *rel, in
break;
case op_select:
+ case op_unnest:
if (rel->l) {
exps_mark_used(sql->sa, rel, rel->l);
rel_mark_used(sql, rel->l, 0);
@@ -5912,7 +5920,27 @@ rel_remove_unused(mvc *sql, sql_rel *rel
rel->exps = exps;
}
return rel;
-
+ case op_unnest: { // similar to above
+ list* attributes = rel_unnest_attributes(rel);
+ bool needed = false;
+
+ for(node* n = attributes->h; n && !needed; n = n->next){
+ needed = !((sql_exp*) n->data)->used;
+ }
+
+ if(needed){
+ list* new_attributes = new_exp_list(sql->sa);
+ for(node* n = attributes->h; n; n = n->next){
+ sql_exp *e = n->data;
+
+ if (e->used)
+ append(new_attributes, e);
+ }
+
+ ((sql_exp*)rel->exps->h->data)->r = new_attributes;
+ }
+ return rel;
+ } break;
case op_union:
case op_inter:
case op_except:
@@ -5980,7 +6008,7 @@ rel_dce_refs(mvc *sql, sql_rel *rel)
case op_project:
case op_groupby:
case op_select:
-
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list