Changeset: 84f723edadae for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=84f723edadae
Modified Files:
        sql/server/rel_select.c
        sql/server/rel_select.h
        sql/server/rel_updates.c
        sql/server/sql_parser.y
Branch: default
Log Message:

allow advanced update statements, ie including from part within
the update statement.


diffs (129 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
@@ -721,13 +721,12 @@ rel_values( mvc *sql, symbol *tableref)
        return r;
 }
 
-static sql_rel *
+sql_rel *
 table_ref(mvc *sql, sql_rel *rel, symbol *tableref)
 {
        char *tname = NULL;
        sql_table *t = NULL;
 
-       (void)rel;
        if (tableref->token == SQL_NAME) {
                dlist *name = tableref->data.lval->h->data.lval;
                sql_rel *temp_table = NULL;
diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h
--- a/sql/server/rel_select.h
+++ b/sql/server/rel_select.h
@@ -33,5 +33,6 @@ extern sql_exp *rel_binop_(mvc *sql, sql
 extern sql_exp *rel_nop_(mvc *sql, sql_exp *l, sql_exp *r, sql_exp *r2, 
sql_exp *r3, sql_schema *s, char *fname, int card);
 
 extern sql_rel *rel_with_query(mvc *sql, symbol *q);
+extern sql_rel *table_ref(mvc *sql, sql_rel *rel, symbol *tableref);
 
 #endif /*_REL_SELECT_H_*/
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
@@ -837,13 +837,12 @@ update_check_column(mvc *sql, sql_table 
 }
 
 static sql_rel *
-update_table(mvc *sql, dlist *qname, dlist *assignmentlist, symbol *opt_where)
+update_table(mvc *sql, dlist *qname, dlist *assignmentlist, symbol *opt_from, 
symbol *opt_where)
 {
        char *sname = qname_schema(qname);
        char *tname = qname_table(qname);
        sql_schema *s = NULL;
        sql_table *t = NULL;
-       sql_rel *bt = NULL;
 
        if (sname && !(s=mvc_bind_schema(sql,sname))) {
                (void) sql_error(sql, 02, "3F000!UPDATE: no such schema '%s'", 
sname);
@@ -866,7 +865,9 @@ update_table(mvc *sql, dlist *qname, dli
                list *exps;
                dnode *n;
                const char *rname = NULL;
+               sql_rel *res = NULL, *bt = rel_basetable(sql, t, t->base.name);
 
+               res = bt;
 #if 0
                        dlist *selection = dlist_create(sql->sa);
                        dlist *from_list = dlist_create(sql->sa);
@@ -912,6 +913,19 @@ update_table(mvc *sql, dlist *qname, dli
                }
 #endif
 
+               if (opt_from) {
+                       dlist *fl = opt_from->data.lval;
+                       dnode *n = NULL;
+                       sql_rel *fnd = NULL;
+
+                       for (n = fl->h; n && res; n = n->next) {
+                               fnd = table_ref(sql, NULL, n->data.sym);
+                               if (fnd)
+                                       res = rel_crossproduct(sql->sa, res, 
fnd, op_join);
+                       }
+                       if (!res) 
+                               return NULL;
+               }
                if (opt_where) {
                        int status = sql->session->status;
        
@@ -920,21 +934,18 @@ update_table(mvc *sql, dlist *qname, dli
                        r = rel_logical_exp(sql, NULL, opt_where, sql_where);
                        if (r) { /* simple predicate which is not using the to 
                                    be updated table. We add a select all */
-
-                               sql_rel *l = bt = rel_basetable(sql, t, 
t->base.name );
-                               r = rel_crossproduct(sql->sa, l, r, op_semi);
+                               r = rel_crossproduct(sql->sa, res, r, op_semi);
                        } else {
                                sql->errstr[0] = 0;
                                sql->session->status = status;
-                               bt = r = rel_basetable(sql, t, t->base.name );
-                               r = rel_logical_exp(sql, r, opt_where, 
sql_where);
-                               if (r && is_join(r->op))
+                               r = rel_logical_exp(sql, res, opt_where, 
sql_where);
+                               if (!opt_from && r && is_join(r->op))
                                        r->op = op_semi;
                        }
                        if (!r) 
                                return NULL;
                } else {        /* update all */
-                       bt = r = rel_basetable(sql, t, t->base.name );
+                       r = res;
                }
        
                /* first create the project */
@@ -1634,7 +1645,7 @@ rel_updates(mvc *sql, symbol *s)
        {
                dlist *l = s->data.lval;
 
-               ret = update_table(sql, l->h->data.lval, l->h->next->data.lval, 
l->h->next->next->data.sym);
+               ret = update_table(sql, l->h->data.lval, l->h->next->data.lval, 
l->h->next->next->data.sym, l->h->next->next->next->data.sym);
                sql->type = Q_UPDATE;
        }
                break;
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
@@ -2654,12 +2654,13 @@ delete_stmt:
  ;
 
 update_stmt:
-    UPDATE qname SET assignment_commalist opt_where_clause
+    UPDATE qname SET assignment_commalist opt_from_clause opt_where_clause
 
        { dlist *l = L();
          append_list(l, $2);
          append_list(l, $4);
          append_symbol(l, $5);
+         append_symbol(l, $6);
          $$ = _symbol_create_list( SQL_UPDATE, l ); }
  ;
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to