Changeset: a39d581e9e51 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a39d581e9e51
Modified Files:
        sql/backends/monet5/rel_tvtree.c
        sql/backends/monet5/rel_tvtree.h
Branch: tvtree
Log Message:

Simplifies the tv_tree node types and the overall implementation


diffs (truncated from 381 to 300 lines):

diff --git a/sql/backends/monet5/rel_tvtree.c b/sql/backends/monet5/rel_tvtree.c
--- a/sql/backends/monet5/rel_tvtree.c
+++ b/sql/backends/monet5/rel_tvtree.c
@@ -20,127 +20,119 @@
 static tv_type
 tv_get_type(sql_subtype *st)
 {
-       bool comp = st->type->composite;
-
        if (st->multiset) {
                if (st->multiset == MS_ARRAY)
-                       return comp ? TV_MS_COMP : TV_MS_BSC;
+                       return TV_MSET;
                if (st->multiset == MS_SETOF)
-                       return comp ? TV_SO_COMP : TV_SO_BSC;
-       } else if (comp)
+                       return TV_SETOF;
+       } else if (st->type->composite)
                return TV_COMP;
 
        return TV_BASIC;
 }
 
 static tv_tree*
-tv_node(allocator *sa, sql_subtype *st)
+tv_node_(allocator *sa, sql_subtype *st, tv_type tvt)
 {
        tv_tree *n = (sa)?SA_NEW(sa, tv_tree):MNEW(tv_tree);
        if (n == NULL)
                return NULL;
 
        n->st = st;
-       n->tvt = tv_get_type(st);
+       n->tvt = tvt;
        n->rid_idx = 0;
-       n->cf = n->rid = n->msid = n->msnr = n->vals = NULL;
+       n->ctl = n->rid = n->msid = n->msnr = n->vals = NULL;
+
+       return n;
+}
+
+static tv_tree*
+tv_create_(allocator *sa, sql_subtype *st, tv_type tvt)
+{
+       tv_tree *n = tv_node_(sa, st, tvt);
 
-       /* allocate only the lists that we need based on tv-tree type */
+       /* allocate only the lists that we need based on the tv-tree type */
        switch (n->tvt) {
-        case TV_MS_BSC:
-               n->msnr = sa_list(sa);
+               case TV_BASIC:
+                       n->vals = sa_list(sa);
+                       return n;
+        case TV_COMP:
+                       n->ctl = sa_list(sa);
+                       for (node *sf = st->type->d.fields->h; sf; sf = 
sf->next) {
+                               sql_arg *sfa = sf->data;
+                               append(n->ctl, tv_create_(sa, &sfa->type, 
tv_get_type(&sfa->type)));
+                       }
+               return n;
+        case TV_MSET:
+                       n->msnr = sa_list(sa);
                        /* fall through */
-        case TV_SO_BSC:
+        case TV_SETOF:
                n->rid = sa_list(sa);
                n->msid = sa_list(sa);
-                       /* fall through */
-               case TV_BASIC:
-                       n->vals = sa_list(sa);
-                       break;
-        case TV_MS_COMP:
-                       n->msnr = sa_list(sa);
-                       /* fall through */
-               case TV_SO_COMP:
-               n->rid = sa_list(sa);
-               n->msid = sa_list(sa);
-                       /* fall through */
-        case TV_COMP:
-                       n->cf = sa_list(sa);
-               break;
+                       n->ctl = sa_list(sa);
+
+                       /* For MSET/SETOF we make a new child node for the 
values
+                        * NOTE: the ->st of the child is the same as this node 
so
+                        * we need to **EXPLICITLY** specify the tv_type */
+                       tv_tree *sn;
+                       if (st->type->composite)
+                               sn = tv_create_(sa, st, TV_COMP);
+                       else
+                               sn = tv_create_(sa, st, TV_BASIC);
+                       sn->st = st;
+
+                       append(n->ctl, sn);
+
+                       return n;
                default:
                        assert(0);
                        break;
        }
 
-       return n;
+       return NULL;
 }
 
 tv_tree *
 tv_create(backend *be, sql_subtype *st)
 {
-       tv_tree *t = tv_node(be->mvc->sa, st);
-
-       switch (t->tvt) {
-               case TV_MS_BSC:
-               case TV_SO_BSC:
-               case TV_BASIC:
-                       /* no need to do anything */
-                       break;
-               case TV_MS_COMP:
-               case TV_SO_COMP:
-               case TV_COMP:
-                       for (node *n = st->type->d.fields->h; n; n = n->next) {
-                               sql_arg *fa = n->data;
-                               append(t->cf, tv_create(be, &fa->type));
-                       }
-                       break;
-               default:
-                       assert(0);
-                       break;
-       }
-
-       return t;
+       /* there is some ambiguity with the types-value tree construction:
+        * nodes which are mset/setof have their underlying type 
(composite/basic)
+        * in the same subtype->type struct. That's why we have to be careful
+        * with how we generate the nodes. Read carefully tv_node */
+       return tv_create_(be->mvc->sa, st, tv_get_type(st));
 }
 
 static bool
 tv_parse_values_(backend *be, tv_tree *t, sql_exp *value, stmt *left, stmt 
*sel);
 
 static bool
-mset_values_from_array_constructor(backend *be, tv_tree *t, sql_exp *values, 
stmt *left, stmt *sel)
+mset_value_from_array_constructor(backend *be, tv_tree *t, sql_exp *values, 
stmt *left, stmt *sel)
 {
-    /* add the rowid to the mset "origin" table */
+    /* rowid */
     stmt *rid = stmt_atom_int(be, t->rid_idx);
     if (!rid)
         return false;
     assert(t->rid);
     list_append(t->rid, rid);
 
-    /* per value insert actual data, msid(=rowid), msnr(for MS only) */
+    /* per value insert actual data, msid(=rowid), msnr(for MSET only) */
     int msnr_idx = 1;  /* NOTE: in mset-value values are 1-offset indexed */
     list *ms_vals = values->f;
     for (node *n = ms_vals->h; n; n = n->next, msnr_idx++) {
 
-        if (t->tvt == TV_MS_COMP) {
-            assert(t->cf);
-            int cfi = 0;
-            list *cf_vals = ((sql_exp*)n->data)->f;
-            for (node *m = cf_vals->h; m; m = m->next, cfi++)
-                if (false == tv_parse_values_(be, list_fetch(t->cf, cfi), 
m->data, left, sel))
-                    return false;
-        } else {
-            assert(t->vals && !t->cf);
-            stmt *i = exp_bin(be, n->data, left, NULL, NULL, NULL, NULL, sel, 
0, 0, 0);
-            if (!i)
-                return false;
-            list_append(t->vals, i);
-        }
+               /* vals (in the child tree) */
+               assert(list_length(t->ctl) == 1);
+               tv_tree *ct = t->ctl->h->data;
+               tv_parse_values_(be, ct, n->data, left, sel);
 
+               /* msid */
         stmt *msid = stmt_atom_int(be, t->rid_idx);
         if (!msid)
             return false;
         list_append(t->msid, msid);
 
-        if (t->tvt == TV_MS_COMP || t->tvt == TV_MS_BSC) {
+               /* msnr */
+        if (t->tvt == TV_MSET) {
             stmt *msnr = stmt_atom_int(be, msnr_idx);
             if (!msnr)
                 return false;
@@ -148,7 +140,7 @@ mset_values_from_array_constructor(backe
         }
     }
 
-    /* we inserted all the mset-value subvalues so now
+    /* we inserted all the mset-value's subvalues so now
      * increment this tv_tree node's (mset) rowid index */
     t->rid_idx++;
 
@@ -156,7 +148,7 @@ mset_values_from_array_constructor(backe
 }
 
 static bool
-mset_values_from_literal(backend *be, tv_tree *t, sql_exp *values, stmt *left, 
stmt *sel)
+mset_value_from_literal(backend *be, tv_tree *t, sql_exp *values, stmt *left, 
stmt *sel)
 {
     /* per entry-value in the literal the call to exp_bin() will generate an
      * `sql.from_varchar()` instruction. This instructions for a given returns
@@ -164,8 +156,8 @@ mset_values_from_literal(backend *be, tv
      * msnr (multiset vs setof). Those return values will be in an st_list stmt
      * so we have to retrieve them (from stmt_list's op4) and append them to 
the
      * tv_tree list of stmts */
-    assert(t->tvt == TV_SO_BSC || t->tvt == TV_MS_BSC);
-       assert(t->vals && !t->cf);
+    assert(t->tvt == TV_SETOF || t->tvt == TV_MSET);
+       assert(!t->vals && t->ctl);
 
        stmt *i = exp_bin(be, values, left, NULL, NULL, NULL, NULL, sel, 0, 0, 
0);
        if (!i)
@@ -174,10 +166,19 @@ mset_values_from_literal(backend *be, tv
        assert(i->type == st_list);
        assert(list_length(i->op4.lval) == 3 || list_length(i->op4.lval) == 4);
 
+       /* rowid */
        list_append(t->rid, list_fetch(i->op4.lval, 0));
-       list_append(t->vals, list_fetch(i->op4.lval, 1));
+
+       /* vals (in the child tree) */
+       assert(list_length(t->ctl) == 1);
+       tv_tree *ct = t->ctl->h->data;
+       list_append(ct->vals, list_fetch(i->op4.lval, 1));
+
+       /* msid */
        list_append(t->msid, list_fetch(i->op4.lval, 2));
-       if (t->tvt == TV_MS_BSC)
+
+       /* msnr */
+       if (t->tvt == TV_MSET)
                list_append(t->msnr, list_fetch(i->op4.lval, 3));
 
     return true;
@@ -195,23 +196,21 @@ tv_parse_values_(backend *be, tv_tree *t
                        assert(t->vals);
                        list_append(t->vals, i);
                        break;
-               case TV_MS_COMP:
-               case TV_SO_COMP:
-               case TV_MS_BSC:
-               case TV_SO_BSC:
+               case TV_MSET:
+               case TV_SETOF:
             if (is_convert(value->type))
                        /* VALUES ('{1, 2, 3}') */
-                return mset_values_from_literal(be, t, value, left, sel);
+                return mset_value_from_literal(be, t, value, left, sel);
             else
                        /* VALUES (array[1, 2, 3]) */
-                return mset_values_from_array_constructor(be, t, value, left, 
sel);
+                return mset_value_from_array_constructor(be, t, value, left, 
sel);
             break;
                case TV_COMP:
                        assert(value->f);
                        int cnt = 0;
-                       list *cf_vals = value->f;
-                       for (node *n = cf_vals->h; n; cnt++, n = n->next)
-                               if (false == tv_parse_values_(be, 
list_fetch(t->cf, cnt), n->data, left, sel))
+                       list *ct_vals = value->f;
+                       for (node *n = ct_vals->h; n; cnt++, n = n->next)
+                               if (false == tv_parse_values_(be, 
list_fetch(t->ctl, cnt), n->data, left, sel))
                                        return false;
                        break;
                default:
@@ -243,17 +242,15 @@ tv_parse_values(backend *be, tv_tree *t,
         * that's why we need to check for
         *       a. ->row in the first entry of col_vals exp
         *       b. for mset/setof the first ->row in the first entry of vals
-        * If it is set it means we are dealing with a single row insert and we 
need
-        * a dummy expression de (to put vals at its e->f) so parsing the 
values stays
-        * similar with the general case
+        * If it is set it means that we are dealing with a single row insert 
and we
+        * need a dummy expression de (to put vals at its e->f) so parsing the 
values
+        * stays similar with the general case
         */
        bool single_row_val = false;
        single_row_val |= col_vals->row;
-       if ((t->tvt == TV_MS_BSC) || (t->tvt == TV_MS_COMP) ||
-           (t->tvt == TV_SO_BSC) || (t->tvt == TV_SO_COMP))
+       if ((t->tvt == TV_MSET) || (t->tvt == TV_SETOF))
                single_row_val |= ((sql_exp*)vals->h->data)->row;
 
-
     if (single_row_val) {
                /* we need to create a dummy expression to single row vals
                 * to adhere to the rest of the api */
@@ -280,30 +277,27 @@ tv_generate_stmts_(backend *be, tv_tree 
                        ap = stmt_append_bulk(be, stmt_temp(be, t->st), 
t->vals);
                        list_append(stmts_list, ap);
                        break;
-               case TV_MS_BSC:
-               case TV_SO_BSC:
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to