Changeset: 9978af20edee for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/9978af20edee
Added Files:
        sql/server/rel_multiset.c
        sql/server/rel_multiset.h
Modified Files:
        sql/storage/store.c
Branch: nested
Log Message:

add missing files
drop internal table when we destroy the multiset


diffs (193 lines):

diff --git a/sql/server/rel_multiset.c b/sql/server/rel_multiset.c
new file mode 100644
--- /dev/null
+++ b/sql/server/rel_multiset.c
@@ -0,0 +1,148 @@
+
+#include "monetdb_config.h"
+#include "rel_multiset.h"
+#include "rel_exp.h"
+#include "rel_rel.h"
+#include "rel_basetable.h"
+#include "rel_updates.h"
+
+static sql_rel *
+fm_insert(visitor *v, sql_rel *rel)
+{
+       sql_rel *bt = rel->l;
+       if (is_basetable(bt->op)) {
+               sql_table *t = bt->l;
+
+               bool needed = false;
+               for(node *n = ol_first_node(t->columns); n && !needed; n = 
n->next) {
+                       sql_column *c = n->data;
+                       needed = c->type.multiset;
+               }
+               if (needed) {
+                       sql_rel *cur = NULL;
+                       sql_rel *ins = rel->r;
+                       assert(is_project(ins->op) || is_base(ins->op));
+                       list *exps = ins->exps;
+                       list *btexps = sa_list(v->sql->sa);
+                       /* do insert per multiset and once for base table */
+                       for(node *n = ol_first_node(t->columns), *m = exps->h; 
n && m; n = n->next) {
+                               sql_column *c = n->data;
+                               if (c->type.multiset) {
+                                       list *nexps = sa_list(v->sql->sa);
+                                       append(btexps, exp_ref(v->sql, 
m->data)); /* rowid */
+                                       m = m->next;
+                                       /* find fields and msid,nr from right 
handside */
+                                       for(node *f = 
c->type.type->d.fields->h; f; f = f->next, m = m->next)
+                                               append(nexps, exp_ref(v->sql, 
m->data));
+                                       append(nexps, exp_ref(v->sql, m->data));
+                                       m = m->next;
+                                       if (c->type.multiset == MS_ARRAY) {
+                                               append(nexps, exp_ref(v->sql, 
m->data));
+                                               m = m->next;
+                                       }
+                                       sql_table *t = mvc_bind_table(v->sql, 
c->t->s, c->storage_type);
+                                       if (!t) {
+                                               /* should not happen */
+                                               (void) sql_error(v->sql, 10, 
SQLSTATE(42000) "Could not find table: %s.%s", c->t->s->base.name, 
c->storage_type);
+                                               return NULL;
+                                       }
+                                       sql_rel *st = rel_basetable(v->sql, t, 
a_create(v->sql->sa, t->base.name));
+                                       sql_rel *i = rel_insert(v->sql, st, 
rel_project(v->sql->sa, rel_dup(rel->r), nexps));
+                                       if (cur)
+                                               cur = rel_list(v->sql->sa, cur, 
i);
+                                       else
+                                               cur = i;
+                               } else {
+                                       append(btexps, exp_ref(v->sql, 
m->data));
+                               }
+                       }
+                       rel->r = rel_project(v->sql->sa, rel->r, btexps);
+                       cur = rel_list(v->sql->sa, cur, rel);
+                       return cur;
+               }
+       }
+       return rel;
+}
+
+static sql_rel *
+fm_project(visitor *v, sql_rel *rel)
+{
+       if (!rel->l && rel->exps) { /* check for type multiset */
+               bool needed = false;
+               for(node *n = rel->exps->h; n && !needed; n = n->next) {
+                       sql_subtype *t = exp_subtype(n->data);
+                       needed = (t && t->multiset);
+               }
+               if (needed) {
+                       //sql_subtype *oidtype = sql_bind_localtype("oid");
+                       sql_subtype *inttype = sql_bind_localtype("int");
+                       list *nexps = sa_list(v->sql->sa);
+                       list *fexps = sa_list(v->sql->sa);
+                       for(node *n = rel->exps->h; n; n = n->next) {
+                               sql_exp *e = n->data;
+                               sql_subtype *t = exp_subtype(e);
+                               if (t->multiset) {
+                                       e = exp_ref(v->sql, e);
+                                       sql_alias *cn = a_create(v->sql->sa, 
e->alias.name);
+                                       sql_exp *mse = exp_column(v->sql->sa, 
cn, "rowid", inttype, 1,1, 1, 1);
+                                       exp_setalias(mse, -(++v->sql->label), 
cn, "rowid");
+                                       mse->nid = e->alias.label;
+                                       append(nexps, mse);
+                                       for(node *f = t->type->d.fields->h; f; 
f = f->next) {
+                                               sql_arg *field = f->data;
+                                               mse = exp_column(v->sql->sa, 
cn, field->name, &field->type, 1,1, 1, 1);
+                                               exp_setalias(mse, 
-(++v->sql->label), cn, field->name);
+                                               mse->nid = e->alias.label;
+                                               append(nexps, mse);
+                                       }
+                                       mse = exp_column(v->sql->sa, cn, 
"multisetid", inttype, 1,1, 1, 1);
+                                       exp_setalias(mse, -(++v->sql->label), 
cn, "multisetid");
+                                       mse->nid = e->alias.label;
+                                       append(nexps, mse);
+                                       if (t->multiset == MS_ARRAY) {
+                                               mse = exp_column(v->sql->sa, 
cn, "multisetnr", inttype, 1,1, 1, 1);
+                                               exp_setalias(mse, 
-(++v->sql->label), cn, "multsetnr");
+                                               mse->nid = e->alias.label;
+                                               append(nexps, mse);
+                                       }
+                               } else {
+                                       append(nexps, e);
+                               }
+                               append(fexps, exp_ref(v->sql, e));
+                       }
+                       sql_rel *nrel = rel_project(v->sql->sa, NULL, 
rel->exps);
+                       list *tl = append(sa_list(v->sql->sa), 
exp_subtype(fexps->h->data));//exp_types(v->sql->sa, fexps);
+                       list *rl = exp_types(v->sql->sa, nexps);
+                       sql_subfunc *msf = sql_bind_func_(v->sql, NULL, 
"multiset", tl, F_UNION, true, true, false);
+                       msf->res = rl;
+                       sql_exp *e = exp_op(v->sql->sa, fexps, msf);
+                       rel = rel_table_func(v->sql->sa, nrel, e, nexps, 
TABLE_PROD_FUNC);
+                       v->changes++;
+               }
+       }
+       return rel;
+}
+
+static sql_rel *
+flatten_multiset(visitor *v, sql_rel *rel)
+{
+       (void)v;
+       switch(rel->op) {
+       case op_project:
+               return fm_project(v, rel);
+       case op_insert:
+               return fm_insert(v, rel);
+       default:
+               //printf("todo %d\n", rel->op);
+       }
+       return rel;
+}
+
+sql_rel *
+rel_multiset(mvc *sql, sql_rel *rel)
+{
+       visitor v = { .sql = sql };
+
+       rel = rel_visitor_bottomup(&v, rel, &flatten_multiset);
+       return rel;
+}
diff --git a/sql/server/rel_multiset.h b/sql/server/rel_multiset.h
new file mode 100644
--- /dev/null
+++ b/sql/server/rel_multiset.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 2024 MonetDB Foundation;
+ * Copyright August 2008 - 2023 MonetDB B.V.;
+ * Copyright 1997 - July 2008 CWI.
+ */
+
+#ifndef _REL_MULTISET_H_
+#define _REL_MULTISET_H_
+
+#include "sql_relation.h"
+#include "sql_mvc.h"
+#include "sql_query.h"
+
+extern sql_rel *rel_multiset(mvc *sql, sql_rel *rel);
+
+#endif /*_REL_MULTISET_H_*/
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -4848,6 +4848,9 @@ sys_drop_column(sql_trans *tr, sql_colum
        if ((res = sys_drop_default_object(tr, col, drop_action)))
                return res;
 
+       if (col->type.multiset && col->storage_type && (res = 
sql_trans_drop_table(tr, col->t->s, col->storage_type, drop_action)))
+               return res;
+
        col->base.deleted = 1;
        if (!isNew(col) && !isTempTable(col->t))
                if ((res = store->storage_api.drop_col(tr, 
(sql_column*)dup_base(&col->base))))
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to