Changeset: 9b542205f1f0 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9b542205f1f0
Modified Files:
        sql/common/sql_types.c
        sql/include/sql_catalog.h
        sql/include/sql_relation.h
        sql/server/rel_rel.c
        sql/server/rel_select.c
        sql/server/rel_xml.c
        sql/server/sql_parser.h
        sql/server/sql_parser.y
        sql/server/sql_scan.c
Branch: graph0
Log Message:

WIP: op_unnest


diffs (226 lines):

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
@@ -158,6 +158,7 @@ sql_init_subtype(sql_subtype *res, sql_t
        if (t->digits && res->digits > t->digits)
                res->digits = t->digits;
        res->scale = scale;
+       res->attributes = NULL;
 }
 
 sql_subtype *
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -134,14 +134,15 @@ typedef enum comp_type {
        cmp_or = 7,
        cmp_in = 8,
        cmp_notin = 9,
+       cmp_unnest = 10,
 
        /* The followin cmp_* are only used within stmt (not sql_exp) */
-       cmp_all = 10,                   /* special case for crossproducts */
-       cmp_project = 11,               /* special case for projection joins */
-       cmp_joined = 12,                /* special case already joined */
-       cmp_equal_nil = 13,             /* special case equi join, with nil = 
nil */
-       cmp_left = 14,                  /* special case equi join, keep left 
order */
-       cmp_left_project = 15           /* last step of outer join */
+       cmp_all = 11,                   /* special case for crossproducts */
+       cmp_project = 12,               /* special case for projection joins */
+       cmp_joined = 13,                /* special case already joined */
+       cmp_equal_nil = 14,             /* special case equi join, with nil = 
nil */
+       cmp_left = 15,                  /* special case equi join, keep left 
order */
+       cmp_left_project = 16           /* last step of outer join */
 } comp_type;
 
 /* for ranges we keep the requirment for symmetric */
@@ -262,6 +263,7 @@ typedef struct sql_subtype {
        sql_type *type;
        unsigned int digits;
        unsigned int scale;
+       list* attributes; // attributes for a nested table
 } sql_subtype;
 
 /* sql_func need type transform rules types are equal if underlying
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
@@ -140,8 +140,6 @@ typedef struct expression {
 
 #define DDL_EMPTY 100
 
-#define MAXOPS 21
-
 typedef enum operator_type {
        op_basetable = 0,
        op_table,
@@ -161,11 +159,14 @@ typedef enum operator_type {
        op_groupby,     
        op_topn,
        op_sample,
+       op_unnest,
        op_insert,      /* insert(l=table, r insert expressions) */ 
        op_update,      /* update(l=table, r update expressions) */
        op_delete       /* delete(l=table, r delete expression) */
 } operator_type;
 
+#define MAXOPS (op_delete +1)
+
 #define is_atom(et) \
        (et == e_atom)
 /* a simple atom is a literal or on the query stack */
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
@@ -374,6 +374,24 @@ rel_crossproduct(sql_allocator *sa, sql_
        return rel;
 }
 
+
+sql_rel *
+rel_unnest(sql_allocator* sa, sql_rel *l, sql_exp* e){
+       sql_rel *rel = rel_create(sa);
+
+       assert(exp_subtype(e)->type->eclass == EC_NESTED_TABLE);
+       assert(exp_subtype(e)->attributes != NULL);
+       assert(list_length(exp_subtype(e)->attributes) > 0);
+
+       rel->l = l;
+       rel->r = e;
+       rel->op = op_unnest;
+       rel->exps = list_append(sa_list(sa), exp_compare(sa, 
exp_subtype(e)->attributes->h->data, NULL, cmp_unnest));
+       rel->card = CARD_MULTI;
+       rel->nrcols = l->nrcols + list_length(exp_subtype(e)->attributes);
+       return rel;
+}
+
 sql_rel *
 rel_topn(sql_allocator *sa, sql_rel *l, list *exps )
 {
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
@@ -341,6 +341,16 @@ query_exp_optname(mvc *sql, sql_rel *r, 
                        return NULL;
                return rel_table_optname(sql, tq, q->data.lval->t->data.sym);
        }
+       case SQL_UNNEST:
+       {
+               sql_rel* tq = rel_unnestquery(sql, r, q);
+
+               if(!tq)
+                       return NULL;
+
+               return rel_table_optname(sql, tq, q->data.lval->t->data.sym);
+               break;
+       }
        default:
                (void) sql_error(sql, 02, "case %d %s\n", q->token, 
token2string(q->token));
        }
@@ -3418,6 +3428,16 @@ static sql_exp *
                        }
                }
        }
+
+       // record the attributes for nested tables
+       if(a) {
+               sql_subtype* sqltype = a->res->h->data;
+               if(sqltype->type->eclass == EC_NESTED_TABLE){
+                       // suspecting it should be exp_alias_or_copy
+                       sqltype->attributes = exps_copy(sql->sa, a->aggr->ops);
+               }
+       }
+
        if (a && execute_priv(sql,a->aggr)) {
                sql_exp *e = exp_aggr(sql->sa, exps, a, distinct, no_nil, 
groupby->card, have_nil(exps));
 
@@ -5322,6 +5342,29 @@ rel_unionjoinquery(mvc *sql, sql_rel *re
        return rel;
 }
 
+static sql_rel *
+rel_unnestquery(mvc* sql, sql_rel* rel, symbol* q){
+       dnode* head = q->data.lval->h;
+       sql_rel* lhs = NULL;
+       sql_exp* rhs = NULL;
+
+       // bind the table and the column
+       lhs = table_ref(sql, rel, head->data, 0);
+       if(!lhs){
+               return NULL;
+       }
+       rhs = rel_column_ref(sql, &rel, head->next->data, sql_from);
+       if(!rhs){
+               return NULL;
+       }
+
+       rel = rel_unnest(sql->sa, lhs, rhs);
+
+       // add the projection at the end
+
+}
+
+
 sql_rel *
 rel_subquery(mvc *sql, sql_rel *rel, symbol *sq, exp_kind ek, int apply)
 {
diff --git a/sql/server/rel_xml.c b/sql/server/rel_xml.c
--- a/sql/server/rel_xml.c
+++ b/sql/server/rel_xml.c
@@ -13,8 +13,8 @@
 #include "sql_semantic.h"
 #include "sql_parser.h"
 
-static sql_subtype xml_type = { NULL, 0, 0 };
-static sql_subtype str_type = { NULL, 0, 0 };
+static sql_subtype xml_type = { NULL, 0, 0, NULL };
+static sql_subtype str_type = { NULL, 0, 0, NULL };
 
 static sql_exp *
 rel_xmlelement(mvc *sql, sql_rel **rel, symbol *sym, int f, exp_kind knd) 
diff --git a/sql/server/sql_parser.h b/sql/server/sql_parser.h
--- a/sql/server/sql_parser.h
+++ b/sql/server/sql_parser.h
@@ -93,6 +93,7 @@ typedef enum tokens {
        SQL_STORAGE,
        SQL_CROSS,
        SQL_JOIN,
+       SQL_UNNEST,
        SQL_SELECT,
        SQL_CONNECT,
        SQL_DISCONNECT,
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -529,7 +529,7 @@ int yydebug=1;
 %token USER CURRENT_USER SESSION_USER LOCAL LOCKED BEST EFFORT
 %token  CURRENT_ROLE sqlSESSION
 %token <sval> sqlDELETE UPDATE SELECT INSERT 
-%token <sval> LATERAL LEFT RIGHT FULL OUTER NATURAL CROSS JOIN INNER
+%token <sval> LATERAL LEFT RIGHT FULL OUTER NATURAL CROSS JOIN INNER UNNEST
 %token <sval> COMMIT ROLLBACK SAVEPOINT RELEASE WORK CHAIN NO PRESERVE ROWS
 %token  START TRANSACTION READ WRITE ONLY ISOLATION LEVEL
 %token  UNCOMMITTED COMMITTED sqlREPEATABLE SERIALIZABLE DIAGNOSTICS sqlSIZE 
STORAGE
@@ -2938,6 +2938,11 @@ joined_table:
          append_symbol(l, $5);
          append_symbol(l, NULL);
          $$ = _symbol_create_list( SQL_JOIN, l); }
+   |  table_ref UNNEST column_ref
+       { dlist *l = L();
+         append_symbol(l, $1);
+         append_list(l, $3);
+         $$ = _symbol_create_list( SQL_UNNEST, l); }
   ;
 
 join_type:
diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c
--- a/sql/server/sql_scan.c
+++ b/sql/server/sql_scan.c
@@ -226,6 +226,7 @@ scanner_init_keywords(void)
        keywords_insert("PATH", PATH);
        keywords_insert("PRECISION", PRECISION);
        keywords_insert("PRIMARY", PRIMARY);
+       keywords_insert("UNNEST", UNNEST);
 
        keywords_insert("USER", USER);
        keywords_insert("RENAME", RENAME);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to