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