Changeset: 416950cf458e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=416950cf458e
Modified Files:
clients/mapiclient/dump.c
monetdb5/modules/mal/wlc.mal
sql/backends/monet5/sql_cat.c
sql/backends/monet5/sqlcatalog.mal
sql/backends/monet5/wlr.mal
sql/include/sql_catalog.h
sql/server/rel_optimizer.c
sql/server/rel_propagate.c
sql/server/rel_propagate.h
sql/server/rel_schema.c
sql/storage/sql_catalog.c
sql/storage/sql_storage.h
sql/storage/store.c
sql/test/merge-partitions/Tests/mergepart05.stable.err
sql/test/merge-partitions/Tests/mergepart30.sql
sql/test/merge-partitions/Tests/mergepart30.stable.err
sql/test/merge-partitions/Tests/mergepart30.stable.out
Branch: Jun2020
Log Message:
Changes in range partitioned tables.
Added FROM RANGE MINVALUE TO RANGE MAXVALUE and FROM RANGE MINVALUE TO RANGE
MAXVALUE WITH NULL VALUES cases handling from user requests.
Both minvalue and maxvalue are translated into NULL values in the storage, so
to distinguish the FROM RANGE MINVALUE TO RANGE MAXVALUE WITH NULL VALUES from
the FOR NULL VALUES case, the 'with_nulls' field is set to nil instead of 1.
Also fixed a small bug of missing propagation of 'with_nulls' flag at
rollforward_update_part.
Some cosmetic changes at rel_propagate as well.
diffs (truncated from 1458 to 300 lines):
diff --git a/clients/mapiclient/dump.c b/clients/mapiclient/dump.c
--- a/clients/mapiclient/dump.c
+++ b/clients/mapiclient/dump.c
@@ -2916,7 +2916,7 @@ dump_database(Mapi mid, stream *toConsol
maxv = mapi_fetch_field(shdl, 1);
wnulls = mapi_fetch_field(shdl, 2);
}
- if (minv || maxv) {
+ if (minv || maxv || !wnulls) {
mnstr_printf(toConsole, " FROM ");
if (minv)
squoted_print(toConsole, minv,
'\'');
@@ -2928,9 +2928,8 @@ dump_database(Mapi mid, stream *toConsol
else
mnstr_printf(toConsole, "RANGE
MAXVALUE");
}
- if (strcmp(wnulls, "true") == 0) {
- mnstr_printf(toConsole, " %s NULL
VALUES", (minv || maxv) ? "WITH" : "FOR");
- }
+ if (!wnulls || strcmp(wnulls, "1") == 0)
+ mnstr_printf(toConsole, " %s NULL
VALUES", (minv || maxv || !wnulls) ? "WITH" : "FOR");
mapi_close_handle(shdl);
}
free(s2);
diff --git a/monetdb5/modules/mal/wlc.mal b/monetdb5/modules/mal/wlc.mal
--- a/monetdb5/modules/mal/wlc.mal
+++ b/monetdb5/modules/mal/wlc.mal
@@ -234,7 +234,7 @@ pattern alter_set_table( sname:str, tnme
address WLCgeneric
comment "Catalog operation alter_set_table";
-pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
min:str, max:str, nills:int, update:int)
+pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
min:str, max:str, nills:bit, update:int)
address WLCgeneric
comment "Catalog operation alter_add_range_partition";
@@ -274,10 +274,10 @@ unsafe pattern transaction()
address WLCgeneric
comment "Start an autocommit transaction";
-pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:int, update:int)
+pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:bit, update:int)
address WLCgeneric
comment "Catalog operation alter_add_value_partition";
-pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:int, update:int, arg:str...)
+pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:bit, update:int, arg:str...)
address WLCgeneric
comment "Catalog operation alter_add_value_partition";
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
@@ -196,14 +196,13 @@ alter_table_add_table(mvc *sql, char *ms
static char *
alter_table_add_range_partition(mvc *sql, char *msname, char *mtname, char
*psname, char *ptname, ptr min, ptr max,
- int with_nills,
int update)
+ bit with_nills,
int update)
{
sql_table *mt = NULL, *pt = NULL;
sql_part *err = NULL;
str msg = MAL_SUCCEED, err_min = NULL, err_max = NULL, conflict_err_min
= NULL, conflict_err_max = NULL;
int tp1 = 0, errcode = 0, min_null = 0, max_null = 0;
size_t length = 0;
- ssize_t (*atomtostr)(str *, size_t *, const void *, bool);
sql_subtype tpe;
if ((msg = validate_alter_table_add_table(sql,
"sql.alter_table_add_range_partition", msname, mtname, psname, ptname,
@@ -226,10 +225,7 @@ alter_table_add_range_partition(mvc *sql
min_null = ATOMcmp(tp1, min, ATOMnilptr(tp1)) == 0;
max_null = ATOMcmp(tp1, max, ATOMnilptr(tp1)) == 0;
- if (max_null && min_null && !with_nills) {
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
"ALTER TABLE: range bound cannot be null");
- goto finish;
- } else if (!min_null && !max_null && ATOMcmp(tp1, min, max) > 0) {
+ if (!min_null && !max_null && ATOMcmp(tp1, min, max) > 0) {
msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
"ALTER TABLE: minimum value is higher than maximum value");
goto finish;
}
@@ -251,26 +247,57 @@ alter_table_add_range_partition(mvc *sql
break;
case -4:
assert(err);
- if (with_nills && err->with_nills) {
+ if (is_bit_nil(err->with_nills)) {
+ msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
+
"ALTER TABLE: conflicting partitions: table %s.%s stores every possible value",
err->t->s->base.name, err->base.name);
+ } else if (with_nills && err->with_nills) {
msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
"ALTER TABLE: conflicting partitions: table %s.%s stores null values and only "
"one partition can store null values at the time", err->t->s->base.name,
err->base.name);
} else {
- atomtostr = BATatoms[tp1].atomToStr;
- if (atomtostr(&conflict_err_min, &length,
err->part.range.minvalue, true) < 0) {
+ ssize_t (*atomtostr)(str *, size_t *, const
void *, bool) = BATatoms[tp1].atomToStr;
+ ptr nil = ATOMnil(tp1);
+ sql_table *errt = mvc_bind_table(sql, mt->s,
err->base.name);
+
+ if (!ATOMcmp(tp1, nil,
err->part.range.minvalue)) {
+ if (!(conflict_err_min =
GDKstrdup("absolute min value")))
+ msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ } else if (atomtostr(&conflict_err_min,
&length, err->part.range.minvalue, true) < 0) {
msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+ if (msg)
+ goto finish;
+
+ if (!ATOMcmp(tp1, nil,
err->part.range.maxvalue)) {
+ if (!(conflict_err_max =
GDKstrdup("absolute max value")))
+ msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
} else if (atomtostr(&conflict_err_max,
&length, err->part.range.maxvalue, true) < 0) {
msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+ if (msg)
+ goto finish;
+
+ if (!ATOMcmp(tp1, nil, min)) {
+ if (!(err_min = GDKstrdup("absolute min
value")))
+ msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
} else if (atomtostr(&err_min, &length, min,
true) < 0) {
msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+ if (msg)
+ goto finish;
+
+ if (!ATOMcmp(tp1, nil, max)) {
+ if (!(err_max = GDKstrdup("absolute max
value")))
+ msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
} else if (atomtostr(&err_max, &length, max,
true) < 0) {
msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
- } else {
- sql_table *errt = mvc_bind_table(sql,
mt->s, err->base.name);
- msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
+ }
+ if (msg)
+ goto finish;
+
+ msg =
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
"ALTER TABLE: conflicting partitions: %s to %s and %s to %s from table %s.%s",
err_min, err_max, conflict_err_min, conflict_err_max, errt->s->base.name,
errt->base.name);
- }
}
break;
default:
@@ -293,7 +320,7 @@ finish:
static char *
alter_table_add_value_partition(mvc *sql, MalStkPtr stk, InstrPtr pci, char
*msname, char *mtname, char *psname,
- char *ptname,
int with_nills, int update)
+ char *ptname,
bit with_nills, int update)
{
sql_table *mt = NULL, *pt = NULL;
str msg = MAL_SUCCEED;
@@ -302,6 +329,7 @@ alter_table_add_value_partition(mvc *sql
list *values = list_new(sql->session->tr->sa, (fdestroy) NULL);
sql_subtype tpe;
+ assert(with_nills == false || with_nills == true); /* No nills allowed
here */
if ((msg = validate_alter_table_add_table(sql,
"sql.alter_table_add_value_partition", msname, mtname, psname, ptname,
&mt, &pt, update))) {
return msg;
@@ -1500,7 +1528,7 @@ SQLalter_add_range_partition(Client cntx
char *ptname = SaveArgReference(stk, pci, 4);
ValRecord *min = &(stk)->stk[(pci)->argv[5]];
ValRecord *max = &(stk)->stk[(pci)->argv[6]];
- int with_nills = *getArgReference_int(stk, pci, 7);
+ bit with_nills = *getArgReference_bit(stk, pci, 7);
int update = *getArgReference_int(stk, pci, 8);
initcontext();
@@ -1516,7 +1544,7 @@ SQLalter_add_value_partition(Client cntx
char *mtname = SaveArgReference(stk, pci, 2);
char *psname = SaveArgReference(stk, pci, 3);
char *ptname = SaveArgReference(stk, pci, 4);
- int with_nills = *getArgReference_int(stk, pci, 5);
+ bit with_nills = *getArgReference_bit(stk, pci, 5);
int update = *getArgReference_int(stk, pci, 6);
initcontext();
diff --git a/sql/backends/monet5/sqlcatalog.mal
b/sql/backends/monet5/sqlcatalog.mal
--- a/sql/backends/monet5/sqlcatalog.mal
+++ b/sql/backends/monet5/sqlcatalog.mal
@@ -151,15 +151,15 @@ pattern alter_set_table( sname:str, tnme
address SQLalter_set_table
comment "Catalog operation alter_set_table";
-pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
min:any_1, max:any_1, nills:int, update:int)
+pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
min:any_1, max:any_1, nills:bit, update:int)
address SQLalter_add_range_partition
comment "Catalog operation alter_add_range_partition";
-pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:int, update:int)
+pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:bit, update:int)
address SQLalter_add_value_partition
comment "Catalog operation alter_add_value_partition";
-pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:int, update:int, arg:any...)
+pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:bit, update:int, arg:any...)
address SQLalter_add_value_partition
comment "Catalog operation alter_add_value_partition";
diff --git a/sql/backends/monet5/wlr.mal b/sql/backends/monet5/wlr.mal
--- a/sql/backends/monet5/wlr.mal
+++ b/sql/backends/monet5/wlr.mal
@@ -239,7 +239,7 @@ pattern alter_set_table( sname:str, tnme
address WLRgeneric
comment "Catalog operation alter_set_table";
-pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
min:str, max:str, nills:int, update:int)
+pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
min:str, max:str, nills:bit, update:int)
address WLRgeneric
comment "Catalog operation alter_add_range_partition";
@@ -279,10 +279,10 @@ unsafe pattern transaction()
address WLRgeneric
comment "Start an autocommit transaction";
-pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:int, update:int)
+pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:bit, update:int)
address WLRgeneric
comment "Catalog operation alter_add_value_partition";
-pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:int, update:int, arg:str...)
+pattern alter_add_value_partition( sname:str, mtnme:str, psnme:str, ptnme:str,
nills:bit, update:int, arg:str...)
address WLRgeneric
comment "Catalog operation alter_add_value_partition";
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -613,7 +613,7 @@ typedef struct sql_part {
sql_base base;
struct sql_table *t; /* cached value of the merge table */
sql_subtype tpe; /* the column/expression type */
- int with_nills;
+ bit with_nills; /* 0 no nills, 1 holds nills, NULL holds all
values -> range FROM MINVALUE TO MAXVALUE WITH NULL */
union {
list *values; /* partition by values/list */
struct sql_range { /* partition by range */
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -8861,9 +8861,9 @@ optimize_rel(mvc *sql, sql_rel *rel, int
}
if ((gp.cnt[op_select] || gp.cnt[op_left] || gp.cnt[op_right] ||
gp.cnt[op_full] ||
- gp.cnt[op_join] || gp.cnt[op_semi] || gp.cnt[op_anti]) &&
level <= 0)
+ gp.cnt[op_join] || gp.cnt[op_semi] || gp.cnt[op_anti] ||
gp.cnt[op_ddl]) && level <= 0)
if (value_based_opt)
- rel = rel_visitor_bottomup(sql, rel,
&rel_simplify_predicates, &changes);
+ rel = rel_visitor_bottomup(sql, rel,
&rel_simplify_predicates, &changes);
/* join's/crossproducts between a relation and a constant (row).
* could be rewritten
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
@@ -26,13 +26,13 @@ rel_generate_anti_expression(mvc *sql, s
*anti_rel = rel_basetable(sql, pt, pt->base.name);
- if(isPartitionedByColumnTable(mt)) {
+ if (isPartitionedByColumnTable(mt)) {
int colr = mt->part.pcol->colnr;
res = list_fetch((*anti_rel)->exps, colr);
res = exp_ref(sql->sa, res);
- } else if(isPartitionedByExpressionTable(mt)) {
+ } else if (isPartitionedByExpressionTable(mt)) {
*anti_rel = rel_project(sql->sa, *anti_rel, NULL);
- if(!(res = rel_parse_val(sql, sa_message(sql->sa, "select %s;",
mt->part.pexp->exp), sql->emode, (*anti_rel)->l)))
+ if (!(res = rel_parse_val(sql, sa_message(sql->sa, "select
%s;", mt->part.pexp->exp), sql->emode, (*anti_rel)->l)))
return NULL;
exp_label(sql->sa, res, ++sql->label);
} else {
@@ -47,9 +47,9 @@ rel_generate_anti_expression(mvc *sql, s
static sql_rel*
rel_create_common_relation(mvc *sql, sql_rel *rel, sql_table *t)
{
- if(isPartitionedByColumnTable(t)) {
+ if (isPartitionedByColumnTable(t)) {
return rel_dup(rel->r);
- } else if(isPartitionedByExpressionTable(t)) {
+ } else if (isPartitionedByExpressionTable(t)) {
sql_rel *inserts;
list *l = new_exp_list(sql->sa);
@@ -76,13 +76,13 @@ rel_generate_anti_insert_expression(mvc
{
sql_exp* res = NULL;
- if((*anti_rel)->op != op_project && (*anti_rel)->op != op_basetable &&
(*anti_rel)->op != op_table) {
+ if ((*anti_rel)->op != op_project && (*anti_rel)->op != op_basetable &&
(*anti_rel)->op != op_table) {
sql_rel *inserts; //In a nested partition case the operation is
a op_select, then a projection must be created
list *l = new_exp_list(sql->sa);
*anti_rel = rel_project(sql->sa, *anti_rel, l);
inserts = (*anti_rel)->l;
- if(inserts->op != op_project && inserts->op != op_basetable &&
inserts->op != op_table)
+ if (inserts->op != op_project && inserts->op != op_basetable &&
inserts->op != op_table)
inserts = inserts->l;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list