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

Reply via email to