Changeset: dfb15931417c for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=dfb15931417c
Modified Files:
sql/backends/monet5/rel_bin.c
sql/server/rel_optimizer.c
sql/server/rel_psm.c
sql/server/sql_parser.y
Branch: default
Log Message:
allow for set (a, .., z) = (select av, .. az from .. );
diffs (195 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
@@ -3058,8 +3058,6 @@ insert_check_fkey(backend *be, list *ins
sql_subtype *bt = sql_bind_localtype("bit");
sql_subfunc *ne = sql_bind_func_result(sql->sa, sql->session->schema,
"<>", lng, lng, bt);
- (void) sql; /* unused! */
-
if (pin && list_length(pin->op4.lval))
s = pin->op4.lval->h->data;
if (s->key && s->nrcols == 0) {
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -7924,8 +7924,6 @@ exp_apply_rename(mvc *sql, sql_exp *e, l
ne = exp_op(sql->sa, nl, e->f);
else
ne = exp_aggr(sql->sa, nl, e->f, need_distinct(e),
need_no_nil(e), e->card, has_nil(e));
- if (e && e->rname)
- exp_setname(sql->sa, ne, e->rname, e->name);
break;
}
case e_atom:
@@ -7934,6 +7932,8 @@ exp_apply_rename(mvc *sql, sql_exp *e, l
}
if (ne && e->p)
ne->p = prop_copy(sql->sa, e->p);
+ if (ne && !ne->used && e->rname)
+ exp_setname(sql->sa, ne, e->rname, e->name);
return ne;
}
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -44,52 +44,106 @@ rel_psm_stmt(sql_allocator *sa, sql_exp
return NULL;
}
-/* SET variable = value */
+/* SET variable = value and set (variable1, .., variableN) = (query) */
static sql_exp *
psm_set_exp(mvc *sql, dnode *n)
{
- exp_kind ek = {type_value, card_value, FALSE};
- const char *name = n->data.sval;
symbol *val = n->next->data.sym;
sql_exp *e = NULL;
int level = 0, is_last = 0;
sql_subtype *tpe = NULL;
sql_rel *rel = NULL;
sql_exp *res = NULL;
+ int single = (n->type == type_string);
- /* name can be
- 'parameter of the function' (ie in the param list)
- or a local or global variable, declared earlier
- */
- /* check if variable is known from the stack */
- if (!stack_find_var(sql, name)) {
- sql_arg *a = sql_bind_param(sql, name);
+ if (single) {
+ exp_kind ek = {type_value, card_value, FALSE};
+ const char *name = n->data.sval;
+ /* name can be
+ 'parameter of the function' (ie in the param list)
+ or a local or global variable, declared earlier
+ */
- if (!a) /* not parameter, ie local var ? */
- return sql_error(sql, 01, "Variable %s unknown", name);
- tpe = &a->type;
- } else {
- tpe = stack_find_type(sql, name);
- }
+ /* check if variable is known from the stack */
+ if (!stack_find_var(sql, name)) {
+ sql_arg *a = sql_bind_param(sql, name);
- e = rel_value_exp2(sql, &rel, val, sql_sel, ek, &is_last);
- if (!e || (rel && e->card > CARD_AGGR))
- return NULL;
+ if (!a) /* not parameter, ie local var ? */
+ return sql_error(sql, 01, "Variable %s
unknown", name);
+ tpe = &a->type;
+ } else {
+ tpe = stack_find_type(sql, name);
+ }
- level = stack_find_frame(sql, name);
- e = rel_check_type(sql, tpe, e, type_cast);
- if (!e)
- return NULL;
- if (rel) {
- sql_exp *er = exp_rel(sql, rel);
- list *b = sa_list(sql->sa);
+ e = rel_value_exp2(sql, &rel, val, sql_sel, ek, &is_last);
+ if (!e || (rel && e->card > CARD_AGGR))
+ return NULL;
- append(b, er);
- append(b, exp_set(sql->sa, name, e, level));
+ level = stack_find_frame(sql, name);
+ e = rel_check_type(sql, tpe, e, type_cast);
+ if (!e)
+ return NULL;
+ if (rel) {
+ sql_exp *er = exp_rel(sql, rel);
+ list *b = sa_list(sql->sa);
+
+ append(b, er);
+ append(b, exp_set(sql->sa, name, e, level));
+ res = exp_rel(sql, rel_psm_block(sql->sa, b));
+ } else {
+ res = exp_set(sql->sa, name, e, level);
+ }
+ } else { /* multi assignment */
+ exp_kind ek = {type_value, (single)?card_column:card_relation,
FALSE};
+ sql_rel *rel_val = rel_subquery(sql, NULL, val, ek, APPLY_JOIN);
+ dlist *vars = n->data.lval;
+ dnode *m;
+ node *n;
+ list *b;
+
+ if (!rel_val || !is_project(rel_val->op) ||
+ dlist_length(vars) != list_length(rel_val->exps)) {
+ return sql_error(sql, 02, "SET: Number of variables not
equal to number of supplied values");
+ }
+
+ b = sa_list(sql->sa);
+ if (rel_val) {
+ sql_exp *er = exp_rel(sql, rel_val);
+
+ append(b, er);
+ }
+
+ for(m = vars->h, n = rel_val->exps->h; n && m; n = n->next, m =
m->next) {
+ char *vname = m->data.sval;
+ sql_exp *v = n->data;
+
+ if (!stack_find_var(sql, vname)) {
+ sql_arg *a = sql_bind_param(sql, vname);
+
+ if (!a) /* not parameter, ie local var ? */
+ return sql_error(sql, 01, "Variable %s
unknown", vname);
+ tpe = &a->type;
+ } else {
+ tpe = stack_find_type(sql, vname);
+ }
+
+ if (!exp_name(v))
+ exp_label(sql->sa, v, ++sql->label);
+ v = exp_column(sql->sa, exp_relname(v), exp_name(v),
exp_subtype(v), v->card, has_nil(v), is_intern(v));
+
+ level = stack_find_frame(sql, vname);
+ v = rel_check_type(sql, tpe, v, type_cast);
+ if (!v)
+ return NULL;
+ if (v->card > CARD_AGGR) {
+ sql_subaggr *zero_or_one =
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(v));
+ assert(zero_or_one);
+ v = exp_aggr1(sql->sa, v, zero_or_one, 0, 0,
CARD_ATOM, 0);
+ }
+ append(b, exp_set(sql->sa, vname, v, level));
+ }
res = exp_rel(sql, rel_psm_block(sql->sa, b));
- } else {
- res = exp_set(sql->sa, name, e, level);
}
return res;
}
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -767,11 +767,17 @@ variable_list:
;
set_statement:
- set ident '=' simple_atom
+ /*set ident '=' simple_atom*/
+ set ident '=' search_condition
{ dlist *l = L();
append_string(l, $2 );
append_symbol(l, $4 );
$$ = _symbol_create_list( SQL_SET, l); }
+ | set column_commalist_parens '=' subquery
+ { dlist *l = L();
+ append_list(l, $2);
+ append_symbol(l, $4);
+ $$ = _symbol_create_list( SQL_SET, l ); }
| set sqlSESSION AUTHORIZATION ident
{ dlist *l = L();
sql_subtype t;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list