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 -- [email protected]
To unsubscribe send an email to [email protected]