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