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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to