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]

Reply via email to