Changeset: 7460da94eea6 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7460da94eea6
Added Files:
        sql/test/merge-partitions/Tests/mergepart07.sql
        sql/test/merge-partitions/Tests/mergepart07.stable.err
        sql/test/merge-partitions/Tests/mergepart07.stable.out
Modified Files:
        monetdb5/modules/mal/wlc.mal
        sql/backends/monet5/sql_cat.c
        sql/backends/monet5/sqlcatalog.mal
        sql/backends/monet5/wlr.mal
        sql/common/sql_list.c
        sql/include/sql_catalog.h
        sql/server/rel_schema.c
        sql/server/sql_atom.c
        sql/server/sql_mvc.c
        sql/server/sql_parser.y
        sql/storage/sql_catalog.c
        sql/storage/sql_storage.h
        sql/storage/store.c
        sql/test/merge-partitions/Tests/All
Branch: merge-partitions
Log Message:

Added option WITH NULL clause for a range partition to store NULL values, and 
memory leak fixes.


diffs (truncated from 933 to 300 lines):

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
@@ -222,7 +222,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)
+pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str, 
min:str, max:str, nills:int)
 address WLCgeneric
 comment "Catalog operation alter_add_range_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
@@ -176,7 +176,7 @@ add_quotes(char *atom_str) /* always pro
 }
 
 static char *
-alter_table_add_range_partition(mvc *sql, char *msname, char *mtname, char 
*psname, char *ptname, char *min, char *max)
+alter_table_add_range_partition(mvc *sql, char *msname, char *mtname, char 
*psname, char *ptname, char *min, char *max, int with_nills)
 {
        sql_table *mt = NULL, *pt = NULL;
        sql_part *err = NULL;
@@ -200,12 +200,8 @@ alter_table_add_range_partition(mvc *sql
 
        col = mt->pcol;
        tp1 = col->type.type->localtype;
-       if(tp1 == TYPE_str) {
-               if((escaped_min = add_quotes(min)) == NULL) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                       goto finish;
-               }
-               if((escaped_max = add_quotes(max)) == NULL) {
+       if(tp1 == TYPE_str && ATOMcmp(tp1, min, ATOMnilptr(tp1))) {
+               if ((escaped_min = add_quotes(min)) == NULL) {
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
                        goto finish;
                }
@@ -213,21 +209,36 @@ alter_table_add_range_partition(mvc *sql
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing minimum value");
                        goto finish;
                }
+       } else {
+               if (ATOMfromstr(tp1, &pmin, &smin, min) < 0) {
+                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing minimum value");
+                       goto finish;
+               }
+       }
+
+       if(tp1 == TYPE_str && ATOMcmp(tp1, max, ATOMnilptr(tp1))) {
+               if((escaped_max = add_quotes(max)) == NULL) {
+                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                       goto finish;
+               }
                if(ATOMfromstr(tp1, &pmax, &smax, escaped_max) < 0) {
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing maximum value");
                        goto finish;
                }
        } else {
-               if(ATOMfromstr(tp1, &pmin, &smin, min) < 0) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing minimum value");
-                       goto finish;
-               }
                if(ATOMfromstr(tp1, &pmax, &smax, max) < 0) {
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing maximum value");
                        goto finish;
                }
        }
-       if(ATOMcmp(tp1, pmin, pmax) > 0) {
+
+       if(ATOMcmp(tp1, pmin, ATOMnilptr(tp1)) == 0) {
+               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: range bound cannot be null");
+               goto finish;
+       } else if(ATOMcmp(tp1, pmax, ATOMnilptr(tp1)) == 0) {
+               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: range bound cannot be null");
+               goto finish;
+       } else if(ATOMcmp(tp1, pmin, pmax) > 0) {
                msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: minimum value is higher than maximum value");
                goto finish;
        }
@@ -251,6 +262,11 @@ alter_table_add_range_partition(mvc *sql
                        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((diff1 = BATthetaselect(cbind, NULL, pmin, "<")) == NULL) {
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
                        goto finish;
@@ -271,7 +287,7 @@ alter_table_add_range_partition(mvc *sql
                }
        }
 
-       errcode = sql_trans_add_range_partition(sql->session->tr, mt, pt, tp1, 
pmin, smin, pmax, smax, &err);
+       errcode = sql_trans_add_range_partition(sql->session->tr, mt, pt, tp1, 
pmin, smin, pmax, smax, with_nills, &err);
        switch(errcode) {
                case -1:
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
@@ -286,18 +302,24 @@ alter_table_add_range_partition(mvc *sql
                        break;
                case -4:
                        assert(err);
-                       atomtostr = BATatoms[tp1].atomToStr;
-                       if(atomtostr(&err_min, &serr_min, 
err->part.range.minvalue) < 0) {
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                       } else if(atomtostr(&err_max, &serr_max, 
err->part.range.maxvalue) < 0) {
-                               GDKfree(err_min);
-                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                       if(with_nills && err->part.range.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->t->base.name);
                        } else {
-                               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",
-                                                                 min, max, 
err_min, err_max, err->t->s->base.name, err->t->base.name);
-                               GDKfree(err_min);
-                               GDKfree(err_max);
+                               atomtostr = BATatoms[tp1].atomToStr;
+                               if(atomtostr(&err_min, &serr_min, 
err->part.range.minvalue) < 0) {
+                                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                               } else if(atomtostr(&err_max, &serr_max, 
err->part.range.maxvalue) < 0) {
+                                       GDKfree(err_min);
+                                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                               } else {
+                                       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",
+                                                                         min, 
max, err_min, err_max, err->t->s->base.name, err->t->base.name);
+                                       GDKfree(err_min);
+                                       GDKfree(err_max);
+                               }
                        }
                        break;
        }
@@ -307,18 +329,16 @@ finish:
                GDKfree(escaped_min);
        if(escaped_max)
                GDKfree(escaped_max);
+       if(pmin)
+               GDKfree(pmin);
+       if(pmax)
+               GDKfree(pmax);
        if(cbind)
                BBPunfix(cbind->batCacheid);
        if(diff1)
                BBPunfix(diff1->batCacheid);
        if(diff2)
                BBPunfix(diff2->batCacheid);
-       if(msg) {
-               if(pmin)
-                       GDKfree(pmin);
-               if(pmax)
-                       GDKfree(pmax);
-       }
        return msg;
 }
 
@@ -365,7 +385,7 @@ alter_table_add_value_partition(mvc *sql
                        escaped = NULL;
                }
 
-               if(tp1 == TYPE_str) {
+               if(tp1 == TYPE_str && ATOMcmp(tp1, next, ATOMnilptr(tp1))) {
                        if ((escaped = add_quotes(next)) == NULL) {
                                msg = createException(SQL, 
"sql.alter_table_add_value_partition", SQLSTATE(HY001) MAL_MALLOC_FAIL);
                                goto finish;
@@ -1640,9 +1660,10 @@ SQLalter_add_range_partition(Client cntx
        char *ptname = SaveArgReference(stk, pci, 4);
        char *min = SaveArgReference(stk, pci, 5);
        char *max = SaveArgReference(stk, pci, 6);
+       int with_nills = *getArgReference_int(stk, pci, 7);
 
        initcontext();
-       msg = alter_table_add_range_partition(sql, sname, mtname, psname, 
ptname, min, max);
+       msg = alter_table_add_range_partition(sql, sname, mtname, psname, 
ptname, min, max, with_nills);
        return msg;
 }
 
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
@@ -147,7 +147,7 @@ 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:str, max:str)
+pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str, 
min:str, max:str, nills:int)
 address SQLalter_add_range_partition
 comment "Catalog operation alter_add_range_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
@@ -227,7 +227,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)
+pattern alter_add_range_partition( sname:str, mtnme:str, psnme:str, ptnme:str, 
min:str, max:str, nills:int)
 address WLRgeneric
 comment "Catalog operation alter_add_range_partition";
 
diff --git a/sql/common/sql_list.c b/sql/common/sql_list.c
--- a/sql/common/sql_list.c
+++ b/sql/common/sql_list.c
@@ -210,12 +210,14 @@ list_append_sorted(list *l, void *data, 
                        err = cmp(m->data, data, &comp);
                        if(err)
                                return err;
-                       if(comp > 0)
+                       if(comp < 0)
                                break;
                        first = 0;
                }
-               if(first)
+               if(first) {
+                       n->next = l->h;
                        l->h = n;
+               }
                if(!m) {
                        l->t->next = n;
                        l->t = n;
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
@@ -519,8 +519,9 @@ typedef struct sql_part {
        union {
                bat values;           /* partition by values/list */
                struct sql_range {    /* partition by range */
-                       ptr *minvalue;
-                       ptr *maxvalue;
+                       int with_nills;
+                       ptr minvalue;
+                       ptr maxvalue;
                        size_t minlength;
                        size_t maxlength;
                } range;
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,7 +85,8 @@ 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)
+rel_alter_table_add_partition_range(sql_allocator *sa, 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);
@@ -102,6 +103,7 @@ rel_alter_table_add_partition_range(sql_
        }
        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;
@@ -1455,6 +1457,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                        sql_column *col =  t->pcol;
                                        dlist* ll = extra->data.lval;
                                        symbol* min = ll->h->data.sym, *max = 
ll->h->next->data.sym;
+                                       int nills = 
ll->h->next->next->data.i_val;
                                        atom *amin = NULL, *amax = NULL;
 
                                        if(t->type != tt_range_partition) {
@@ -1465,10 +1468,13 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                        if(min->token == SQL_MINVALUE) {
                                                amin = 
atom_absolute_min(sql->sa, &(col->type));
                                                if(!amin) {
+                                                       sql_rel *res = NULL;
                                                        char *err = 
sql_subtype_string(&(col->type));
                                                        if(!err)
                                                                return 
sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
-                                                       return sql_error(sql, 
02, SQLSTATE(HY001) "ALTER TABLE: absolute minimum value not available for %s 
type", err);
+                                                       res = sql_error(sql, 
02, SQLSTATE(HY001) "ALTER TABLE: absolute minimum value not available for %s 
type", err);
+                                                       GDKfree(err);
+                                                       return res;
                                                }
                                        } else {
                                                amin = ((AtomNode *) min)->a;
@@ -1478,13 +1484,16 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                        } else {
                                                amax = ((AtomNode *) max)->a;
                                                if(!amin) {
+                                                       sql_rel *res = NULL;
                                                        char *err = 
sql_subtype_string(&(col->type));
                                                        if(!err)
                                                                return 
sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
-                                                       return sql_error(sql, 
02, SQLSTATE(HY001) "ALTER TABLE: absolute maximum value not available for %s 
type", err);
+                                                       res = sql_error(sql, 
02, SQLSTATE(HY001) "ALTER TABLE: absolute maximum value not available for %s 
type", err);
+                                                       GDKfree(err);
+                                                       return res;
                                                }
                                        }
-                                       return 
rel_alter_table_add_partition_range(sql->sa, sname, tname, sname, ntname, amin, 
amax);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to