Changeset: 5b5ffba33e65 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5b5ffba33e65
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_statement.c
        sql/server/rel_exp.c
        sql/server/rel_multiset.c
        sql/server/rel_optimize_others.c
        sql/server/rel_optimize_proj.c
        sql/server/rel_rel.c
        sql/test/nested/Tests/fileloader.test.in
        sql/test/nested/Tests/webclicks.test.in
Branch: nestedtypes
Log Message:

insert values into nested tyes, use renumber and next_val
fix inserting json object/array

implemented more unnest access patterns


diffs (truncated from 605 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
@@ -1747,6 +1747,31 @@ exp2bin_proto_loader(backend *be, sql_ex
        return (stmt*)pl->load(be, f, filename, topn);
 }
 
+static stmt *
+nested_stmts(backend *be, list *exps, node **M)
+{
+       node *m = *M;
+       list *r = sa_list(be->mvc->sa);
+
+       if (!list_empty(exps)) {
+               for (node *n = exps->h; n && m; n = n->next) {
+                       sql_exp *e = n->data;
+                       if (e->type == e_column && e->f) {
+                               stmt *s = nested_stmts(be, e->f, &m);
+                               s->label = e->alias.label;
+                               append(r, s);
+                       } else {
+                               stmt *s = m->data;
+                               s->label = e->alias.label;
+                               m = m->next;
+                               append(r, s);
+                       }
+               }
+       }
+       *M = m;
+       return stmt_list(be, r);
+}
+
 stmt *
 exp_bin(backend *be, sql_exp *e, stmt *left, stmt *right, stmt *grp, stmt 
*ext, stmt *cnt, stmt *sel, int depth, int reduce, int push)
 {
@@ -1902,17 +1927,8 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                } else {
                        s = stmt_convert(be, l, (!push&&l->nrcols==0)?NULL:sel, 
from, to);
                }
-               if (s && s->type == st_list && e->f) {
-                       list *f = e->f;
-                       list *o = s->op4.lval;
-                       if (list_length(f) != list_length(o))
-                               return NULL;
-                       for(node *n = f->h, *m = o->h; n && m; n = n->next, m = 
m->next) {
-                               sql_exp *e = n->data;
-                               stmt *s = m->data;
-                               s->label = e->alias.label;
-                       }
-               }
+               if (s && s->type == st_list && e->f)
+                       s = nested_stmts(be, e->f, &s->op4.lval->h);
        }       break;
        case e_func: {
                node *en;
@@ -5935,7 +5951,7 @@ insert_composite(stmt **updates, sql_col
 }
 
 static stmt *
-insert_ms(backend *be, sql_table *st, stmt *ms)
+insert_ms(backend *be, sql_table *st, sql_subtype *ct, stmt *ms)
 {
        mvc *sql = be->mvc;
 
@@ -5956,7 +5972,7 @@ insert_ms(backend *be, sql_table *st, st
                        sql_table *nst = mvc_bind_table(sql, st->s, 
c->storage_type);
                        if (!nst)
                                return sql_error(sql, 10, SQLSTATE(27000) 
"INSERT INTO: sub table '%s' missing", c->storage_type);
-                       updates[c->colnr] = insert_ms(be, nst, m->data);
+                       updates[c->colnr] = insert_ms(be, nst, &c->type, 
m->data);
                        n = n->next;
                        m = m->next;
                } else if (c->type.type->composite && !c->type.multiset) {
@@ -5981,6 +5997,32 @@ insert_ms(backend *be, sql_table *st, st
                pos = stmt_claim(be, st, cnt);
 
        int mvc_var = be->mvc_var;
+       stmt *rowids = m->data;
+       stmt *msid = updates[len-1 -((ct->multiset == MS_ARRAY)?1:0)];
+
+       /* nrowids = next_value_for(rowids, "schema?", st->base.name) */
+       InstrPtr q = newStmt(be->mb, batsqlRef, "next_value_ms");
+       q = pushArgument(be->mb, q, rowids->nr);
+       q = pushStr(be->mb, q, st->s->base.name); /* sequence schema name */
+       q = pushStr(be->mb, q, st->base.name);    /* sequence number name */
+       pushInstruction(be->mb, q);
+
+       /* nrowids = batcalc.int(nrowids) */
+       InstrPtr r = newStmt(be->mb, batcalcRef, "int");
+       r = pushArgument(be->mb, r, getArg(q, 0));
+       pushInstruction(be->mb, r);
+
+       /* msid = renumber(msid, rowids, nrowids); */
+       q = newStmt(be->mb, batsqlRef, "renumber");
+       q = pushArgument(be->mb, q, msid->nr);
+       q = pushArgument(be->mb, q, rowids->nr);
+       q = pushArgument(be->mb, q, getArg(r, 0));
+       pushInstruction(be->mb, q);
+
+       /* now update msid and rowids */
+       rowids->nr = getArg(r, 0);
+       msid->nr = getArg(q, 0);
+
        for (n = ol_first_node(st->columns); n; n = n->next) {
 
                sql_column *c = n->data;
@@ -5995,7 +6037,7 @@ insert_ms(backend *be, sql_table *st, st
        }
        be->mvc_var = mvc_var;
 
-       return m->data;
+       return rowids;
 }
 
 static stmt *
@@ -6056,7 +6098,7 @@ rel2bin_insert_ms(backend *be, sql_rel *
                        sql_table *st = mvc_bind_table(sql, t->s, 
c->storage_type);
                        if (!st)
                                return sql_error(sql, 10, SQLSTATE(27000) 
"INSERT INTO: sub table '%s' missing", c->storage_type);
-                       updates[c->colnr] = insert_ms(be, st, m->data);
+                       updates[c->colnr] = insert_ms(be, st, &c->type, 
m->data);
                        n = n->next;
                        m = m->next;
                } else if (c->type.type->composite && !c->type.multiset) {
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -5745,8 +5745,8 @@ insert_json(JSON *js, BAT *bats, int nr,
 }
 #endif
 
-static int insert_json_object(char **msg, JSON *js, BAT **bats, int *BO, int 
nr, int elm, size_t id, msindex_t anr, sql_subtype *t);
-static int insert_json_array(char **msg, JSON *js, BAT **bats, int *BO, int 
nr, int elm, size_t id, msindex_t oanr, sql_subtype *t);
+static int insert_json_object(char **msg, JSON *js, BAT **bats, int *BO, int 
nr, int elm, sql_subtype *t);
+static int insert_json_array(char **msg, JSON *js, BAT **bats, int *BO, int 
nr, int elm, sql_subtype *t);
 
 static ValPtr
 jsonv2local(const ValPtr t, char *v)
@@ -5778,59 +5778,61 @@ jsonv2local(const ValPtr t, char *v)
 }
 
 static int
-insert_json_object(char **msg, JSON *js, BAT **bats, int *BO, int nr, int elm, 
size_t id, msindex_t anr, sql_subtype *t)
+insert_json_object(char **msg, JSON *js, BAT **bats, int *BO, int nr, int elm, 
sql_subtype *t)
 {
        char buf[128]; /* TODO use proper buffer */
        int bat_offset = *BO;
        node *n;
-       JSONterm *jt = js->elm+elm;
-       if (jt->kind != JSON_OBJECT || !t->type->composite) {
+       JSONterm *ja = js->elm+elm;
+       if (ja->kind != JSON_OBJECT || !t->type->composite) {
                *msg = "missing object start";
                return -1;
        }
        const char *name = NULL;
        int nlen = 0, pos = -1, w = list_length(t->type->d.fields), i = 0;
        /* TODO check if full object is there */
-       for (elm++; elm > 0 && elm <= jt->tail+1; elm++) {
+       for (elm++; elm > 0 && elm <= ja->tail+1; elm++) {
                JSONterm *jt = js->elm+elm;
 
+               if (bat_offset > nr)
+                       return -10;
                switch (jt->kind) {
                case JSON_OBJECT:
                        if (name && nlen) {
+                               sql_subtype *nt = NULL;
                                // find subtype matching field
                                for(n = t->type->d.fields->h; n; n = n->next) {
                                        sql_arg *a = n->data;
                                        int alen = (int)strlen(a->name);
                                        if (nlen == alen && strncmp(name, 
a->name, nlen) == 0) {
-                                               t = &a->type;
+                                               nt = &a->type;
                                                break;
                                        }
                                }
+                               assert(nt && !nt->multiset);
+                               elm = insert_json_object(msg, js, bats, 
&bat_offset, nr, elm, nt);
+                       } else {
+                               assert(0);
                        }
-                       //if (bat_offset > old_bat_offset && old_bat_offset != 
0) {
-                               elm = insert_json_object(msg, js, bats, 
&bat_offset, nr, elm, id, anr, t);
-                       //} else {
-                               //elm = insert_json_object(msg, js, bats, 
&bat_offset, nr, elm, id, anr, t);
-                       //}
                        break;
                case JSON_ARRAY:
                        /* TODO get id for nested array from the a global 
struct */
                        if (name && nlen) {
                                // find subtype matching field
+                               sql_subtype *nt = NULL;
                                for(n = t->type->d.fields->h; n; n = n->next) {
                                        sql_arg *a = n->data;
                                        int alen = (int)strlen(a->name);
                                        if (nlen == alen && strncmp(name, 
a->name, nlen) == 0) {
-                                               t = &a->type;
+                                               nt = &a->type;
                                                break;
                                        }
                                }
+                               assert(nt && nt->multiset);
+                               elm = insert_json_array(msg, js, bats, 
&bat_offset, nr, elm, nt);
+                       } else {
+                               assert(0);
                        }
-                       //if (bat_offset > old_bat_offset && old_bat_offset != 
0) {
-                               //elm = insert_json_array(msg, js, bats, 
bat_offset + 2, nr, elm, id, anr, t);
-                       //} else {
-                               elm = insert_json_array(msg, js, bats, 
&bat_offset, nr, elm, id, anr, t);
-                       //}
                        break;
                case JSON_ELEMENT: // field
                        name = jt->value;
@@ -5873,19 +5875,14 @@ insert_json_object(char **msg, JSON *js,
                        bat_offset ++;
                }
        }
-
-       if (t->multiset) {
-               if (elm > 0 && BUNappend(bats[bat_offset++], &id, false) != 
GDK_SUCCEED)
-                       elm = -3;
-               if (elm > 0 && BUNappend(bats[bat_offset++], &anr, false) != 
GDK_SUCCEED)
-                       elm = -3;
-       }
+       if (bat_offset > nr)
+               return -10;
        *BO = bat_offset;
        return elm;
 }
 
 static int
-insert_json_array(char **msg, JSON *js, BAT **bats, int *BO, int nr, int elm, 
size_t id, msindex_t oanr, sql_subtype *t)
+insert_json_array(char **msg, JSON *js, BAT **bats, int *BO, int nr, int elm, 
sql_subtype *t)
 {
        int old_bat_offset = *BO, bat_offset = *BO;
        JSONterm *ja = js->elm+elm;
@@ -5894,27 +5891,26 @@ insert_json_array(char **msg, JSON *js, 
                *msg = "missing array start";
                return -1;
        }
-       int anr = 1; // array number
-       node *n;
+       int id = 0, anr = 1;
        for (; elm < tail; elm=ja->next) { /* array begin, comma, end */
                ja = js->elm+elm;
-               for (elm++; elm >0 && elm < ja->next; elm++) {
+               if (bat_offset > nr)
+                       return -10;
+               for (elm++; elm >0 && elm < ja->next; ) {
                        JSONterm *jt = js->elm+elm;
                        switch (jt->kind) {
                        case JSON_OBJECT:
-                               // FIX assumes array of composite?
                                bat_offset = old_bat_offset;
-                               if (t->type->composite && 
list_length(t->type->d.fields) == 1) {
-                                       n = t->type->d.fields->h;
-                                       if (n) {
-                                               sql_arg *a = n->data;
-                                               sql_subtype *atype = &a->type;
-                                               if (atype->type->composite)
-                                                       t = atype;
-                                       }
+                               sql_subtype *nt = t;
+                               elm = insert_json_object(msg, js, bats, 
&bat_offset, nr, elm, nt);
+                               if (nt->multiset) {
+                                       id = (int)BATcount(bats[bat_offset + 
(nt->multiset == MS_ARRAY?2:1)]);
+                                       if (elm > 0 && 
BUNappend(bats[bat_offset++], &id, false) != GDK_SUCCEED)
+                                               elm = -3;
+                                       if (elm > 0 && nt->multiset == MS_ARRAY 
&& BUNappend(bats[bat_offset++], &anr, false) != GDK_SUCCEED)
+                                               elm = -3;
+                                       anr++;
                                }
-                               elm = insert_json_object(msg, js, bats, 
&bat_offset, nr, elm, id, anr++, t);
-                               (void)oanr; // outer array number
                                break;
                        default:
                                printf("todo\n");
@@ -5923,14 +5919,16 @@ insert_json_array(char **msg, JSON *js, 
                if (elm < 0)
                        break;
        }
+       if (bat_offset > nr)
+               return -10;
        if (elm > 0 && anr > 1 && BUNappend(bats[bat_offset++], &id, false) != 
GDK_SUCCEED)
                elm = -2;
        *BO = bat_offset;
-       return elm+1;
+       return elm-1;//+1;
 }
 
 static str
-insert_json_str(const char *jstr, BAT **bats, int cnt, size_t row_id, 
sql_subtype *t)
+insert_json_str(const char *jstr, BAT **bats, int cnt, sql_subtype *t)
 {
        char *res = MAL_SUCCEED;
        JSON *js = JSONparse(jstr);
@@ -5938,9 +5936,9 @@ insert_json_str(const char *jstr, BAT **
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to