Changeset: 48419612af46 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=48419612af46
Modified Files:
        sql/server/rel_propagate.c
        sql/server/sql_partition.c
        sql/storage/sql_catalog.c
        sql/test/merge-partitions/Tests/mergepart01.sql
        sql/test/merge-partitions/Tests/mergepart01.stable.err
        sql/test/merge-partitions/Tests/mergepart01.stable.out
        sql/test/merge-partitions/Tests/mergepart05.sql
        sql/test/merge-partitions/Tests/mergepart05.stable.out
        sql/test/merge-partitions/Tests/mergepart06.sql
        sql/test/merge-partitions/Tests/mergepart06.stable.err
        sql/test/merge-partitions/Tests/mergepart06.stable.out
        sql/test/merge-partitions/Tests/mergepart13.sql
        sql/test/merge-partitions/Tests/mergepart13.stable.err
        sql/test/merge-partitions/Tests/mergepart13.stable.out
        sql/test/merge-partitions/Tests/mergepart17.sql
        sql/test/merge-partitions/Tests/mergepart17.stable.out
        sql/test/merge-partitions/Tests/mergepart18.sql
        sql/test/merge-partitions/Tests/mergepart18.stable.out
        sql/test/merge-partitions/Tests/mergepart24.sql
        sql/test/merge-partitions/Tests/mergepart24.stable.err
        sql/test/merge-partitions/Tests/mergepart26.sql
        sql/test/merge-partitions/Tests/mergepart26.stable.err
        sql/test/merge-partitions/Tests/mergepart26.stable.out
        sql/test/merge-partitions/Tests/mergepart28.sql.in
        sql/test/merge-partitions/Tests/mergepart28.stable.err
        sql/test/merge-partitions/Tests/mergepart28.stable.out
Branch: Apr2019
Log Message:

Changed maximum limit of range partitioned merge tables. The maximum value will 
now be excluded from the range.

This implementation pairs MonetDB with other DBMS supporting partitioned merge 
tables.


diffs (truncated from 1117 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
@@ -184,7 +184,8 @@ create_range_partition_anti_rel(mvc* sql
        anti_le = rel_generate_anti_expression(sql, &anti_rel, mt, pt);
        anti_nils = rel_unop_(sql, anti_le, NULL, "isnull", card_value);
 
-       if(pmin && pmax) {
+       if (pmin && pmax) {
+               sql_exp *range1, *range2;
                e1 = exp_copy(sql->sa, pmin);
                if (subtype_cmp(exp_subtype(pmin), &tpe) != 0)
                        e1 = exp_convert(sql->sa, e1, &e1->tpe, &tpe);
@@ -193,9 +194,11 @@ create_range_partition_anti_rel(mvc* sql
                if (subtype_cmp(exp_subtype(e2), &tpe) != 0)
                        e2 = exp_convert(sql->sa, e2, &e2->tpe, &tpe);
 
-               anti_exp = exp_compare2(sql->sa, anti_le, e1, e2, 3);
-               set_anti(anti_exp);
-               if(!with_nills) {
+               range1 = exp_compare(sql->sa, exp_copy(sql->sa, anti_le), e1, 
3);
+               range2 = exp_compare(sql->sa, exp_copy(sql->sa, anti_le), e2, 
1);
+               anti_exp = exp_or(sql->sa, list_append(new_exp_list(sql->sa), 
range1),
+                                                 
list_append(new_exp_list(sql->sa), range2), 0);
+               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);
@@ -264,16 +267,25 @@ static sql_rel *
 propagate_validation_to_upper_tables(mvc* sql, sql_table *mt, sql_table *pt, 
sql_rel *rel)
 {
        sql->caching = 0;
-       for(sql_table *prev = mt, *it = prev->p ; it && prev ; prev = it, it = 
it->p) {
+       for (sql_table *prev = mt, *it = prev->p ; it && prev ; prev = it, it = 
it->p) {
                sql_part *spt = find_sql_part(it, prev->base.name);
-               if(spt) {
-                       if(isRangePartitionTable(it)) {
-                               sql_exp *e1 = create_table_part_atom_exp(sql, 
spt->tpe, spt->part.range.minvalue),
-                                               *e2 = 
create_table_part_atom_exp(sql, spt->tpe, spt->part.range.maxvalue);
+               if (spt) {
+                       if (isRangePartitionTable(it)) {
+                               int tpe = spt->tpe.type->localtype;
+                               int (*atomcmp)(const void *, const void *) = 
ATOMcompare(tpe);
+                               const void *nil = ATOMnilptr(tpe);
+                               sql_exp *e1 = NULL, *e2 = NULL;
+
+                               if (atomcmp(spt->part.range.minvalue, nil) != 0 
&& atomcmp(spt->part.range.maxvalue, nil) != 0) {
+                                       e1 = create_table_part_atom_exp(sql, 
spt->tpe, spt->part.range.minvalue);
+                                       e2 = create_table_part_atom_exp(sql, 
spt->tpe, spt->part.range.maxvalue);
+                               } else {
+                                       assert(spt->with_nills);
+                               }
                                rel = rel_list(sql->sa, rel, 
create_range_partition_anti_rel(sql, it, pt, spt->with_nills, e1, e2));
-                       } else if(isListPartitionTable(it)) {
+                       } else if (isListPartitionTable(it)) {
                                list *exps = new_exp_list(sql->sa);
-                               for(node *n = spt->part.values->h ; n ; n = 
n->next) {
+                               for (node *n = spt->part.values->h ; n ; n = 
n->next) {
                                        sql_part_value *next = 
(sql_part_value*) n->data;
                                        sql_exp *e1 = 
create_table_part_atom_exp(sql, next->tpe, next->value);
                                        list_append(exps, e1);
@@ -334,7 +346,7 @@ rel_alter_table_add_partition_range(mvc*
        rel_psm->card = CARD_MULTI;
        rel_psm->nrcols = 0;
 
-       res = create_range_partition_anti_rel(sql, mt, pt, with_nills, pmin, 
pmax);
+       res = create_range_partition_anti_rel(sql, mt, pt, with_nills, (min && 
max) ? pmin : NULL, (min && max) ? pmax : NULL);
        res->l = rel_psm;
 
        return propagate_validation_to_upper_tables(sql, mt, pt, res);
@@ -633,40 +645,53 @@ rel_generate_subinserts(mvc *sql, sql_re
                        assert(0);
                }
 
-               if(isRangePartitionTable(t)) {
-                       sql_exp *e1, *e2, *range;
-                       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);
-                       range = exp_compare2(sql->sa, le, e1, e2, 3);
+               if (isRangePartitionTable(t)) {
+                       sql_exp *range = NULL;
+                       int tpe = pt->tpe.type->localtype;
+                       int (*atomcmp)(const void *, const void *) = 
ATOMcompare(tpe);
+                       const void *nil = ATOMnilptr(tpe);
 
-                       if(accum) {
-                               accum = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), exp_copy(sql->sa, range)),
-                                                          
list_append(new_exp_list(sql->sa), accum), 1);
+                       if (atomcmp(pt->part.range.minvalue, nil) != 0 && 
atomcmp(pt->part.range.maxvalue, nil) != 0) {
+                               sql_exp *e1, *e2;
+                               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);
+                               range = exp_compare2(sql->sa, le, e1, e2, 1);
+                       } else {
+                               assert(pt->with_nills);
+                       }
+                       if (pt->with_nills) { /* handle the nulls case */
+                               sql_exp *nils = rel_unop_(sql, le, NULL, 
"isnull", card_value);
+                               nils = exp_compare(sql->sa, nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
+                               if (range) {
+                                       range = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), range),
+                                                                  
list_append(new_exp_list(sql->sa), nils), 0);
+                               } else {
+                                       range = nils;
+                               }
+                               found_nils = 1;
+                       }
+
+                       if (accum) {
+                               accum = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), accum),
+                                                          
list_append(new_exp_list(sql->sa), exp_copy(sql->sa, range)), 0);
                        } else {
                                accum = exp_copy(sql->sa, range);
                        }
 
-                       if(pt->with_nills) { /* handle the nulls case */
-                               sql_exp *nils = rel_unop_(sql, le, NULL, 
"isnull", card_value);
-                               nils = exp_compare(sql->sa, nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
-                               range = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), range),
-                                                          
list_append(new_exp_list(sql->sa), nils), 0);
-                               found_nils = 1;
-                       }
                        dup = rel_select(sql->sa, dup, range);
-               } else if(isListPartitionTable(t)) {
+               } else if (isListPartitionTable(t)) {
                        sql_exp *ein;
                        list *exps = new_exp_list(sql->sa);
 
-                       for(node *n = pt->part.values->h ; n ; n = n->next) {
-                               sql_part_value *next = (sql_part_value*) 
n->data;
+                       for (node *nn = pt->part.values->h ; nn ; nn = 
nn->next) {
+                               sql_part_value *next = (sql_part_value*) 
nn->data;
                                sql_exp *e1 = create_table_part_atom_exp(sql, 
next->tpe, next->value);
                                list_append(exps, e1);
                                list_append(anti_exps, exp_copy(sql->sa, e1));
                        }
 
                        ein = exp_in(sql->sa, le, exps, cmp_in);
-                       if(pt->with_nills) { /* handle the nulls case */
+                       if (pt->with_nills) { /* handle the nulls case */
                                sql_exp *nils = rel_unop_(sql, le, NULL, 
"isnull", card_value);
                                nils = exp_compare(sql->sa, nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
                                ein = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), ein),
@@ -700,8 +725,7 @@ rel_generate_subinserts(mvc *sql, sql_re
 
        //generate the exception
        if(isRangePartitionTable(t)) {
-               if (list_length(t->members.set) == 1) //when there is just one 
partition must set the anti_exp
-                       set_anti(accum);
+               set_anti(accum);
                anti_exp = accum;
        } else if(isListPartitionTable(t)) {
                anti_exp = exp_in(sql->sa, anti_le, anti_exps, cmp_notin);
@@ -814,32 +838,52 @@ rel_subtable_insert(mvc *sql, sql_rel *r
        sql_part *pt = find_sql_part(upper, t->base.name);
        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;
+                       *exception = NULL, *anti_nils = 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];
 
-       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, 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) {
+       if (isRangePartitionTable(upper)) {
+               int tpe = pt->tpe.type->localtype;
+               int (*atomcmp)(const void *, const void *) = ATOMcompare(tpe);
+               const void *nil = ATOMnilptr(tpe);
+
+               if (atomcmp(pt->part.range.minvalue, nil) != 0 && 
atomcmp(pt->part.range.maxvalue, nil) != 0) {
+                       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),
+                                       *range1 = exp_compare(sql->sa, 
exp_copy(sql->sa, anti_le), e1, 3),
+                                       *range2 = exp_compare(sql->sa, 
exp_copy(sql->sa, anti_le), e2, 1);
+                       anti_exp = exp_or(sql->sa, 
list_append(new_exp_list(sql->sa), range1),
+                                                         
list_append(new_exp_list(sql->sa), range2), 0);
+
+                       if (!pt->with_nills) { /* handle the nulls case */
+                               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);
+                       }
+               } else {
+                       assert(pt->with_nills);
+                       anti_nils = rel_unop_(sql, exp_copy(sql->sa, anti_le), 
NULL, "isnull", card_value);
+                       anti_exp = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_notequal);
+               }
+       } else if (isListPartitionTable(upper)) {
+               for (node *n = pt->part.values->h ; n ; n = n->next) {
                        sql_part_value *next = (sql_part_value*) n->data;
                        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, exp_copy(sql->sa, anti_le), 
anti_exps, cmp_notin);
+
+               if (!pt->with_nills) { /* handle the nulls case */
+                       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);
+               }
        } else {
                assert(0);
        }
-       if(!pt->with_nills) { /* handle the nulls case */
-               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);
-       }
 
        //generate a count aggregation for the values not present in any of the 
partitions
        anti_dup = rel_select(sql->sa, anti_dup, anti_exp);
@@ -852,7 +896,7 @@ rel_subtable_insert(mvc *sql, sql_rel *r
        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, "INSERT: table %s.%s is part of merge table %s.%s 
and the insert violates the "
-                                                 "partition %s of values", 
t->s->base.name,  t->base.name, upper->s->base.name,
+                                                 "partition %s of values", 
t->s->base.name, t->base.name, upper->s->base.name,
                         upper->base.name, isRangePartitionTable(upper) ? 
"range" : "list");
        exception = exp_exception(sql->sa, aggr, buf);
 
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
@@ -352,7 +352,7 @@ initialize_sql_parts(mvc* sql, sql_table
                                ptr ok;
 
                                vmin = vmax = (ValRecord) {.vtype = TYPE_void,};
-                               ok = VALinit(&vmin, TYPE_str, 
next->part.range.minvalue);
+                               ok = VALinit(&vmin, TYPE_str, 
next->part.range.minvalue); //Fixme
                                if(ok)
                                        ok = VALconvert(localtype, &vmin);
                                if(ok)
diff --git a/sql/storage/sql_catalog.c b/sql/storage/sql_catalog.c
--- a/sql/storage/sql_catalog.c
+++ b/sql/storage/sql_catalog.c
@@ -366,16 +366,16 @@ sql_range_part_validate_and_insert(void 
        sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
        int res1, res2;
 
-       if(pt == newp) /* same pointer, skip (used in updates) */
+       if (pt == newp) /* same pointer, skip (used in updates) */
                return NULL;
 
        assert(pt->tpe.type->localtype == newp->tpe.type->localtype);
-       if(newp->with_nills && pt->with_nills) //only one partition at most has 
null values
+       if (newp->with_nills && pt->with_nills) //only one partition at most 
has null values
                return pt;
 
        res1 = ATOMcmp(pt->tpe.type->localtype, pt->part.range.minvalue, 
newp->part.range.maxvalue);
        res2 = ATOMcmp(pt->tpe.type->localtype, newp->part.range.minvalue, 
pt->part.range.maxvalue);
-       if (res1 <= 0 && res2 <= 0) //overlap: x1 <= y2 && y1 <= x2
+       if (res1 < 0 && res2 < 0) //overlap: x1 < y2 && y1 < x2
                return pt;
        return NULL;
 }
@@ -388,17 +388,17 @@ sql_values_part_validate_and_insert(void
        node *n1 = b1->h, *n2 = b2->h;
        int res;
 
-       if(pt == newp) /* same pointer, skip (used in updates) */
+       if (pt == newp) /* same pointer, skip (used in updates) */
                return NULL;
 
        assert(pt->tpe.type->localtype == newp->tpe.type->localtype);
-       if(newp->with_nills && pt->with_nills)
+       if (newp->with_nills && pt->with_nills)
                return pt; //check for nulls first
 
-       while(n1 && n2) {
+       while (n1 && n2) {
                sql_part_value *p1 = (sql_part_value *) n1->data, *p2 = 
(sql_part_value *) n2->data;
                res = ATOMcmp(pt->tpe.type->localtype, p1->value, p2->value);
-               if(!res) { //overlap -> same value in both partitions
+               if (!res) { //overlap -> same value in both partitions
                        return pt;
                } else if(res < 0) {
                        n1 = n1->next;
diff --git a/sql/test/merge-partitions/Tests/mergepart01.sql 
b/sql/test/merge-partitions/Tests/mergepart01.sql
--- a/sql/test/merge-partitions/Tests/mergepart01.sql
+++ b/sql/test/merge-partitions/Tests/mergepart01.sql
@@ -20,7 +20,8 @@ ALTER TABLE testme ADD TABLE wrongtable 
 CREATE TABLE subtable2 (a int, b varchar(32));
 ALTER TABLE testme ADD TABLE subtable2 AS PARTITION IN ('0', '1', '2'); --error
 ALTER TABLE testme ADD TABLE subtable2 AS PARTITION BETWEEN 7 AND 9; --error
-ALTER TABLE testme ADD TABLE subtable2 AS PARTITION BETWEEN 5 AND 5; --error
+ALTER TABLE testme ADD TABLE subtable2 AS PARTITION BETWEEN 5 AND 5;
+ALTER TABLE testme DROP TABLE subtable2;
 
 DROP TABLE subtable1; --error
 ALTER TABLE testme SET SCHEMA other_schema; --error, changing schema not 
allowed while with child tables
diff --git a/sql/test/merge-partitions/Tests/mergepart01.stable.err 
b/sql/test/merge-partitions/Tests/mergepart01.stable.err
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to