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