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]