Changeset: d80919e1bc62 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d80919e1bc62
Modified Files:
sql/server/rel_propagate.c
sql/storage/sql_catalog.c
sql/test/merge-partitions/Tests/All
sql/test/merge-partitions/Tests/mergepart01.stable.err
sql/test/merge-partitions/Tests/mergepart30.sql
sql/test/merge-partitions/Tests/mergepart30.stable.err
Branch: Oct2020
Log Message:
Merged with Jun2020
diffs (truncated from 488 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
@@ -160,7 +160,7 @@ generate_partition_limits(sql_query *que
}
static sql_rel*
-create_range_partition_anti_rel(sql_query* query, sql_table *mt, sql_table
*pt, bit with_nills, sql_exp *pmin, sql_exp *pmax, bool all_ranges)
+create_range_partition_anti_rel(sql_query* query, sql_table *mt, sql_table
*pt, bit with_nills, sql_exp *pmin, sql_exp *pmax, bool all_ranges, bool
max_equal_min)
{
mvc *sql = query->sql;
sql_rel *anti_rel;
@@ -184,14 +184,18 @@ create_range_partition_anti_rel(sql_quer
if (!(e1 = exp_check_type(sql, &tpe, NULL, e1,
type_equal)))
return NULL;
- e2 = exp_copy(sql, pmax);
- if (!(e2 = exp_check_type(sql, &tpe, NULL, e2,
type_equal)))
- return NULL;
+ if (max_equal_min) {
+ anti_exp = exp_compare(sql->sa, exp_copy(sql,
anti_le), e1, cmp_notequal);
+ } else {
+ e2 = exp_copy(sql, pmax);
+ if (!(e2 = exp_check_type(sql, &tpe, NULL, e2,
type_equal)))
+ return NULL;
- range1 = exp_compare(sql->sa, exp_copy(sql, anti_le),
e1, 3);
- range2 = exp_compare(sql->sa, exp_copy(sql, 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);
+ range1 = exp_compare(sql->sa, exp_copy(sql,
anti_le), e1, cmp_lt);
+ range2 = exp_compare(sql->sa, exp_copy(sql,
anti_le), e2, cmp_gte);
+ 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);
@@ -277,17 +281,19 @@ propagate_validation_to_upper_tables(sql
int (*atomcmp)(const void *, const void *) =
ATOMcompare(tpe);
const void *nil = ATOMnilptr(tpe);
sql_exp *e1 = NULL, *e2 = NULL;
- bool found_all = false;
+ bool found_all = false, max_equal_min = false;
if (atomcmp(spt->part.range.minvalue, nil) != 0
&& atomcmp(spt->part.range.maxvalue, nil) != 0) {
+ max_equal_min =
ATOMcmp(spt->tpe.type->localtype, spt->part.range.maxvalue,
spt->part.range.minvalue) == 0;
e1 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &spt->tpe, spt->part.range.minvalue));
- e2 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &spt->tpe, spt->part.range.maxvalue));
+ if (!max_equal_min)
+ e2 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &spt->tpe, spt->part.range.maxvalue));
} else {
assert(spt->with_nills);
found_all = is_bit_nil(spt->with_nills);
}
if (!found_all || !spt->with_nills)
- rel = rel_list(sql->sa, rel,
create_range_partition_anti_rel(query, it->t, pt, spt->with_nills, e1, e2,
false));
+ rel = rel_list(sql->sa, rel,
create_range_partition_anti_rel(query, it->t, pt, spt->with_nills, e1, e2,
false, max_equal_min));
} else if (isListPartitionTable(it->t)) {
list *exps = new_exp_list(sql->sa);
for (node *n = spt->part.values->h ; n ; n =
n->next) {
@@ -357,7 +363,12 @@ rel_alter_table_add_partition_range(sql_
rel_psm->nrcols = 0;
if (!is_bit_nil(with_nills)) {
- res = create_range_partition_anti_rel(query, mt, pt,
with_nills, (min && max) ? pmin : NULL, (min && max) ? pmax : NULL, all_ranges);
+ bool min_max_equal = false;
+ if (pmin && pmax && pmin->type == e_atom && pmax->type ==
e_atom && pmin->l && pmax->l) {
+ atom *e1 = pmin->l, *e2 = pmax->l;
+ min_max_equal = ATOMcmp(tpe.type->localtype,
&e1->data.val, &e2->data.val) == 0;
+ }
+ res = create_range_partition_anti_rel(query, mt, pt,
with_nills, (min && max) ? pmin : NULL, (min && max) ? pmax : NULL, all_ranges,
min_max_equal);
res->l = rel_psm;
} else {
res = rel_psm;
@@ -710,9 +721,15 @@ rel_generate_subinserts(sql_query *query
if (atomcmp(pt->part.range.minvalue, nil) != 0 ||
atomcmp(pt->part.range.maxvalue, nil) != 0) {
sql_exp *e1, *e2;
+ bool max_equal_min =
ATOMcmp(pt->tpe.type->localtype, pt->part.range.maxvalue,
pt->part.range.minvalue) == 0;
+
e1 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.minvalue));
- e2 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.maxvalue));
- range = exp_compare2(sql->sa, le, e1, e2,
cmp_gte|CMP_BETWEEN);
+ if (!max_equal_min) {
+ e2 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.maxvalue));
+ range = exp_compare2(sql->sa, le, e1,
e2, cmp_gte|CMP_BETWEEN);
+ } else {
+ range = exp_compare(sql->sa, le, e1,
cmp_equal);
+ }
full_range = range;
} else {
found_all_range_values |= (pt->with_nills != 1);
@@ -954,12 +971,19 @@ rel_subtable_insert(sql_query *query, sq
sql_exp *e1 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.minvalue));
anti_exp = exp_compare(sql->sa, exp_copy(sql,
anti_le), e1, cmp_lt);
} else {
- sql_exp *e1 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.minvalue)),
- *e2 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.maxvalue)),
- *range1 = exp_compare(sql->sa,
exp_copy(sql, anti_le), e1, cmp_lt),
- *range2 = exp_compare(sql->sa,
exp_copy(sql, anti_le), e2, cmp_gte);
- anti_exp = exp_or(sql->sa,
list_append(new_exp_list(sql->sa), range1),
-
list_append(new_exp_list(sql->sa), range2), 0);
+ sql_exp *e1 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.minvalue));
+ bool max_equal_min =
ATOMcmp(pt->tpe.type->localtype, pt->part.range.maxvalue,
pt->part.range.minvalue) == 0;
+
+ if (max_equal_min) {
+ anti_exp = exp_compare(sql->sa,
exp_copy(sql, anti_le), e1, cmp_notequal);
+ } else {
+ sql_exp *e2 = exp_atom(sql->sa,
atom_general_ptr(sql->sa, &pt->tpe, pt->part.range.maxvalue)),
+ *range1 = exp_compare(sql->sa,
exp_copy(sql, anti_le), e1, cmp_lt),
+ *range2 = exp_compare(sql->sa,
exp_copy(sql, anti_le), e2, cmp_gte);
+
+ 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 */
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
@@ -453,7 +453,7 @@ sql_range_part_validate_and_insert(void
sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
int res1, res2, tpe = pt->tpe.type->localtype;
const void *nil = ATOMnilptr(tpe);
- bool pt_down_all = false, pt_upper_all = false, newp_down_all = false,
newp_upper_all = false;
+ bool pt_down_all = false, pt_upper_all = false, newp_down_all = false,
newp_upper_all = false, pt_min_max_same = false, newp_min_max_same = false;
if (pt == newp) /* same pointer, skip (used in updates) */
return NULL;
@@ -476,31 +476,39 @@ sql_range_part_validate_and_insert(void
if ((pt_down_all && pt_upper_all && !pt->with_nills) || (newp_down_all
&& newp_upper_all && !newp->with_nills))
return pt;
+ pt_min_max_same = !ATOMcmp(tpe, pt->part.range.maxvalue,
pt->part.range.minvalue);
+ newp_min_max_same = !ATOMcmp(tpe, newp->part.range.maxvalue,
newp->part.range.minvalue);
+
if (pt_down_all) { /* from range min value until a value */
- if (newp_down_all || ATOMcmp(tpe, pt->part.range.maxvalue,
newp->part.range.minvalue) > 0)
+ res1 = ATOMcmp(tpe, pt->part.range.maxvalue,
newp->part.range.minvalue);
+ if (newp_down_all || (!newp_min_max_same && res1 > 0) ||
(newp_min_max_same && res1 >= 0))
return pt;
return NULL;
}
if (pt_upper_all) { /* from value until range max value */
- if (newp_upper_all || ATOMcmp(tpe, newp->part.range.maxvalue,
pt->part.range.minvalue) > 0)
+ res1 = ATOMcmp(tpe, newp->part.range.maxvalue,
pt->part.range.minvalue);
+ if (newp_upper_all || (!newp_min_max_same && res1 > 0) ||
(newp_min_max_same && res1 >= 0))
return pt;
return NULL;
}
if (newp_down_all) { /* from range min value until a value */
- if (pt_down_all || ATOMcmp(tpe, newp->part.range.maxvalue,
pt->part.range.minvalue) > 0)
+ res1 = ATOMcmp(tpe, newp->part.range.maxvalue,
pt->part.range.minvalue);
+ if (pt_down_all || (!newp_min_max_same && res1 > 0) ||
(newp_min_max_same && res1 >= 0))
return pt;
return NULL;
}
if (newp_upper_all) { /* from value until range max value */
- if (pt_upper_all || ATOMcmp(tpe, pt->part.range.maxvalue,
newp->part.range.minvalue) > 0)
+ res1 = ATOMcmp(tpe, pt->part.range.maxvalue,
newp->part.range.minvalue);
+ if (pt_upper_all || (!pt_min_max_same && res1 > 0) ||
(pt_min_max_same && res1 >= 0))
return pt;
return NULL;
}
/* Fallback into normal cases */
- res1 = ATOMcmp(tpe, pt->part.range.minvalue, newp->part.range.maxvalue);
- res2 = ATOMcmp(tpe, newp->part.range.minvalue, pt->part.range.maxvalue);
- if (res1 < 0 && res2 < 0) /* overlap: x1 < y2 && y1 < x2 */
+ res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
+ res2 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
+ /* overlap: y2 > x1 && x2 > y1 */
+ if (((!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >=
0)) && ((!pt_min_max_same && res2 > 0) || (pt_min_max_same && res2 >= 0)))
return pt;
return NULL;
}
diff --git a/sql/test/merge-partitions/Tests/All
b/sql/test/merge-partitions/Tests/All
--- a/sql/test/merge-partitions/Tests/All
+++ b/sql/test/merge-partitions/Tests/All
@@ -30,3 +30,4 @@ HAVE_DATA_PATH&HAVE_LIBPY3?mergepart28
HAVE_PYMONETDB?mergepart29
mergepart30
mergepart31
+mergepart32
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,8 +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 FROM 7 TO 9; --error
-ALTER TABLE testme ADD TABLE subtable2 AS PARTITION FROM 5 TO 5;
-ALTER TABLE testme DROP TABLE subtable2;
+ALTER TABLE testme ADD TABLE subtable2 AS PARTITION FROM 5 TO 5; --error
+ALTER TABLE testme DROP TABLE subtable2; --error
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
--- a/sql/test/merge-partitions/Tests/mergepart01.stable.err
+++ b/sql/test/merge-partitions/Tests/mergepart01.stable.err
@@ -45,7 +45,15 @@ MAPI = (monetdb) /var/tmp/mtest-13251/.
QUERY = ALTER TABLE testme ADD TABLE subtable2 AS PARTITION FROM 7 TO 9;
--error
ERROR = !ALTER TABLE: conflicting partitions: 7 to 9 and 5 to 10 from table
sys.subtable1
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-28117/.s.monetdb.35132
+MAPI = (monetdb) /var/tmp/mtest-131881/.s.monetdb.39742
+QUERY = ALTER TABLE testme ADD TABLE subtable2 AS PARTITION FROM 5 TO 5;
--error
+ERROR = !ALTER TABLE: conflicting partitions: 5 to 5 and 5 to 10 from table
sys.subtable1
+CODE = 42000
+MAPI = (monetdb) /var/tmp/mtest-131881/.s.monetdb.39742
+QUERY = ALTER TABLE testme DROP TABLE subtable2; --error
+ERROR = !ALTER TABLE: table 'sys.subtable2' isn't part of RANGE PARTITION
TABLE 'sys.testme'
+CODE = 42S02
+MAPI = (monetdb) /var/tmp/mtest-128084/.s.monetdb.39134
QUERY = DROP TABLE subtable1; --error
ERROR = !DROP TABLE: unable to drop table subtable1 (there are database
objects which depend on it)
CODE = 42000
diff --git a/sql/test/merge-partitions/Tests/mergepart30.sql
b/sql/test/merge-partitions/Tests/mergepart30.sql
--- a/sql/test/merge-partitions/Tests/mergepart30.sql
+++ b/sql/test/merge-partitions/Tests/mergepart30.sql
@@ -12,6 +12,9 @@ DROP TABLE table2;
CREATE MERGE TABLE table1 (a int) PARTITION BY RANGE ON (a);
CREATE TABLE another1 (a int);
CREATE TABLE another2 (a int);
+CREATE TABLE another3 (a int);
+CREATE TABLE another4 (a int);
+CREATE TABLE another5 (a int);
ALTER TABLE table1 ADD TABLE another1 AS PARTITION FROM RANGE MINVALUE TO
RANGE MAXVALUE WITH NULL VALUES; --holds all
INSERT INTO table1 VALUES (1), (NULL);
@@ -97,6 +100,27 @@ ALTER TABLE table1 ADD TABLE another2 AS
ALTER TABLE table1 DROP TABLE another1;
ALTER TABLE table1 DROP TABLE another2; --error, not there
+ALTER TABLE table1 ADD TABLE another1 AS PARTITION FROM RANGE MINVALUE TO 0;
+ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM 10 TO RANGE MAXVALUE;
+ALTER TABLE table1 ADD TABLE another3 AS PARTITION FROM 0 TO 10;
+ALTER TABLE table1 ADD TABLE another4 AS PARTITION FOR NULL VALUES;
+
+ALTER TABLE table1 ADD TABLE another5 AS PARTITION FROM -100 TO -1; --error,
conflicts with another1
+ALTER TABLE table1 ADD TABLE another5 AS PARTITION FROM 0 TO 0; --error,
conflicts with another1
+ALTER TABLE table1 ADD TABLE another5 AS PARTITION FROM 10 TO 10; --error,
conflicts with another2
+ALTER TABLE table1 ADD TABLE another5 AS PARTITION FROM 10 TO 11; --error,
conflicts with another2
+ALTER TABLE table1 ADD TABLE another5 AS PARTITION FROM 9 TO 10; --error,
conflicts with another3
+ALTER TABLE table1 ADD TABLE another5 AS PARTITION FOR NULL VALUES; --error,
conflicts with another4
+
+ALTER TABLE table1 DROP TABLE another1;
+ALTER TABLE table1 DROP TABLE another2;
+ALTER TABLE table1 DROP TABLE another3;
+ALTER TABLE table1 DROP TABLE another4;
+ALTER TABLE table1 DROP TABLE another5; --error, not there
+
DROP TABLE another1;
DROP TABLE another2;
+DROP TABLE another3;
+DROP TABLE another4;
+DROP TABLE another5;
DROP TABLE table1;
diff --git a/sql/test/merge-partitions/Tests/mergepart30.stable.err
b/sql/test/merge-partitions/Tests/mergepart30.stable.err
--- a/sql/test/merge-partitions/Tests/mergepart30.stable.err
+++ b/sql/test/merge-partitions/Tests/mergepart30.stable.err
@@ -69,15 +69,15 @@ MAPI = (monetdb) /var/tmp/mtest-84239/.
QUERY = ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM 0 to 5;
--error, conflicts with another1
ERROR = !ALTER TABLE: conflicting partitions: 0 to 5 and absolute min value to
absolute max value from table sys.another1
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-89788/.s.monetdb.36023
+MAPI = (monetdb) /var/tmp/mtest-99796/.s.monetdb.30680
QUERY = ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM RANGE MINVALUE
to 2; --error, conflicts with another1
ERROR = !ALTER TABLE: conflicting partitions: absolute min value to 2 and
absolute min value to absolute max value from table sys.another1
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-89788/.s.monetdb.36023
+MAPI = (monetdb) /var/tmp/mtest-99796/.s.monetdb.30680
QUERY = ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM 2 to RANGE
MAXVALUE; --error, conflicts with another1
ERROR = !ALTER TABLE: conflicting partitions: 2 to absolute max value and
absolute min value to absolute max value from table sys.another1
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-89788/.s.monetdb.36023
+MAPI = (monetdb) /var/tmp/mtest-99796/.s.monetdb.30680
QUERY = ALTER TABLE table1 DROP TABLE another2; --error, not there
ERROR = !ALTER TABLE: table 'sys.another2' isn't part of RANGE PARTITION TABLE
'sys.table1'
CODE = 42S02
@@ -85,11 +85,11 @@ MAPI = (monetdb) /var/tmp/mtest-86521/.
QUERY = ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM RANGE MINVALUE
TO 1; --error, conflicts with another1
ERROR = !ALTER TABLE: conflicting partitions: absolute min value to 1 and
absolute min value to 2 from table sys.another1
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-89557/.s.monetdb.34879
+MAPI = (monetdb) /var/tmp/mtest-99796/.s.monetdb.30680
QUERY = ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM 0 TO 1;
--error, conflicts with another1
ERROR = !ALTER TABLE: conflicting partitions: 0 to 1 and absolute min value to
2 from table sys.another1
CODE = 42000
-MAPI = (monetdb) /var/tmp/mtest-89557/.s.monetdb.34879
+MAPI = (monetdb) /var/tmp/mtest-99796/.s.monetdb.30680
QUERY = ALTER TABLE table1 DROP TABLE another2; --error, not there
ERROR = !ALTER TABLE: table 'sys.another2' isn't part of RANGE PARTITION TABLE
'sys.table1'
CODE = 42S02
@@ -97,14 +97,42 @@ MAPI = (monetdb) /var/tmp/mtest-86671/.
QUERY = ALTER TABLE table1 ADD TABLE another2 AS PARTITION FROM 10 TO RANGE
MAXVALUE; --error, conflicts with another1
ERROR = !ALTER TABLE: conflicting partitions: 10 to absolute max value and 2
to absolute max value from table sys.another1
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list