Changeset: 823487299508 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/823487299508
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/include/sql_relation.h
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_select.c
        sql/server/rel_updates.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
        sql/server/sql_symbol.c
        sql/server/sql_symbol.h
        sql/server/sql_tokens.h
        sql/storage/store.c
Branch: nested
Log Message:

more multiset handling


diffs (truncated from 1016 to 300 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
@@ -626,11 +626,13 @@ handle_in_exps(backend *be, sql_exp *ce,
        return s;
 }
 
-static stmt * value_list(backend *be, list *vals, stmt *left, stmt *sel);
+
+static stmt * value_list(backend *be, sql_exp *vals_exp, stmt *left, stmt 
*sel);
+
 static stmt *
 composite_value_list(backend *be, sql_exp *tuple, stmt *left, stmt *sel)
 {
-       assert(is_values(tuple));
+       assert(is_row(tuple));
        list *fields = exp_get_values(tuple);
        list *f = sa_list(be->mvc->sa);
        for (node *n = fields->h; n; n = n->next) {
@@ -638,7 +640,7 @@ composite_value_list(backend *be, sql_ex
                stmt *i;
 
                if(is_values(e))
-                       i = value_list(be, exp_get_values(e), left, sel);
+                       i = value_list(be, e, left, sel);
                else
                        i = exp_bin(be, e, left, NULL, NULL, NULL, NULL, sel, 
0, 0, 0);
                if (!i)
@@ -649,15 +651,150 @@ composite_value_list(backend *be, sql_ex
 }
 
 static stmt *
-value_list(backend *be, list *vals, stmt *left, stmt *sel)
-{
+set_value_list(backend *be, sql_exp *vals_exp, stmt *left, stmt *sel)
+{
+       assert(is_values(vals_exp));
+       list *vals = exp_get_values(vals_exp);
        sql_subtype *type = exp_subtype(vals->h->data);
-       list *l;
 
        if (!type)
                return sql_error(be->mvc, 02, SQLSTATE(42000) "Could not infer 
the type of a value list column");
-       if (type->type->composite)
-               return composite_value_list(be, vals->h->data, left, sel);
+
+       /* create bat append values */
+       list *l = sa_list(be->mvc->sa);
+       for (node *n = vals->h; n; n = n->next) {
+               sql_exp *e = n->data;
+               stmt *i = exp_bin(be, e, left, NULL, NULL, NULL, NULL, sel, 0, 
0, 0);
+
+               if (!i)
+                       return NULL;
+
+               if (list_length(vals) == 1)
+                       return i;
+               list_append(l, i);
+       }
+       /*  n-tuples */
+       //for (node *n = l->h; n; n = n->next) {
+
+       //}
+       return stmt_append_bulk(be, stmt_temp(be, type), l);
+}
+
+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;
+       }
+       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);
+               }
+               append(cols, sa_list(be->mvc->sa));
+       }
+       if (multiset)
+               append(cols, sa_list(be->mvc->sa));
+       if (multiset == MS_ARRAY)
+               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)) {
+               assert(is_values(tuple));
+               list *tuples = exp_get_values(tuple);
+               int i = 1;
+               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;
+       }
+       assert(tuple->row);
+       list *attr = exp_get_values(tuple);
+       node *n, *m;
+       for(n = attr->h, m = cols->h; n; n = n->next, m = m->next) {
+               sql_exp *e = n->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);
+               append(vals, i);
+       }
+       if (multiset) {
+               list *vals = m->data;
+               append(vals, stmt_atom_int(be, rowcnt));
+               m = m->next;
+       }
+       if (multiset == MS_ARRAY) {
+               list *vals = m->data;
+               append(vals, stmt_atom_int(be, lcnt));
+               m = m->next;
+       }
+       return 0;
+}
+
+static stmt *
+tuple_result(backend *be, list *cols)
+{
+       list *row = sa_list(be->mvc->sa);
+
+       for (node *n = cols->h; n; n = n->next) {
+               list *vals = n->data;
+               sql_subtype *type = tail_type(vals->h->data);
+               append(row, stmt_append_bulk(be, stmt_temp(be, type), vals));
+       }
+       return stmt_list(be, row);
+}
+
+static stmt *
+value_list(backend *be, sql_exp *vals_exp, stmt *left, stmt *sel)
+{
+       assert(is_values(vals_exp));
+       list *vals = exp_get_values(vals_exp);
+       sql_subtype *type = exp_subtype(vals_exp);
+       list *l;
+
+       if (!type || list_empty(vals))
+               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);
+               if (tuple_create_result(be, vals->h->data, attr, multiset) < 0)
+                       return NULL;
+               int rowcnt = 1;
+               for (node *n = vals->h; n; n = n->next, rowcnt++) {
+                       if (append_tuple(be, n->data, left, sel, attr, rowcnt, 
1, multiset) < 0)
+                               return NULL;
+               }
+               return tuple_result(be, attr);
+       }
+       if (type->multiset || (!is_row(vals_exp) && type->type->composite))
+               return set_value_list(be, vals_exp, left, sel);
+
+       if (is_row(vals_exp))
+               return composite_value_list(be, vals_exp, left, sel);
+
+       type = exp_subtype(vals->h->data);
 
        /* create bat append values */
        l = sa_list(be->mvc->sa);
@@ -1596,7 +1733,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                        assert(vname->name);
                        s = stmt_var(be, vname->sname ? a_create(sql->sa, 
sa_strdup(sql->sa, vname->sname)) : NULL, sa_strdup(sql->sa, vname->name), 
e->tpe.type?&e->tpe:NULL, 0, e->flag);
                } else if (e->f) {              /* values */
-                       s = value_list(be, e->f, left, sel);
+                       s = value_list(be, e, left, sel);
                } else {                        /* arguments */
                        sql_subtype *t = e->tpe.type?&e->tpe:NULL;
                        if (!t && 0) {
@@ -5563,6 +5700,10 @@ insert_composite(stmt **updates, sql_col
                input_tuple = input_tuple->op1;
        if (input_tuple->type != st_list)
                return NULL;
+       /* TODO we need to insert the id into the composite column itself if 
this is a multiset */
+       if (c->type.multiset) {
+               printf("todo insert next id?\n");
+       }
        for(m = input_tuple->op4.lval->h, n = n->next, f = 
c->type.type->d.fields->h; n && m && f; m = m->next, f = f->next) {
                sql_column *c = n->data;
 
@@ -5573,6 +5714,20 @@ insert_composite(stmt **updates, sql_col
                        n = n->next;
                }
        }
+       if (c->type.multiset) {
+               sql_column *c = n->data;
+
+               updates[c->colnr] = m->data;
+               n = n->next;
+               m = m->next;
+       }
+       if (c->type.multiset == MS_ARRAY) {
+               sql_column *c = n->data;
+
+               updates[c->colnr] = m->data;
+               n = n->next;
+               m = m->next;
+       }
        if (f || m) /* did we find all fields and use all values */
                return NULL;
        return n;
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -67,6 +67,7 @@ typedef struct expression {
         need_no_nil:1,
         has_no_nil:1,
         unique:1,      /* expression has unique values, but it may have 
multiple NULL values! */
+        row:1,         /* e_atom ->f is a list of values or a list of 
attributes aka a row/tuple */
 
         base:1,
         ref:1,         /* used to indicate an other expression may reference 
this one */
@@ -183,6 +184,7 @@ typedef enum operator_type {
 /* a simple atom is a literal or on the query stack */
 #define is_simple_atom(e)      (is_atom((e)->type) && !(e)->r && !(e)->f)
 #define is_values(e)           ((e)->type == e_atom && (e)->f)
+#define is_row(e)                      ((e)->type == e_atom && (e)->f && 
(e)->row)
 #define is_func(et)            (et == e_func)
 #define is_aggr(et)            (et == e_aggr)
 #define is_convert(et)                 (et == e_convert)
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -102,11 +102,14 @@ dump_sql_subtype(allocator *sa, sql_subt
        char buf[BUFSIZ];
 
        if (t->digits && t->scale)
-               snprintf(buf, BUFSIZ, "%s(%u,%u)", t->type->base.name, 
t->digits, t->scale);
+               snprintf(buf, BUFSIZ, "%s(%u,%u)%s", t->type->base.name, 
t->digits, t->scale,
+                               t->multiset==2?"[]":t->multiset == 1?"{}": "");
        else if (t->digits)
-               snprintf(buf, BUFSIZ, "%s(%u)", t->type->base.name, t->digits);
+               snprintf(buf, BUFSIZ, "%s(%u)%s", t->type->base.name, t->digits,
+                               t->multiset==2?"[]":t->multiset == 1?"{}": "");
        else
-               snprintf(buf, BUFSIZ, "%s", t->type->base.name);
+               snprintf(buf, BUFSIZ, "%s%s", t->type->base.name,
+                               t->multiset==2?"[]":t->multiset == 1?"{}": "");
        return sa_strdup(sa, buf);
 }
 
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
@@ -3682,22 +3682,17 @@ exp_check_composite_type(mvc *sql, sql_s
        node *n, *m;
        list *vals = NULL;
        assert(t->type->composite);
-       if (!exp_is_rel(exp) && !is_values(exp))
+       if (!exp_is_rel(exp) && !is_row(exp))
                return sql_error( sql, 03, SQLSTATE(42000) "cannot convert 
value into composite type '%s'", t->type->base.name);
 
        if (exp_is_rel(exp)) {
+               assert(0);
                sql_rel *valr = exp_rel_get_rel(sql->sa, exp);
                if (!valr || !is_project(valr->op) || !valr->exps)
                        return sql_error( sql, 03, SQLSTATE(42000) "cannot 
convert value into composite type '%s'", t->type->base.name);
                vals = valr->exps;
-       } else { /* values */
-               list *tuple = exp_get_values(exp);
-               if (list_length(tuple) != 1)
-                       return sql_error( sql, 03, SQLSTATE(42000) "cannot 
convert value into composite type '%s'", t->type->base.name);
-               sql_exp *e = tuple->h->data;
-               if (!is_values(e))
-                       return sql_error( sql, 03, SQLSTATE(42000) "cannot 
convert value into composite type '%s'", t->type->base.name);
-               vals = exp_get_values(e);
+       } else { /* attributes */
+               vals = exp_get_values(exp);
        }
        for(n = t->type->d.fields->h, m = vals->h; n && m; n = n->next, m = 
m->next) {
                sql_arg *f = n->data;
@@ -3709,11 +3704,39 @@ exp_check_composite_type(mvc *sql, sql_s
                        return sql_error( sql, 03, SQLSTATE(42000) "cannot 
convert values into composite type '%s', too many values given", 
t->type->base.name);
                return sql_error( sql, 03, SQLSTATE(42000) "cannot convert 
values into composite type '%s', missing values", t->type->base.name);
        }
-       if (!exp_is_rel(exp)) {
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to