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

Reply via email to