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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list