Changeset: 83fe6822b8d7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=83fe6822b8d7
Modified Files:
        sql/server/rel_select.c
        sql/server/rel_updates.c
        sql/server/sql_mvc.h
Branch: default
Log Message:

handle multivalue update statements with subqueries with cardinality problems


diffs (104 lines):

diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -163,17 +163,27 @@ rel_lastexp(mvc *sql, sql_rel *rel )
 static sql_rel *
 rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek)
 {
-       sql_exp *e = lastexp(rel);
-       if (!has_label(e)) 
-               exp_label(sql->sa, e, ++sql->label);
+       if (is_topn(rel->op))
+               rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 
1, 0));
        if (ek.card < card_set && rel->card > CARD_ATOM) {
-               sql_subtype *t = exp_subtype(e); /* parameters don't have a 
type defined, for those use 'void' one */
-               sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, 
F_AGGR);
-
-               e = exp_ref(sql->sa, e);
-               e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(e));
+               assert (is_simple_project(rel->op) || is_set(rel->op));
+               list *exps = rel->exps;
                rel = rel_groupby(sql, rel, NULL);
-               (void)rel_groupby_add_aggr(sql, rel, e);
+               for(node *n = exps->h; n; n=n->next) {
+                       sql_exp *e = n->data;
+                       if (!has_label(e))
+                               exp_label(sql->sa, e, ++sql->label);
+                       sql_subtype *t = exp_subtype(e); /* parameters don't 
have a type defined, for those use 'void' one */
+                       sql_subfunc *zero_or_one = sql_bind_func(sql->sa, 
sql->session->schema, "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, 
F_AGGR);
+
+                       e = exp_ref(sql->sa, e);
+                       e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, 
has_nil(e));
+                       (void)rel_groupby_add_aggr(sql, rel, e);
+               }
+       } else {
+               sql_exp *e = lastexp(rel);
+               if (!has_label(e))
+                       exp_label(sql->sa, e, ++sql->label);
        }
        return rel;
 }
@@ -5897,6 +5907,9 @@ rel_subquery(sql_query *query, sql_rel *
 
        rel = rel_query(query, rel, sq, toplevel, ek);
        stack_pop_frame(sql);
+
+       if (rel && ek.type == type_relation && ek.card < card_set && rel->card 
>= CARD_MULTI)
+               return rel_zero_or_one(sql, rel, ek);
        return rel;
 }
 
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -959,8 +959,7 @@ update_generate_assignments(sql_query *q
 
                a = assignment->h->data.sym;
                if (a) {
-                       int status = sql->session->status;
-                       exp_kind ek = {type_value, 
(single)?card_column:card_relation, FALSE};
+                       exp_kind ek = { (single)?type_value:type_relation, 
card_column, FALSE};
 
                        if (single && a->token == SQL_DEFAULT) {
                                char *colname = assignment->h->next->data.sval;
@@ -978,16 +977,12 @@ update_generate_assignments(sql_query *q
                                v = rel_value_exp(query, &r, a, sql_sel | 
sql_update_set, ek);
                                outer = 1;
                        } else {
+                               if (r)
+                                       query_push_outer(query, r, sql_sel);
                                rel_val = rel_subquery(query, NULL, a, ek);
-                       }
-                       if (!single && !rel_val && r) {
+                               if (r)
+                                       r = query_pop_outer(query);
                                outer = 1;
-                               sql->errstr[0] = 0;
-                               sql->session->status = status;
-                               /* TODO put in else above */
-                               query_push_outer(query, r, sql_sel);
-                               rel_val = rel_subquery(query, NULL, a, ek);
-                               r = query_pop_outer(query);
                        }
                        if ((single && !v) || (!single && !rel_val))
                                return NULL;
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -31,7 +31,7 @@
 
 /* value vs predicate (boolean) */
 #define type_value     0
-#define type_predicate 1
+#define type_relation  1
 
 /* cardinality expected by enclosing operator */
 #define card_none      -1      /* psm call doesn't return anything */
@@ -40,6 +40,7 @@
 #define card_column    2
 #define card_set       3 /* some operators require only a set (IN/EXISTS) */
 #define card_exists    4
+/* to be removed ie are in type (aka dimention) */
 #define card_relation  5
 #define card_loader    6
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to