Changeset: f6472272242a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f6472272242a
Modified Files:
        sql/server/rel_propagate.c
        sql/server/sql_mvc.c
        sql/server/sql_partition.c
        sql/storage/store.c
        sql/test/merge-partitions/Tests/mergepart20.sql
Branch: merge-partitions
Log Message:

After the storage load, start another transaction to load the partitions 
properly (can evaluate expressions only then). Also extended the insertion 
relations to handle expressions.


diffs (truncated from 422 to 300 lines):

diff --git a/sql/server/rel_propagate.c b/sql/server/rel_propagate.c
--- a/sql/server/rel_propagate.c
+++ b/sql/server/rel_propagate.c
@@ -46,18 +46,48 @@ rel_generate_anti_expression(mvc *sql, s
        return res;
 }
 
+static sql_rel*
+rel_create_common_relation(mvc *sql, sql_rel *rel, sql_table *t)
+{
+       if(isPartitionedByColumnTable(t)) {
+               return rel_dup(rel->r);
+       } else if(isPartitionedByExpressionTable(t)) {
+               sql_rel *inserts;
+               list *l = new_exp_list(sql->sa);
+
+               rel->r = rel_project(sql->sa, rel->r, l);
+               set_processed((sql_rel*)rel->r);
+               inserts = ((sql_rel*)(rel->r))->l;
+               for (node *n = t->columns.set->h, *m = inserts->exps->h; n && 
m; n = n->next, m = m->next) {
+                       sql_column *col = n->data;
+                       sql_exp *before = m->data;
+                       sql_exp *help = exp_column(sql->sa, t->base.name, 
col->base.name, exp_subtype(before), before->card,
+                                                                          
has_nil(before), is_intern(before));
+                       help->l = sa_strdup(sql->sa, exp_relname(before));
+                       help->r = sa_strdup(sql->sa, exp_name(before));
+                       list_append(l, help);
+               }
+               return rel_dup(rel->r);
+       } else {
+               assert(0);
+       }
+       return NULL;
+}
+
 static sql_exp*
-rel_generate_anti_insert_expression(mvc *sql, sql_rel *anti_rel, sql_table *t)
+rel_generate_anti_insert_expression(mvc *sql, sql_rel **anti_rel, sql_table *t)
 {
        sql_exp* res = NULL;
 
        if(isPartitionedByColumnTable(t)) {
                int colr = t->part.pcol->colnr;
-               res = list_fetch(anti_rel->exps, colr);
+               res = list_fetch((*anti_rel)->exps, colr);
        } else if(isPartitionedByExpressionTable(t)) {
-               if(!(res = rel_parse_val(sql, sa_message(sql->sa, "select %s;", 
t->part.pexp->exp), sql->emode, anti_rel)))
+               *anti_rel = rel_project(sql->sa, *anti_rel, 
rel_projections(sql, *anti_rel, NULL, 1, 1));
+               if(!(res = rel_parse_val(sql, sa_message(sql->sa, "select %s;", 
t->part.pexp->exp), sql->emode, (*anti_rel)->l)))
                        return NULL;
                exp_label(sql->sa, res, ++sql->label);
+               append((*anti_rel)->exps, res);
        } else {
                assert(0);
        }
@@ -445,14 +475,30 @@ rel_generate_subinserts(mvc *sql, sql_re
        sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count", 
NULL);
        char buf[BUFSIZ];
 
-       *anti_rel = rel_dup(rel->r);
-       anti_le = rel_generate_anti_insert_expression(sql, *anti_rel, t);
+       if(isPartitionedByColumnTable(t)) {
+               *anti_rel = rel_dup(rel->r);
+       } else if(isPartitionedByExpressionTable(t)) {
+               *anti_rel = rel_create_common_relation(sql, rel, t);
+       } else {
+               assert(0);
+       }
+       anti_le = rel_generate_anti_insert_expression(sql, anti_rel, t);
 
        for (node *n = t->members.set->h; n; n = n->next) {
                sql_part *pt = (sql_part *) n->data;
                sql_table *sub = find_sql_table(t->s, pt->base.name);
-               sql_rel *s1, *dup = rel_dup(rel->r);
-               sql_exp *le = rel_generate_anti_insert_expression(sql, dup, t);
+               sql_rel *s1, *dup;
+               sql_exp *le;
+
+               if(isPartitionedByColumnTable(t)) {
+                       dup = rel_dup(rel->r);
+                       le = rel_generate_anti_insert_expression(sql, &dup, t);
+               } else if(isPartitionedByExpressionTable(t)) {
+                       dup = rel_dup(*anti_rel);
+                       le = anti_le;
+               } else {
+                       assert(0);
+               }
 
                if(isRangePartitionTable(t)) {
                        sql_exp *e1, *e2, *range;
@@ -503,6 +549,13 @@ rel_generate_subinserts(mvc *sql, sql_re
                if(list_length(sub->members.set) == 0) //if this table has no 
partitions, set it as used
                        new_table->p = prop_create(sql->sa, PROP_USED, 
new_table->p);
 
+               if(isPartitionedByExpressionTable(t)) {
+                       sql_exp *del;
+                       dup = rel_project(sql->sa, dup, rel_projections(sql, 
dup, NULL, 1, 1));
+                       del = list_fetch(dup->exps, list_length(dup->exps) - 1);
+                       list_remove_data(dup->exps, del);
+               }
+
                s1 = rel_insert(sql, new_table, dup);
                if (just_one == 0) {
                        sel = rel_list(sql->sa, sel, s1);
@@ -617,19 +670,17 @@ rel_subtable_insert(mvc *sql, sql_rel *r
 {
        sql_table *upper = t->p; //is part of a partition table and not been 
used yet
        sql_part *pt = find_sql_part(upper, t->base.name);
-       sql_rel *anti_dup = rel_dup(rel->r) /* the anti relation */, *left = 
rel->l;
-       sql_exp *anti_exp = NULL, *anti_le = 
rel_generate_anti_insert_expression(sql, anti_dup, upper), *aggr = NULL, 
*exception = NULL;
+       sql_rel *anti_dup = rel_create_common_relation(sql, rel, upper), *left 
= rel->l;
+       sql_exp *anti_exp = NULL, *anti_le = 
rel_generate_anti_insert_expression(sql, &anti_dup, upper), *aggr = NULL,
+                       *exception = NULL;
        list *anti_exps = new_exp_list(sql->sa);
        sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count", 
NULL);
        char buf[BUFSIZ];
 
-       anti_le = exp_column(sql->sa, exp_relname(anti_le), exp_name(anti_le), 
exp_subtype(anti_le),
-                                                anti_le->card, 
has_nil(anti_le), is_intern(anti_le));
-
        if(isRangePartitionTable(upper)) {
                sql_exp *e1 = create_table_part_atom_exp(sql, pt->tpe, 
pt->part.range.minvalue),
                                *e2 = create_table_part_atom_exp(sql, pt->tpe, 
pt->part.range.maxvalue);
-               anti_exp = exp_compare2(sql->sa, anti_le, exp_copy(sql->sa, 
e1), exp_copy(sql->sa, e2), 3);
+               anti_exp = exp_compare2(sql->sa, exp_copy(sql->sa, anti_le), 
exp_copy(sql->sa, e1), exp_copy(sql->sa, e2), 3);
                set_anti(anti_exp);
        } else if(isListPartitionTable(upper)) {
                for(node *n = pt->part.values->h ; n ; n = n->next) {
@@ -637,12 +688,12 @@ rel_subtable_insert(mvc *sql, sql_rel *r
                        sql_exp *e1 = create_table_part_atom_exp(sql, 
next->tpe, next->value);
                        list_append(anti_exps, exp_copy(sql->sa, e1));
                }
-               anti_exp = exp_in(sql->sa, anti_le, anti_exps, cmp_notin);
+               anti_exp = exp_in(sql->sa, exp_copy(sql->sa, anti_le), 
anti_exps, cmp_notin);
        } else {
                assert(0);
        }
        if(!pt->with_nills) { /* handle the nulls case */
-               sql_exp *anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", 
card_value);
+               sql_exp *anti_nils = rel_unop_(sql, exp_copy(sql->sa, anti_le), 
NULL, "isnull", card_value);
                anti_nils = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
                anti_exp = exp_or(sql->sa, list_append(new_exp_list(sql->sa), 
anti_exp),
                                                  
list_append(new_exp_list(sql->sa), anti_nils), 0);
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -108,13 +108,14 @@ mvc_init(int debug, store_type store, in
        m->history = 0;
        /* disable size header */
        m->sizeheader = 0;
-       if(mvc_trans(m) < 0) {
-               mvc_destroy(m);
-               fprintf(stderr, "!mvc_init: failed to start transaction\n");
-               return -1;
-       }
 
        if (first || catalog_version) {
+               if(mvc_trans(m) < 0) {
+                       mvc_destroy(m);
+                       fprintf(stderr, "!mvc_init: failed to start 
transaction\n");
+                       return -1;
+               }
+
                s = m->session->schema = mvc_bind_schema(m, "sys");
                assert(m->session->schema != NULL);
 
@@ -266,6 +267,20 @@ mvc_init(int debug, store_type store, in
                        sql_create_comments(m, s);
                        sql_create_privileges(m, s);
                }
+
+               s = m->session->schema = mvc_bind_schema(m, "tmp");
+               assert(m->session->schema != NULL);
+
+               if (mvc_commit(m, 0, NULL) < 0) {
+                       fprintf(stderr, "!mvc_init: unable to commit system 
tables\n");
+                       return -1;
+               }
+       }
+
+       if(mvc_trans(m) < 0) {
+               mvc_destroy(m);
+               fprintf(stderr, "!mvc_init: failed to start transaction\n");
+               return -1;
        }
 
        //as the sql_parser is not yet initialized in the storage, we determine 
the sql type of the sql_parts here
@@ -286,16 +301,12 @@ mvc_init(int debug, store_type store, in
                }
        }
 
-       s = m->session->schema = mvc_bind_schema(m, "tmp");
-       assert(m->session->schema != NULL);
-
        if (mvc_commit(m, 0, NULL) < 0) {
                fprintf(stderr, "!mvc_init: unable to commit system tables\n");
                return -1;
        }
 
        mvc_destroy(m);
-
        return first;
 }
 
diff --git a/sql/server/sql_partition.c b/sql/server/sql_partition.c
--- a/sql/server/sql_partition.c
+++ b/sql/server/sql_partition.c
@@ -214,61 +214,107 @@ initialize_sql_parts(mvc* sql, sql_table
        if((res = find_partition_type(sql, &found, mt)) != NULL)
                return res;
        localtype = found.type->localtype;
-       for (node *n = mt->members.set->h; n; n = n->next) {
-               sql_part* next = (sql_part*) n->data;
-               next->tpe = found;
-               if(isListPartitionTable(mt)) {
-                       for (node *m = next->part.values->h; m; m = m->next) {
-                               sql_part_value* v = (sql_part_value*) m->data;
-                               ValRecord vvalue;
+       if(localtype != TYPE_str) {
+               list *new = sa_list(sql->sa), *old = sa_list(sql->sa);
+
+               for (node *n = mt->members.set->h; n; n = n->next) {
+                       sql_part* next = (sql_part*) n->data, *p = 
SA_ZNEW(sql->sa, sql_part);
+                       sql_table* pt = find_sql_table(mt->s, next->base.name);
+
+                       base_init(sql->sa, &p->base, pt->base.id, TR_NEW, 
pt->base.name);
+                       p->t = pt;
+                       p->tpe = found;
+                       p->with_nills = next->with_nills;
+
+                       if(isListPartitionTable(mt)) {
+                               p->part_type = PARTITION_LIST;
+                               p->part.values = sa_list(sql->sa);
+
+                               for (node *m = next->part.values->h; m; m = 
m->next) {
+                                       sql_part_value *v = (sql_part_value*) 
m->data, *nv = SA_ZNEW(sql->sa, sql_part_value);
+                                       ValRecord vvalue;
+                                       ptr ok;
+
+                                       nv->tpe = found;
+                                       memset(&vvalue, 0, sizeof(ValRecord));
+                                       ok = VALinit(&vvalue, TYPE_str, 
v->value);
+                                       if(ok)
+                                               ok = VALconvert(localtype, 
&vvalue);
+                                       if(ok) {
+                                               nv->value = sa_alloc(sql->sa, 
vvalue.len);
+                                               memcpy(nv->value, 
VALget(&vvalue), vvalue.len);
+                                               nv->length = vvalue.len;
+                                       }
+                                       list_append(p->part.values, nv);
+                                       VALclear(&vvalue);
+                                       if(!ok) {
+                                               res = createException(SQL, 
"sql.partition",
+                                                                               
          SQLSTATE(42000) "Internal error while bootstrapping partitioned 
tables");
+                                               goto finish;
+                                       }
+                               }
+                       } else if(isRangePartitionTable(mt)) {
+                               ValRecord vmin, vmax;
                                ptr ok;
 
-                               v->tpe = found;
-                               memset(&vvalue, 0, sizeof(ValRecord));
-                               ok = VALinit(&vvalue, TYPE_str, v->value);
+                               p->part_type = PARTITION_RANGE;
+                               memset(&vmin, 0, sizeof(ValRecord));
+                               memset(&vmax, 0, sizeof(ValRecord));
+                               ok = VALinit(&vmin, TYPE_str, 
next->part.range.minvalue);
                                if(ok)
-                                       ok = VALconvert(localtype, &vvalue);
+                                       ok = VALconvert(localtype, &vmin);
+                               if(ok)
+                                       ok = VALinit(&vmax, TYPE_str, 
next->part.range.maxvalue);
+                               if(ok)
+                                       ok = VALconvert(localtype, &vmax);
                                if(ok) {
-                                       v->value = sa_alloc(sql->sa, 
vvalue.len);
-                                       memcpy(v->value, VALget(&vvalue), 
vvalue.len);
-                                       v->length = vvalue.len;
+                                       p->part.range.minvalue = 
sa_alloc(sql->sa, vmin.len);
+                                       p->part.range.maxvalue = 
sa_alloc(sql->sa, vmax.len);
+                                       memcpy(p->part.range.minvalue, 
VALget(&vmin), vmin.len);
+                                       memcpy(p->part.range.maxvalue, 
VALget(&vmax), vmax.len);
+                                       p->part.range.minlength = vmin.len;
+                                       p->part.range.maxlength = vmax.len;
                                }
-                               VALclear(&vvalue);
+                               VALclear(&vmin);
+                               VALclear(&vmax);
                                if(!ok) {
                                        res = createException(SQL, 
"sql.partition",
                                                                                
  SQLSTATE(42000) "Internal error while bootstrapping partitioned tables");
                                        goto finish;
                                }
                        }
-               } else if(isRangePartitionTable(mt)) {
-                       ValRecord vmin, vmax;
-                       ptr ok;
+                       list_append(new, p);
+                       list_append(old, next);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to