Changeset: 94013ed66263 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=94013ed66263
Modified Files:
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql_cat.c
sql/rel.txt
sql/server/rel_schema.c
sql/test/merge-partitions/Tests/mergepart03.stable.err
sql/test/merge-partitions/Tests/mergepart03.stable.out
sql/test/merge-partitions/Tests/mergepart04.stable.err
sql/test/merge-partitions/Tests/mergepart05.stable.err
sql/test/merge-partitions/Tests/mergepart07.stable.err
Branch: merge-partitions
Log Message:
Do the proper validation for partitions by range.
However I found another bug :(
diffs (truncated from 432 to 300 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
@@ -4904,7 +4904,7 @@ rel2bin_exception(backend *be, sql_rel *
{
stmt *l = NULL, *r = NULL;
node *n = NULL;
- sql_exp *except = NULL;
+ list *slist = sa_list(be->mvc->sa);
if(find_prop(rel->p, PROP_DISTRIBUTE) && be->cur_append == 0) /* create
affected rows accumulator */
create_merge_partitions_accumulator(be);
@@ -4914,16 +4914,17 @@ rel2bin_exception(backend *be, sql_rel *
if (rel->r) /* first construct the sub relation */
r = subrel_bin(be, rel->r, refs);
- if(rel->exps && list_length(rel->exps) == 1) {
- n = rel->exps->h;
- except = n->data;
- return exp_bin(be, except, l, r, NULL, NULL, NULL, NULL);
+ if(rel->exps) {
+ for(n = rel->exps->h; n; n = n->next) {
+ sql_exp *e = n->data;
+ stmt *s = exp_bin(be, e, l, r, NULL, NULL, NULL, NULL);
+ append(slist, s);
+ }
} else { //if there is no exception condition, just generate a
statement list
- list *slist = sa_list(be->mvc->sa);
list_append(slist, l);
list_append(slist, r);
- return stmt_list(be, slist);
}
+ return stmt_list(be, slist);
}
static stmt *
diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -185,13 +185,12 @@ alter_table_add_range_partition(mvc *sql
sql_table *mt = NULL, *pt = NULL;
sql_part *err = NULL;
str msg = MAL_SUCCEED, err_min = NULL, err_max = NULL, escaped_min =
NULL, escaped_max = NULL;
- sql_column *col = NULL, *bcol = NULL;
- BAT *diff1 = NULL, *diff2 = NULL, *cbind = NULL;
- int tp1 = 0, errcode = 0, i = 0;
+ sql_column *col = NULL;
+ int tp1 = 0, errcode = 0;
ptr pmin = NULL, pmax = NULL;
size_t smin = 0, smax = 0, serr_min = 0, serr_max = 0;
ssize_t (*atomtostr)(str *, size_t *, const void *);
- int accesses[3] = {RDONLY, RD_INS, RD_UPD_VAL}, free_pmin = 1,
free_pmax = 1;
+ int free_pmin = 1, free_pmax = 1;
if((msg = validate_alter_table_add_table(sql,
"sql.alter_table_add_range_partition", msname, mtname, psname, ptname, &mt,
&pt))) {
return msg;
@@ -261,62 +260,6 @@ alter_table_add_range_partition(mvc *sql
goto finish;
}
- bcol = mvc_bind_column(sql, pt, col->base.name);
-
- for(i = 0 ; i < 3 ; i++) {
- if(cbind) {
- BBPunfix(cbind->batCacheid);
- cbind = NULL;
- }
- if(diff1) {
- BBPunfix(diff1->batCacheid);
- diff1 = NULL;
- }
- if(diff2) {
- BBPunfix(diff2->batCacheid);
- diff2 = NULL;
- }
- if((cbind = store_funcs.bind_col(sql->session->tr, bcol,
accesses[i])) == NULL) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001)
MAL_MALLOC_FAIL);
- goto finish;
- }
- if(!with_nills && cbind->tnil) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
- "ALTER
TABLE: there are null values in the column which is not allowed for this
partition");
- goto finish;
- }
- if(!pmin && !pmax) {
- if((diff1 = BATselect(cbind, NULL, ATOMnilptr(tp1),
NULL, 1, 1, 1)) == NULL) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001)
MAL_MALLOC_FAIL);
- goto finish;
- }
- if(BATcount(diff1) > 0) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
- "ALTER
TABLE: there are non-null values in the column which is not allowed for this
partition");
- goto finish;
- }
- } else {
- if((diff1 = BATthetaselect(cbind, NULL, pmin, "<")) ==
NULL) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001)
MAL_MALLOC_FAIL);
- goto finish;
- }
- if(BATcount(diff1) > 0) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
- "ALTER
TABLE: there are values in the column %s with values lesser than the partition
minimum", col->base.name);
- goto finish;
- }
- if((diff2 = BATthetaselect(cbind, NULL, pmax, ">")) ==
NULL) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001)
MAL_MALLOC_FAIL);
- goto finish;
- }
- if(BATcount(diff2) > 0) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
- "ALTER
TABLE: there are values in the column %s with values higher than the partition
maximum", col->base.name);
- goto finish;
- }
- }
- }
-
if(!pmin) {
pmin = (ptr) ATOMnilptr(tp1);
smin = ATOMsize(tp1);
@@ -378,12 +321,6 @@ finish:
GDKfree(pmin);
if(pmax && free_pmax)
GDKfree(pmax);
- if(cbind)
- BBPunfix(cbind->batCacheid);
- if(diff1)
- BBPunfix(diff1->batCacheid);
- if(diff2)
- BBPunfix(diff2->batCacheid);
if(msg != MAL_SUCCEED)
pt->p = NULL;
return msg;
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -23,7 +23,7 @@ TABLE (card MULTI)
*/
DDL (card 0!, top of the tree always)
-> flags /* OUTPUT, TRANSACTION-types, CREATE/DROP/ALTER* */
- -> exps For 'OUTPUT' is list of output options, for DISTRIBUTE
has a single exception expression
+ -> exps For 'OUTPUT' is list of output options, for
DDL_EXCEPTION is a list of psm_exception
For 'transactions' simple flags
for CREATE etc full sql string.
-> l used in DDL_OUTPUT as the relation to output and
DDL_EXCEPTION as a DDL_LIST
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -85,33 +85,81 @@ rel_alter_table(sql_allocator *sa, int c
}
static sql_rel *
-rel_alter_table_add_partition_range(sql_allocator *sa, char *sname, char
*tname, char *sname2, char *tname2, atom* min,
- atom*
max, int with_nills)
+rel_alter_table_add_partition_range(mvc* sql, sql_table *mt, sql_table *pt,
char *sname, char *tname, char *sname2,
+ char
*tname2, atom* min, atom* max, int with_nills)
{
- sql_rel *rel = rel_create(sa);
- list *exps = new_exp_list(sa);
- char *pmin = min ? atom2string(sa, min): NULL, *pmax = max ?
atom2string(sa, max) : NULL;
- if(!rel || !exps)
+ sql_rel *rel_psm = rel_create(sql->sa), *anti_rel;
+ list *exps = new_exp_list(sql->sa);
+ sql_exp *exception, *aggr, *anti_exp = NULL, *anti_le, *e1, *e2,
*anti_nils;
+ sql_column *col = mt->pcol;
+ sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count",
NULL);
+ int colr = mt->pcol->colnr;
+ char buf[BUFSIZ], *pmin = min ? atom2string(sql->sa, min): NULL, *pmax
= max ? atom2string(sql->sa, max) : NULL;
+
+ if(!rel_psm || !exps)
return NULL;
- append(exps, exp_atom_clob(sa, sname));
- append(exps, exp_atom_clob(sa, tname));
+ anti_rel = rel_basetable(sql, pt, tname2);
+ anti_le = list_fetch(anti_rel->exps, colr);
+ 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));
+ anti_rel->exps = new_exp_list(sql->sa);
+ append(anti_rel->exps, anti_le);
+ anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", card_value);
+
+ assert((!min && !max && with_nills) || (min && max));
+ if(min && max) {
+ e1 = create_table_part_atom_exp(sql, min->tpe,
VALget(&min->data));
+ if (subtype_cmp(&e1->tpe, &col->type) != 0)
+ e1 = exp_convert(sql->sa, e1, &e1->tpe, &col->type);
+
+ e2 = create_table_part_atom_exp(sql, max->tpe,
VALget(&max->data));
+ if (subtype_cmp(&e2->tpe, &col->type) != 0)
+ e2 = exp_convert(sql->sa, e2, &e2->tpe, &col->type);
+
+ anti_exp = exp_compare2(sql->sa, anti_le, e1, e2, 3);
+ set_anti(anti_exp);
+ if(!with_nills) {
+ 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);
+ }
+ } else {
+ anti_exp = exp_compare(sql->sa, anti_nils,
exp_atom_bool(sql->sa, 1), cmp_notequal);
+ }
+
+ anti_rel = rel_select(sql->sa, anti_rel, anti_exp);
+ anti_rel = rel_groupby(sql, anti_rel, NULL);
+ aggr = exp_aggr(sql->sa, NULL, cf, 0, 0, anti_rel->card, 0);
+ (void) rel_groupby_add_aggr(sql, anti_rel, aggr);
+ exp_label(sql->sa, aggr, ++sql->label);
+
+ //generate the exception
+ aggr = exp_column(sql->sa, exp_relname(aggr), exp_name(aggr),
exp_subtype(aggr), aggr->card, has_nil(aggr),
+ is_intern(aggr));
+ snprintf(buf, BUFSIZ, "ALTER TABLE: there are values in the column %s,
outside the partition range", col->base.name);
+ exception = exp_exception(sql->sa, aggr, buf);
+
+ //generate the psm statement
+ append(exps, exp_atom_clob(sql->sa, sname));
+ append(exps, exp_atom_clob(sql->sa, tname));
assert((sname2 && tname2) || (!sname2 && !tname2));
if (sname2) {
- append(exps, exp_atom_clob(sa, sname2));
- append(exps, exp_atom_clob(sa, tname2));
+ append(exps, exp_atom_clob(sql->sa, sname2));
+ append(exps, exp_atom_clob(sql->sa, tname2));
}
- append(exps, exp_atom_clob(sa, pmin));
- append(exps, exp_atom_clob(sa, pmax));
- append(exps, exp_atom_int(sa, with_nills));
- rel->l = NULL;
- rel->r = NULL;
- rel->op = op_ddl;
- rel->flag = DDL_ALTER_TABLE_ADD_RANGE_PARTITION;
- rel->exps = exps;
- rel->card = CARD_MULTI;
- rel->nrcols = 0;
- return rel;
+ append(exps, exp_atom_clob(sql->sa, pmin));
+ append(exps, exp_atom_clob(sql->sa, pmax));
+ append(exps, exp_atom_int(sql->sa, with_nills));
+ rel_psm->l = NULL;
+ rel_psm->r = NULL;
+ rel_psm->op = op_ddl;
+ rel_psm->flag = DDL_ALTER_TABLE_ADD_RANGE_PARTITION;
+ rel_psm->exps = exps;
+ rel_psm->card = CARD_MULTI;
+ rel_psm->nrcols = 0;
+
+ return rel_exception(sql->sa, rel_psm, anti_rel,
list_append(new_exp_list(sql->sa), exception));
}
static sql_rel *
@@ -120,7 +168,7 @@ rel_alter_table_add_partition_list(mvc *
{
sql_rel *rel_psm = rel_create(sql->sa), *anti_rel;
list *exps = new_exp_list(sql->sa), *anti_exps = new_exp_list(sql->sa),
*lvals = new_exp_list(sql->sa);
- sql_exp *exception, *aggr, *anti_exp, *anti_le;
+ sql_exp *exception, *aggr, *anti_exp, *anti_le, *anti_nils;
sql_column *col = mt->pcol;
sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count",
NULL);
int with_nills = 0, colr = mt->pcol->colnr;
@@ -135,6 +183,7 @@ rel_alter_table_add_partition_list(mvc *
anti_le->card,
has_nil(anti_le), is_intern(anti_le));
anti_rel->exps = new_exp_list(sql->sa);
append(anti_rel->exps, anti_le);
+ anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", card_value);
for (dnode *dn = values->h; dn ; dn = dn->next) { /* parse the atoms
and generate the expressions */
symbol* next = dn->data.sym;
@@ -155,14 +204,12 @@ rel_alter_table_add_partition_list(mvc *
if(list_length(anti_exps) > 0) {
anti_exp = exp_in(sql->sa, anti_le, anti_exps, cmp_notin);
if(!with_nills) {
- sql_exp *anti_nils = rel_unop_(sql, 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,
append(new_exp_list(sql->sa), anti_exp),
append(new_exp_list(sql->sa), anti_nils), 0);
}
} else {
assert(with_nills);
- sql_exp *anti_nils = rel_unop_(sql, anti_le, NULL, "isnull",
card_value);
anti_exp = exp_compare(sql->sa, anti_nils,
exp_atom_bool(sql->sa, 1), cmp_notequal);
}
@@ -175,8 +222,8 @@ rel_alter_table_add_partition_list(mvc *
//generate the exception
aggr = exp_column(sql->sa, exp_relname(aggr), exp_name(aggr),
exp_subtype(aggr), aggr->card, has_nil(aggr),
is_intern(aggr));
- snprintf(buf, BUFSIZ, "ALTER TABLE: there are values in the column %s
not according to the partition values list",
- col->base.name);
+ snprintf(buf, BUFSIZ, "ALTER TABLE: there are values in the column %s
which is outside the partition list of values",
+ col->base.name);
exception = exp_exception(sql->sa, aggr, buf);
//generate the psm statement
@@ -1574,7 +1621,7 @@ sql_alter_table(mvc *sql, dlist *qname,
} else if(max) {
amax = ((AtomNode *) max)->a;
}
- return
rel_alter_table_add_partition_range(sql->sa, sname, tname, sname, ntname, amin,
amax, nills);
+ return
rel_alter_table_add_partition_range(sql, t, pt, sname, tname, sname, ntname,
amin, amax, nills);
} else if(extra->token == SQL_PARTITION_LIST) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list