Changeset: 3eab74799708 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3eab74799708
Modified Files:
cmake/os_release_info.cmake
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql.c
sql/backends/monet5/sql_rank.c
sql/backends/monet5/sql_statement.c
sql/common/sql_types.c
sql/server/rel_exp.c
sql/server/rel_multiset.c
sql/server/rel_select.c
sql/storage/store.c
Branch: nested
Log Message:
handling more nested multisets
diffs (truncated from 628 to 300 lines):
diff --git a/cmake/os_release_info.cmake b/cmake/os_release_info.cmake
--- a/cmake/os_release_info.cmake
+++ b/cmake/os_release_info.cmake
@@ -29,7 +29,7 @@ set(_os_release_info TRUE)
# of the local cmake environment.
# Set cmake policies for at least this level:
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.10)
# Function get_os_release_info - Determine and return OS name and version
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
@@ -681,84 +681,108 @@ set_value_list(backend *be, sql_exp *val
}
static int
-tuple_create_result(backend *be, sql_exp *tuple, list *cols, bte multiset)
-{
- if (multiset && !is_row(tuple)) {
- assert(is_values(tuple));
- list *tuples = exp_get_values(tuple);
- tuple = tuples->h->data;
- }
- assert(is_row(tuple));
-
- list *attr = exp_get_values(tuple);
- if (list_empty(attr)) {
- (void)sql_error(be->mvc, 02, SQLSTATE(42000) "Cannot handle
empty composite type");
- return -1;
- }
- if (multiset) /* rowid */
+type_create_result(backend *be, sql_subtype *type, list *cols)
+{
+ if (type->multiset) /* rowid */
append(cols, sa_list(be->mvc->sa));
- for(node *n = attr->h; n; n = n->next) {
- sql_exp *e = n->data;
-
- sql_subtype *type = exp_subtype(e);
- if (type->type->composite) {
- /* todo handle arrays and nesting */
- assert(0);
- }
+ if (type->type->composite) {
+ for(node *n = type->type->d.fields->h; n; n = n->next) {
+ sql_arg *a = n->data;
+
+ if (a->type.type->composite) {
+ if(type_create_result(be, &a->type, cols) < 0)
+ return -1;
+ } else {
+ append(cols, sa_list(be->mvc->sa));
+ }
+ }
+ } else {
append(cols, sa_list(be->mvc->sa));
}
- if (multiset) /* multisetid */
+ if (type->multiset) /* multisetid */
append(cols, sa_list(be->mvc->sa));
- if (multiset == MS_ARRAY) /* multisetnr */
+ if (type->multiset == MS_ARRAY) /* multisetnr */
append(cols, sa_list(be->mvc->sa));
return 0;
}
-static int
-append_tuple(backend *be, sql_exp *tuple, stmt *left, stmt *sel, list *cols,
int rowcnt, int lcnt, bte multiset)
-{
- if (multiset && !is_row(tuple)) {
+static node *
+append_tuple(backend *be, sql_exp *tuple, sql_subtype *type, stmt *left, stmt
*sel, node *cols, int rowcnt, int lcnt, bool row)
+{
+ if (row && !is_row(tuple)) { /* multiset data */
+ node *ncols;
assert(is_values(tuple));
list *tuples = exp_get_values(tuple);
int i = 1;
+ if (list_empty(tuples)) {
+ list *vals = cols->data;
+ append(vals, stmt_atom_int(be, int_nil));
+ if (type->type->composite) {
+ node *n = cols;
+ if (type->multiset)
+ n = n->next;
+ for(node *o = type->type->d.fields->h; n && o;
n = n->next, o = o->next)
+ ;
+ if (type->multiset)
+ n = n->next;
+ if (type->multiset == MS_ARRAY)
+ n = n->next;
+ return n;
+ } else
+ return cols->next;
+ }
for(node *n = tuples->h; n; n = n->next, i++)
- if (append_tuple(be, n->data, left, sel, cols, rowcnt,
i, multiset) < 0)
- return -1;
- return 0;
+ if ((ncols=append_tuple(be, n->data, type, left, sel,
cols, rowcnt, i, 0)) == cols)
+ return cols;
+ return ncols;
}
assert(tuple->row);
list *attr = exp_get_values(tuple);
- node *n, *m = cols->h;
- if (multiset) {
+ node *n, *m = cols, *o;
+ if (type->multiset) {
if (lcnt == 1) {
list *vals = m->data;
append(vals, stmt_atom_int(be, rowcnt));
}
m = m->next;
}
- for(n = attr->h; n; n = n->next, m = m->next) {
- sql_exp *e = n->data;
+ if (type->type->composite) {
+ for(n = attr->h, o = type->type->d.fields->h; n && o; n =
n->next, o = o->next) {
+ sql_exp *e = n->data;
+ list *vals = m->data;
+ sql_arg *nested_tuple = o->data;
+ sql_subtype *type = exp_subtype(e);
+ assert(type->type == nested_tuple->type.type);
+ if (type->type->composite) {
+ node *nm = append_tuple(be, e, type, left, sel,
m, rowcnt, lcnt, type->multiset);
+ if (nm == m)
+ return m;
+ m = nm;
+ } else {
+ stmt *i = exp_bin(be, e, left, NULL, NULL,
NULL, NULL, sel, 0, 0, 0);
+ m = m->next;
+ append(vals, i);
+ }
+ }
+ } else {
+ assert(list_length(attr) == 1);
+ sql_exp *e = attr->h->data;
list *vals = m->data;
-
- sql_subtype *type = exp_subtype(e);
- if (type->type->composite) {
- /* todo handle arrays and nesting */
- assert(0);
- }
stmt *i = exp_bin(be, e, left, NULL, NULL, NULL, NULL, sel, 0,
0, 0);
+ m = m->next;
append(vals, i);
}
- if (multiset) {
+ if (type->multiset) {
list *vals = m->data;
append(vals, stmt_atom_int(be, rowcnt));
m = m->next;
}
- if (multiset == MS_ARRAY) {
+ if (type->multiset == MS_ARRAY) {
list *vals = m->data;
append(vals, stmt_atom_int(be, lcnt));
m = m->next;
}
- return 0;
+ return m;
}
static stmt *
@@ -786,16 +810,15 @@ value_list(backend *be, sql_exp *vals_ex
return sql_error(be->mvc, 02, SQLSTATE(42000) "Could not infer
the type of a value list column");
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)
+ if (type_create_result(be, type, attr) < 0)
return NULL;
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)
+ if (append_tuple(be, n->data, type, left, sel, attr->h,
rowcnt, lcnt, 1) == attr->h)
return NULL;
}
return tuple_result(be, attr);
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
@@ -1095,7 +1095,17 @@ mvc_next_value_bulk(Client cntxt, MalBlk
sql_schema *s;
sql_sequence *seq;
bat *res = getArgReference_bat(stk, pci, 0);
- BUN card = (BUN)*getArgReference_lng(stk, pci, 1);
+ BUN card = 0;
+ if (getArgType(mb, pci,1) == TYPE_lng)
+ card = (BUN)*getArgReference_lng(stk, pci, 1);
+ else {
+ bat bid = *getArgReference_bat(stk, pci, 1);
+ BAT *b = BATdescriptor(bid);
+ if (!b)
+ return createException(SQL, "sql.next_value",
SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+ card = BATcount(b);
+ BBPreclaim(b);
+ }
const char *sname = *getArgReference_str(stk, pci, 2);
const char *seqname = *getArgReference_str(stk, pci, 3);
BAT *r = NULL;
@@ -5887,7 +5897,10 @@ static mel_func sql_init_funcs[] = {
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("sql", "next_value_ms", mvc_next_value, false, "return the next value
of the sequence", args(1,4, arg("",lng),argany("card",1),
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("batsql", "next_value_ms", mvc_next_value_bulk, false, "return the
next value of the sequence", args(1,4, batarg("",lng),batargany("card",1),
arg("sname",str),arg("sequence",str))),
+ //pattern("batsql", "next_value_ms", mvc_next_value_bulk, false, "return the
next value of the sequence", args(1,5, batarg("",lng),batargany("card",1),
arg("sname",str),arg("sequence",str), batarg("cand",oid))),
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))),
pattern("batsql", "get_value", mvc_get_value_bulk, false, "return the current
value of the sequence (ie the next to be used value)", args(1,3,
batarg("",lng),batarg("sname",str),batarg("sequence",str))),
pattern("batsql", "get_value", mvc_get_value_bulk, false, "return the current
value of the sequence (ie the next to be used value)", args(1,5,
batarg("",lng),batarg("sname",str),batarg("sequence",str),batarg("s1",oid),batarg("s2",oid))),
diff --git a/sql/backends/monet5/sql_rank.c b/sql/backends/monet5/sql_rank.c
--- a/sql/backends/monet5/sql_rank.c
+++ b/sql/backends/monet5/sql_rank.c
@@ -1284,7 +1284,13 @@ SQLbasecount(Client cntxt, MalBlkPtr mb,
TABLE_TYPE_DESCRIPTION(t->type, t->properties),
t->base.name);
if (!ol_first_node(t->columns))
throw(SQL, "sql.count", SQLSTATE(42S22) "Column missing
%s.%s",sname,tname);
- c = ol_first_node(t->columns)->data;
+ for(node *n = ol_first_node(t->columns); n; n = n->next) {
+ c = n->data;
+ if (c->type.multiset || !c->type.type->composite)
+ break;
+ }
+ if (!c)
+ throw(SQL, "sql.count", SQLSTATE(42S02) "Table missing
%s.%s",sname,tname);
sqlstore *store = m->session->tr->store;
*res = store->storage_api.count_col(m->session->tr, c, 10);
diff --git a/sql/backends/monet5/sql_statement.c
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -3295,6 +3295,9 @@ dump_header(mvc *sql, MalBlkPtr mb, list
for (n = l->h; n; n = n->next) {
stmt *c = n->data;
sql_subtype *t = tail_type(c);
+ if (t->multiset) { /* properly handle subtable */
+ printf("multiset\n");
+ }
sql_alias *tname = table_name(sql->sa, c);
const char *_empty = "";
const char *tn = (tname) ? tname->name : _empty;
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
@@ -1677,6 +1677,7 @@ sqltypeinit( allocator *sa)
sql_create_func(sa, "next_value_for", "sql", "next_value", TRUE, FALSE,
SCALE_NONE, 0, LNG, 2, STR, STR);
sql_create_func(sa, "get_value_for", "sql", "get_value", TRUE, FALSE,
SCALE_NONE, 0, LNG, 2, STR, STR);
sql_create_func(sa, "restart", "sql", "restart", TRUE, FALSE,
SCALE_NONE, 0, LNG, 3, STR, STR, LNG);
+ sql_create_func(sa, "next_value_for", "sql", "next_value_ms", FALSE,
FALSE, SCALE_NONE, 0, LNG, 3, ANY, STR, STR);
sql_create_func(sa, "locate", "str", "locate", FALSE, FALSE,
SCALE_NONE, 0, INT, 2, STR, STR);
sql_create_func(sa, "locate", "str", "locate3", FALSE, FALSE,
SCALE_NONE, 0, INT, 3, STR, STR, INT);
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -3739,9 +3739,12 @@ exp_check_multiset_type(mvc *sql, sql_su
sql_exp *r = v->data;
if (!is_row(r))
- v->data = exp_check_multiset_type(sql, &ct, rel, r,
tpe);
+ r = exp_check_multiset_type(sql, &ct, rel, r, tpe);
else
- v->data = exp_check_composite_type(sql, &ct, rel, r,
tpe);
+ r = exp_check_composite_type(sql, &ct, rel, r, tpe);
+ if (!r)
+ return r;
+ v->data = r;
}
exp->tpe = *t;
return exp;
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
@@ -79,6 +79,86 @@ fm_table(visitor *v, sql_rel *rel)
}
#endif
+static node *
+fm_insert_ms(visitor *v, node *m, sql_subtype *t, sql_table *pt, char *name,
list *btexps, list *niexps, sql_rel **cur, sql_rel *ins)
+{
+ assert (t->multiset);
+
+ sql_subfunc *next_val = sql_find_func(v->sql, "sys", "next_value_for",
3, F_FUNC, false, NULL);
+ list *args = sa_list(v->sql->sa);
+ sql_exp *rowid = m->data;
+
+ /* give old rowid unique label !*/
+ sql_alias a = rowid->alias;
+ exp_setalias(rowid, ++v->sql->label, rowid->alias.parent, "oldid");
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]