Changeset: 01eb51c80ae0 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/01eb51c80ae0
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/server/rel_dump.c
        sql/server/rel_updates.c
        sql/server/sql_parser.y
Branch: returning
Log Message:

implement first version of returning clause on delete statement


diffs (135 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
@@ -6644,7 +6644,7 @@ static stmt *
 rel2bin_delete(backend *be, sql_rel *rel, list *refs)
 {
        mvc *sql = be->mvc;
-       stmt *stdelete = NULL, *tids = NULL;
+       stmt *stdelete = NULL, *tids = NULL, *s = NULL;
        sql_rel *tr = rel->l;
        sql_table *t = NULL;
 
@@ -6655,12 +6655,20 @@ rel2bin_delete(backend *be, sql_rel *rel
 
        if (rel->r) { /* first construct the deletes relation */
                stmt *rows = subrel_bin(be, rel->r, refs);
+               (void) rel_dup(((sql_rel*) rel->r)->l); // rel_dup in case 
returning
                rows = subrel_project(be, rows, refs, rel->r);
                if (!rows)
                        return NULL;
                assert(rows->type == st_list);
                tids = rows->op4.lval->h->data; /* TODO this should be the 
candidate list instead */
        }
+
+       if (rel->attr) {
+               sql_rel* ret = rel_project(sql->sa, ((sql_rel*) rel->r)->l, 
rel->attr);
+               s = subrel_bin(be, ret, refs);
+               s = subrel_project(be, s, refs, rel);
+               sql->type = Q_TABLE;
+       }
        stdelete = sql_delete(be, t, tids);
        if (sql->cascade_action)
                sql->cascade_action = NULL;
@@ -6669,7 +6677,7 @@ rel2bin_delete(backend *be, sql_rel *rel
 
        if (rel->r && !rel_predicates(be, rel->r))
                return NULL;
-       return stdelete;
+       return s?s:stdelete;
 }
 
 struct tablelist {
@@ -7517,7 +7525,7 @@ subrel_bin(backend *be, sql_rel *rel, li
                break;
        case op_delete:
                s = rel2bin_delete(be, rel, refs);
-               if (sql->type == Q_TABLE)
+               if (!rel->attr && sql->type == Q_TABLE)
                        sql->type = Q_UPDATE;
                break;
        case op_truncate:
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
@@ -691,6 +691,8 @@ rel_print_rel(mvc *sql, stream  *fout, s
                mnstr_printf(fout, ")");
                if (rel->op != op_truncate && rel->op != op_merge && rel->exps)
                        exps_print(sql, fout, rel->exps, depth, refs, 1, 0, 
decorate, 0);
+               if (is_modify(rel->op) && rel->attr) /* returning lists */
+                       exps_print(sql, fout, rel->attr, depth, refs, 1, 0, 
decorate, 0);
        }       break;
        default:
                assert(0);
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
@@ -1281,7 +1281,7 @@ rel_truncate(allocator *sa, sql_rel *t, 
 }
 
 static sql_rel *
-delete_table(sql_query *query, dlist *qname, str alias, symbol *opt_where)
+delete_table(sql_query *query, dlist *qname, str alias, symbol *opt_where, 
dlist *opt_returning)
 {
        mvc *sql = query->sql;
        char *sname = qname_schema(qname);
@@ -1312,6 +1312,16 @@ delete_table(sql_query *query, dlist *qn
                } else {        /* delete all */
                        r = rel_delete(sql->sa, r, NULL);
                }
+               if (opt_returning) {
+                       sql->type = Q_TABLE;
+                       list *pexps = sa_list(sql->sa);
+                       for (dnode *n = opt_returning->h; n; n = n->next) {
+                               sql_rel* inner = r->l;
+                               sql_exp *ce = rel_column_exp(query, &inner, 
n->data.sym, sql_sel);
+                               pexps = append(pexps, ce);
+                       }
+                       r->attr = pexps;
+               }
                return r;
        }
        return NULL;
@@ -2197,8 +2207,8 @@ rel_updates(sql_query *query, symbol *s)
        {
                dlist *l = s->data.lval;
 
-               ret = delete_table(query, l->h->data.lval, 
l->h->next->data.sval, l->h->next->next->data.sym);
-               sql->type = Q_UPDATE;
+               ret = delete_table(query, l->h->data.lval, 
l->h->next->data.sval, l->h->next->next->data.sym, 
l->h->next->next->next->data.lval);
+               if (!ret->attr) sql->type = Q_UPDATE;
        }
                break;
        case SQL_TRUNCATE:
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
@@ -515,6 +515,7 @@ int yydebug=1;
        opt_schema_element_list
        opt_seps
        opt_decimal_seps
+       opt_returning_clause
        opt_seq_params
        opt_typelist
        opt_with_encrypted_password
@@ -3191,13 +3192,19 @@ opt_endianness:
        | NATIVE ENDIAN { $$ = endian_native; }
        ;
 
+opt_returning_clause:
+    /* empty */                                { $$ = NULL; }
+       | RETURNING selection   { $$ = $2; }
+       ;
+
 delete_stmt:
-    sqlDELETE FROM qname opt_alias_name opt_where_clause
+    sqlDELETE FROM qname opt_alias_name opt_where_clause opt_returning_clause
 
        { dlist *l = L();
          append_list(l, $3);
          append_string(l, $4);
          append_symbol(l, $5);
+         append_list(l, $6);
          $$ = _symbol_create_list( SQL_DELETE, l ); }
  ;
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to