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