Changeset: 16bd9ee60291 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/16bd9ee60291 Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql.c sql/common/sql_types.c sql/server/rel_multiset.c sql/storage/store.c Branch: nested Log Message:
use sequence numbers for unique multiset id's diffs (276 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 @@ -788,11 +788,14 @@ value_list(backend *be, sql_exp *vals_ex if (!is_row(vals_exp) && type->type->composite) { bte multiset = type->multiset; list *attr = sa_list(be->mvc->sa); + sql_exp *v = vals->h->data; if (tuple_create_result(be, vals->h->data, attr, multiset) < 0) return NULL; - int rowcnt = 1, lcnt = 1; - for (node *n = vals->h; n; n = n->next, lcnt++) { - if (append_tuple(be, n->data, left, sel, attr, rowcnt, lcnt++, multiset) < 0) + int rowcnt = 0, lcnt = 1; + int irc = is_row(v)?0:1; + int lrc = is_row(v)?1:0; + for (node *n = vals->h; n; n = n->next, rowcnt += irc, lcnt += lrc) { + if (append_tuple(be, n->data, left, sel, attr, rowcnt, lcnt, multiset) < 0) return NULL; } return tuple_result(be, attr); @@ -1595,15 +1598,22 @@ is_const_func(sql_subfunc *f, list *attr static stmt* exp2bin_multiset(backend *be, sql_exp *fe, stmt *left, stmt *right, stmt *sel) { - (void)be; (void)fe; (void)right; (void)sel; - assert(list_length(left->op4.lval) == 1); - stmt *s = left->op4.lval->h->data; - while(s->type == st_alias) - s = s->op1; - return s; + list *l = sa_list(be->mvc->sa); + for(node *n = left->op4.lval->h; n; n = n->next) { + stmt *s = n->data, *ns = s; + while(ns->type == st_alias) + ns = ns->op1; + if (ns->type == st_list) { + for(node *m = ns->op4.lval->h; m; m = m->next) + append(l, m->data); + } else { + append(l, s); + } + } + return stmt_list(be, l); } static stmt* 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 @@ -1003,6 +1003,89 @@ mvc_next_value(Client cntxt, MalBlkPtr m throw(SQL, "sql.next_value", SQLSTATE(HY050) "Cannot generate next sequence value %s.%s", sname, seqname); } +static str +mvc_renumber(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + (void)cntxt; + (void)mb; + (void)stk; + (void)pci; + assert(0); + return MAL_SUCCEED; +} + +static str +mvc_renumber_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + bat *res = getArgReference_bat(stk, pci, 0); + bat *input = getArgReference_bat(stk, pci, 1); + bat *old_id = getArgReference_bat(stk, pci, 2); + bat *new_id = getArgReference_bat(stk, pci, 3); + (void)cntxt; + (void)mb; + + BAT *r, *i, *bo, *bn; + + i = BATdescriptor(*input); + bo = BATdescriptor(*old_id); + bn = BATdescriptor(*new_id); + if (!i || !bo || !bn) { + BBPreclaim(bo); + BBPreclaim(bn); + return createException(SQL, "sql.renumber", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + } + + BUN cnt = BATcount(i); + BUN bcnt = BATcount(bo); + int *ii = Tloc(i,0); + int *oi = Tloc(bo,0); + int *ni = Tloc(bn,0); + /* TODO handle nils */ + /* if oi is dense, use offset based renumbers */ + if (!bo->tsorted || !BATtkey(bo) || (bcnt && (oi[0] + (int)(bcnt-1)) != oi[bcnt-1]) ) { + BAT *lo = NULL; + printf("not dense %d\n", oi[0]); + if (BATleftjoin(&lo, NULL, i, bo, NULL, NULL, false, cnt) != GDK_SUCCEED) { + BBPreclaim(i); + BBPreclaim(bo); + BBPreclaim(bn); + throw(SQL, "sql.renumber", SQLSTATE(42000) "renumber failed\n"); + } + r = BATproject(lo, bn); + BBPreclaim(lo); + if (!r) { + BBPreclaim(i); + BBPreclaim(bo); + BBPreclaim(bn); + throw(SQL, "sql.renumber", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + } else { + if (!(r = COLnew(0, TYPE_int, cnt, TRANSIENT))) { + BBPreclaim(i); + BBPreclaim(bo); + BBPreclaim(bn); + throw(SQL, "sql.renumber", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + int *ri = Tloc(r,0); + int base = oi[0]; + for (BUN j = 0; j<cnt; j++){ + ri[j] = ni[ii[j]-base]; + } + BATsetcount(r, cnt); + } + r->tnonil = i->tnonil; + r->tnil = i->tnil; + r->tsorted = i->tsorted; + r->trevsorted = i->trevsorted; + r->tkey = i->tkey; + BBPreclaim(i); + BBPreclaim(bo); + BBPreclaim(bn); + *res = r->batCacheid; + BBPkeepref(r); + return MAL_SUCCEED; +} + str mvc_next_value_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { @@ -5633,6 +5716,9 @@ static mel_func sql_init_funcs[] = { pattern("sql", "setVariable", setVariable, true, "Set the value of a session variable", args(1,5, arg("",int),arg("mvc",int),arg("sname",str),arg("varname",str),argany("value",1))), pattern("sql", "getVariable", getVariable, false, "Get the value of a session variable", args(1,4, argany("",1),arg("mvc",int),arg("sname",str),arg("varname",str))), pattern("sql", "logfile", mvc_logfile, true, "Enable/disable saving the sql statement traces", args(1,2, arg("",void),arg("filename",str))), + //pattern("batsql", "renumber", mvc_renumber_bulk, false, "return the input b renumbered using values from base", args(1,6, batarg("res",int),batarg("input",int),batarg("mapping_oid",int),batarg("mapping_nid",int),batarg("s1",oid),batarg("s2",oid),batarg("s3",oid))), + pattern("batsql", "renumber", mvc_renumber_bulk, false, "return the input b renumbered using values from base", args(1,4, batarg("res",int),batarg("input",int),batarg("mapping_oid",int),batarg("mapping_nid",int))), + pattern("sql", "renumber", mvc_renumber, false, "return the input b renumbered using values from base", args(1,4, arg("res",int),arg("input",int),arg("mapping_oid",int),arg("mapping_nid",int))), pattern("sql", "next_value", mvc_next_value, true, "return the next value of the sequence", args(1,3, arg("",lng),arg("sname",str),arg("sequence",str))), pattern("batsql", "next_value", mvc_next_value_bulk, true, "return the next value of the sequence", args(1,4, batarg("",lng),arg("card",lng), arg("sname",str),arg("sequence",str))), pattern("sql", "get_value", mvc_get_value, false, "return the current value of the sequence (ie the next to be used value)", args(1,3, arg("",lng),arg("sname",str),arg("sequence",str))), 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 @@ -1740,16 +1740,13 @@ sqltypeinit( allocator *sa) sql_create_procedure(sa, "sys_update_tables", "sql", "update_tables", FALSE, 0); /* virtual multiset mapping functions */ - sql_create_func(sa, "rowid", "", "", TRUE, TRUE, SCALE_NONE, 0, OID, 0); - sql_create_func(sa, "multisetid", "", "", TRUE, TRUE, SCALE_NONE, 0, OID, 1, ANY); - sql_create_func(sa, "multisetnr", "", "", TRUE, TRUE, SCALE_NONE, 0, INT, 1, ANY); - sql_create_func(sa, "multisetfield", "", "", TRUE, TRUE, SCALE_NONE, 0, ANY, 1, ANY); f = sql_create_union(sa, "multiset", "", "", TRUE, SCALE_NONE, 0, TABLE, 1, ANY); f->vararg = 1; f->varres = 1; f = sql_create_union(sa, "unnest", "", "", TRUE, SCALE_NONE, 0, TABLE, 1, ANY); /* unnest multiset */ f->vararg = 1; f->varres = 1; + sql_create_func(sa, "renumber", "sql", "renumber", FALSE, FALSE, SCALE_NONE, 0, INT, 3, INT, INT, INT); } void diff --git a/sql/server/rel_multiset.c b/sql/server/rel_multiset.c --- a/sql/server/rel_multiset.c +++ b/sql/server/rel_multiset.c @@ -6,6 +6,8 @@ #include "rel_basetable.h" #include "rel_updates.h" +extern void _rel_print(mvc *sql, sql_rel *cur); + static sql_rel * fm_insert(visitor *v, sql_rel *rel) { @@ -22,22 +24,52 @@ fm_insert(visitor *v, sql_rel *rel) sql_rel *cur = NULL; sql_rel *ins = rel->r; assert(is_project(ins->op) || is_base(ins->op)); - list *exps = ins->exps; + list *exps = ins->exps, *niexps = sa_list(v->sql->sa); list *btexps = sa_list(v->sql->sa); /* do insert per multiset and once for base table */ + rel->r = ins = rel_project(v->sql->sa, ins, niexps); for(node *n = ol_first_node(t->columns), *m = exps->h; n && m; n = n->next) { sql_column *c = n->data; if (c->type.multiset) { + sql_subfunc *next_val = sql_find_func(v->sql, "sys", "next_value_for", 2, F_FUNC, false, NULL); + list *args = sa_list(v->sql->sa); + sql_exp *rowid = m->data; + append(args, exp_atom_clob(v->sql->sa, "sys")); + append(args, exp_atom_clob(v->sql->sa, c->storage_type)); + sql_exp *nrowid = exp_op(v->sql->sa, args, next_val), *e; + sql_subtype *inttype = sql_bind_localtype("int"); + nrowid = exp_convert(v->sql, nrowid, exp_subtype(nrowid), inttype); + exp_prop_alias(v->sql->sa, nrowid, rowid); + append(niexps, nrowid); + nrowid = exp_ref(v->sql, nrowid); + + exp_setalias(rowid, ++v->sql->label, rowid->alias.parent, "oldid"); + rowid = exp_ref(v->sql, rowid); + list *nexps = sa_list(v->sql->sa); - append(btexps, exp_ref(v->sql, m->data)); /* rowid */ + append(btexps, nrowid); m = m->next; /* find fields and msid,nr from right handside */ - for(node *f = c->type.type->d.fields->h; f; f = f->next, m = m->next) - append(nexps, exp_ref(v->sql, m->data)); + for(node *f = c->type.type->d.fields->h; f; f = f->next, m = m->next) { + append(niexps, e = exp_ref(v->sql, m->data)); + append(nexps, exp_ref(v->sql, e)); + } + + sql_subfunc *renumber = sql_find_func(v->sql, "sys", "renumber", 3, F_FUNC, false, NULL); + args = sa_list(v->sql->sa); + sql_exp *msid = exp_ref(v->sql, m->data); + append(args, msid); + append(args, rowid); + append(args, nrowid); + sql_exp *nmsid = exp_op(v->sql->sa, args, renumber); + exp_prop_alias(v->sql->sa, nmsid, msid); + append(niexps, nmsid); + append(nexps, exp_ref(v->sql, m->data)); m = m->next; if (c->type.multiset == MS_ARRAY) { - append(nexps, exp_ref(v->sql, m->data)); + append(niexps, e = exp_ref(v->sql, m->data)); + append(nexps, exp_ref(v->sql, e)); m = m->next; } sql_table *t = mvc_bind_table(v->sql, c->t->s, c->storage_type); @@ -53,7 +85,10 @@ fm_insert(visitor *v, sql_rel *rel) else cur = i; } else { - append(btexps, exp_ref(v->sql, m->data)); + sql_exp *e = exp_ref(v->sql, m->data); + append(niexps, e); + append(btexps, exp_ref(v->sql, e)); + m = m->next; } } rel->r = rel_project(v->sql->sa, rel->r, btexps); @@ -170,6 +205,7 @@ flatten_multiset(visitor *v, sql_rel *re return fm_join(v, rel); case op_insert: return fm_insert(v, rel); + //case op_truncate: ie also truncate multiset table and restart sequence number default: //printf("todo %d\n", rel->op); return rel; diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -3887,7 +3887,7 @@ sql_trans_copy_column( sql_trans *tr, sq col->storage_type = _STRDUP(buf); if ((res = sql_trans_create_table(&tt, tr, t->s, col->storage_type, NULL, tt_table, true, t->persistence, 0, 0, 0)) != LOG_OK) return res; - if (sql_trans_create_sequence(tr, t->s, col->storage_type, 1, 1, lng_nil, 1, 1, false, true) != LOG_OK) + if (sql_trans_create_sequence(tr, t->s, col->storage_type, 1, 1, GDK_lng_max, 1, 1, false, true) != LOG_OK) return res; } /* All nested types, need the internal columns for the field contents */ _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org