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

Reply via email to