Changeset: 75280a18cc58 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=75280a18cc58
Added Files:
        sql/test/merge-partitions/Tests/mergepart15.sql
        sql/test/merge-partitions/Tests/mergepart15.stable.err
        sql/test/merge-partitions/Tests/mergepart15.stable.out
Modified Files:
        sql/backends/monet5/sql_cat.c
        sql/server/rel_schema.c
        sql/server/sql_parser.y
        sql/storage/store.c
        sql/test/merge-partitions/Tests/All
Branch: merge-partitions
Log Message:

Allow range partitions to held only null values.


diffs (truncated from 516 to 300 lines):

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
@@ -191,7 +191,7 @@ alter_table_add_range_partition(mvc *sql
        ptr pmin = NULL, pmax = NULL;
        size_t smin = 0, smax = 0, serr_min = 0, serr_max = 0;
        ssize_t (*atomtostr)(str *, size_t *, const void *);
-       int accesses[3] = {RDONLY, RD_INS, RD_UPD_VAL};
+       int accesses[3] = {RDONLY, RD_INS, RD_UPD_VAL}, free_pmin = 1, 
free_pmax = 1;
 
        if((msg = validate_alter_table_add_table(sql, 
"sql.alter_table_add_range_partition", msname, mtname, psname, ptname, &mt, 
&pt))) {
                return msg;
@@ -209,45 +209,54 @@ alter_table_add_range_partition(mvc *sql
 
        col = mt->pcol;
        tp1 = col->type.type->localtype;
-       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;
-               }
-               if(ATOMfromstr(tp1, &pmin, &smin, escaped_min) < 0) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing minimum value");
+       if(ATOMcmp(TYPE_str, min, ATOMnilptr(TYPE_str))) {
+               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 (ATOMfromstr(tp1, &pmin, &smin, escaped_min) < 0) {
+                               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;
                }
        } 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 the ranges are not set, the partition is for null values 
only
+               assert(with_nills && !ATOMcmp(TYPE_str, max, 
ATOMnilptr(TYPE_str)));
        }
 
-       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");
+       if(ATOMcmp(TYPE_str, max, ATOMnilptr(TYPE_str))) {
+               if (tp1 == TYPE_str) {
+                       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, &pmax, &smax, 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, &pmax, &smax, max) < 0) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: error while parsing maximum value");
-                       goto finish;
-               }
+               assert(with_nills && !ATOMcmp(TYPE_str, min, 
ATOMnilptr(TYPE_str)));
        }
 
-       if(ATOMcmp(tp1, pmin, ATOMnilptr(tp1)) == 0) {
+       if(pmin && 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) {
+       } else if(pmax && 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) {
+       } else if(pmin && pmax && 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;
        }
@@ -276,28 +285,53 @@ alter_table_add_range_partition(mvc *sql
                                                                        "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;
-               }
-               if(BATcount(diff1) > 0) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
+               if(!pmin && !pmax) {
+                       if((diff1 = BATselect(cbind, NULL, ATOMnilptr(tp1), 
NULL, 1, 1, 1)) == NULL) {
+                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                               goto finish;
+                       }
+                       if(BATcount(diff1) > 0) {
+                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
+                                                                       "ALTER 
TABLE: there are non-null values in the column which is not allowed for this 
partition");
+                               goto finish;
+                       }
+               } else {
+                       if((diff1 = BATthetaselect(cbind, NULL, pmin, "<")) == 
NULL) {
+                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                               goto finish;
+                       }
+                       if(BATcount(diff1) > 0) {
+                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
                                                                        "ALTER 
TABLE: there are values in the column %s with values lesser than the partition 
minimum", col->base.name);
-                       goto finish;
+                               goto finish;
+                       }
+                       if((diff2 = BATthetaselect(cbind, NULL, pmax, ">")) == 
NULL) {
+                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                               goto finish;
+                       }
+                       if(BATcount(diff2) > 0) {
+                               msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
+                                                                       "ALTER 
TABLE: there are values in the column %s with values higher than the partition 
maximum", col->base.name);
+                               goto finish;
+                       }
                }
-               if((diff2 = BATthetaselect(cbind, NULL, pmax, ">")) == NULL) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
-                       goto finish;
-               }
-               if(BATcount(diff2) > 0) {
-                       msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
-                                                                       "ALTER 
TABLE: there are values in the column %s with values higher than the partition 
maximum", col->base.name);
-                       goto finish;
-               }
+       }
+
+       if(!pmin) {
+               pmin = (ptr) ATOMnilptr(tp1);
+               smin = ATOMsize(tp1);
+               free_pmin = 0;
+       }
+       if(!pmax) {
+               pmax = (ptr) ATOMnilptr(tp1);
+               smax = ATOMsize(tp1);
+               free_pmax = 0;
        }
 
        errcode = sql_trans_add_range_partition(sql->session->tr, mt, pt, 
col->type, pmin, smin, pmax, smax, with_nills, &err);
        switch(errcode) {
+               case 0:
+                       break;
                case -1:
                        msg = 
createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
                        break;
@@ -331,6 +365,8 @@ alter_table_add_range_partition(mvc *sql
                                }
                        }
                        break;
+               default:
+                       assert(0);
        }
 
 finish:
@@ -338,9 +374,9 @@ finish:
                GDKfree(escaped_min);
        if(escaped_max)
                GDKfree(escaped_max);
-       if(pmin)
+       if(pmin && free_pmin)
                GDKfree(pmin);
-       if(pmax)
+       if(pmax && free_pmax)
                GDKfree(pmax);
        if(cbind)
                BBPunfix(cbind->batCacheid);
@@ -1599,8 +1635,8 @@ SQLalter_add_range_partition(Client cntx
        char *mtname = SaveArgReference(stk, pci, 2);
        char *psname = SaveArgReference(stk, pci, 3);
        char *ptname = SaveArgReference(stk, pci, 4);
-       char *min = SaveArgReference(stk, pci, 5);
-       char *max = SaveArgReference(stk, pci, 6);
+       char *min = *getArgReference_str(stk, pci, 5);
+       char *max = *getArgReference_str(stk, pci, 6);
        int with_nills = *getArgReference_int(stk, pci, 7);
 
        initcontext();
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
@@ -90,8 +90,8 @@ rel_alter_table_add_partition_range(sql_
 {
        sql_rel *rel = rel_create(sa);
        list *exps = new_exp_list(sa);
-       char *pmin = atom2string(sa, min), *pmax = atom2string(sa, max);
-       if(!rel || !exps || !pmin || !pmax)
+       char *pmin = min ? atom2string(sa, min): NULL, *pmax = max ? 
atom2string(sa, max) : NULL;
+       if(!rel || !exps)
                return NULL;
 
        append(exps, exp_atom_clob(sa, sname));
@@ -1478,7 +1478,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                                                (t->type == 
tt_merge_table)?"merge":"list partition");
                                        }
 
-                                       if(min->token == SQL_MINVALUE) {
+                                       if(min && min->token == SQL_MINVALUE) {
                                                amin = 
atom_absolute_min(sql->sa, &(col->type));
                                                if(!amin) {
                                                        sql_rel *res = NULL;
@@ -1489,10 +1489,10 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                                        GDKfree(err);
                                                        return res;
                                                }
-                                       } else {
+                                       } else if(min) {
                                                amin = ((AtomNode *) min)->a;
                                        }
-                                       if(max->token == SQL_MAXVALUE) {
+                                       if(max && max->token == SQL_MAXVALUE) {
                                                amax = 
atom_absolute_max(sql->sa, &(col->type));
                                                if(!amax) {
                                                        sql_rel *res = NULL;
@@ -1503,7 +1503,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                                        GDKfree(err);
                                                        return res;
                                                }
-                                       } else {
+                                       } else if(max) {
                                                amax = ((AtomNode *) max)->a;
                                        }
                                        return 
rel_alter_table_add_partition_range(sql->sa, sname, tname, sname, ntname, amin, 
amax, nills);
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -1509,6 +1509,12 @@ opt_partition_spec:
       append_symbol(l, $4);
       append_int(l, $5);
       $$ = _symbol_create_list( SQL_PARTITION_RANGE, l ); }
+ | WITH sqlNULL
+    { dlist *l = L();
+      append_symbol(l, NULL);
+      append_symbol(l, NULL);
+      append_int(l, TRUE);
+      $$ = _symbol_create_list( SQL_PARTITION_RANGE, l ); }
  ;
 
 opt_as_partition:
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -4658,16 +4658,21 @@ sql_trans_add_range_partition(sql_trans 
        sql_table *partitions = find_sql_table(syss, "_table_partitions");
        sql_table *ranges = find_sql_table(syss, "_range_partitions");
        sql_part *p = SA_ZNEW(tr->sa, sql_part);
-       ssize_t (*atomtostr)(str *, size_t *, const void *) = 
BATatoms[tpe.type->localtype].atomToStr;
+       int localtype = tpe.type->localtype, free_min = 1, free_max = 1;
+       ssize_t (*atomtostr)(str *, size_t *, const void *) = 
BATatoms[localtype].atomToStr;
        str str_min = NULL, str_max = NULL;
        size_t length = 0;
        bit to_insert = (bit) with_nills;
        oid rid;
        int *v, res = 0;
 
-       if(atomtostr(&str_min, &length, min) == 0) {
+       if(min && atomtostr(&str_min, &length, min) == 0) {
                res = -1;
                goto finish;
+       } else if(!min) {
+               str_min = (ptr) ATOMnilptr(localtype);
+               smin = ATOMlen(localtype, str_min);
+               free_min = 0;
        }
        if(length > STORAGE_MAX_VALUE_LENGTH) {
                res = -2;
@@ -4677,6 +4682,10 @@ sql_trans_add_range_partition(sql_trans 
        if(atomtostr(&str_max, &length, max) == 0) {
                res = -1;
                goto finish;
+       } else if(!max) {
+               str_max = (ptr) ATOMnilptr(localtype);
+               smax = ATOMlen(localtype, str_max);
+               free_max = 0;
        }
        if(length > STORAGE_MAX_VALUE_LENGTH) {
                res = -3;
@@ -4716,9 +4725,9 @@ sql_trans_add_range_partition(sql_trans 
        _DELETE(v);
 
 finish:
-       if(str_min)
+       if(str_min && free_min)
                GDKfree(str_min);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to