Changeset: f19c05c83193 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f19c05c83193 Added Files: sql/test/merge-partitions/Tests/mergepart01.stable.err sql/test/merge-partitions/Tests/mergepart01.stable.out Modified Files: sql/backends/monet5/sql_cat.c sql/common/sql_changeset.c sql/common/sql_list.c sql/common/sql_mem.c sql/include/sql_catalog.h sql/include/sql_list.h sql/include/sql_mem.h sql/storage/sql_catalog.c sql/storage/sql_storage.h sql/storage/store.c sql/test/merge-partitions/Tests/mergepart01.sql Branch: merge-partitions Log Message:
Validates range partitions intervals diffs (truncated from 742 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 @@ -119,7 +119,7 @@ validate_alter_table_add_table(mvc *sql, node *n = cs_find_id(&rmt->members, rpt->base.id); if (n) - throw(SQL,"alter_table_add_table",SQLSTATE(42S02) "ALTER TABLE: table '%s.%s' is already part of the MERGE TABLE '%s.%s'", psname, ptname, msname, mtname); + throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: table '%s.%s' is already part of the MERGE TABLE '%s.%s'", psname, ptname, msname, mtname); if ((msg = rel_check_tables(rmt, rpt)) != NULL) return msg; return MAL_SUCCEED; @@ -146,11 +146,13 @@ static char * alter_table_add_range_partition(mvc *sql, char *msname, char *mtname, char *psname, char *ptname, char *min, char *max) { sql_table *mt = NULL, *pt = NULL; - str msg = MAL_SUCCEED; + sql_part *err = NULL; + str msg = MAL_SUCCEED, err_min = NULL, err_max = NULL; sql_column *col = NULL; int tp1 = 0, errcode = 0; ptr pmin = NULL, pmax = NULL; - size_t smin = 0, smax = 0; + size_t smin = 0, smax = 0, serr_min = 0, serr_max = 0; + ssize_t (*atomtostr)(str *, size_t *, const void *); if((msg = validate_alter_table_add_table(sql, "sql.alter_table_add_range_partition", msname, mtname, psname, ptname, &mt, &pt))) return msg; @@ -176,18 +178,32 @@ alter_table_add_range_partition(mvc *sql goto finish; } - /* TODO search for a conflicting partition */ - errcode = sql_trans_add_range_partition(sql->session->tr, mt, pt, tp1, pmin, smin, pmax, smax); + errcode = sql_trans_add_range_partition(sql->session->tr, mt, pt, tp1, pmin, smin, pmax, smax, &err); switch(errcode) { case -1: msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY001) MAL_MALLOC_FAIL); - break; + break; case -2: msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) "ALTER TABLE: minimum value length is higher than %d", STORAGE_MAX_VALUE_LENGTH); - break; + break; case -3: msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) "ALTER TABLE: maximum value length is higher than %d", STORAGE_MAX_VALUE_LENGTH); - break; + 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); + } 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; } finish: @@ -256,10 +272,10 @@ alter_table_add_value_partition(mvc *sql break; case -1: msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(HY001) MAL_MALLOC_FAIL); - break; + break; default: msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000) "ALTER TABLE: value at position %d length is higher than %d", (errcode * -1) - 1, STORAGE_MAX_VALUE_LENGTH); - break; + break; } finish: diff --git a/sql/common/sql_changeset.c b/sql/common/sql_changeset.c --- a/sql/common/sql_changeset.c +++ b/sql/common/sql_changeset.c @@ -42,6 +42,19 @@ cs_add(changeset * cs, void *elm, int fl cs->nelm = cs->set->t; } +void* +cs_add_sorted(changeset * cs, void *elm, int flag, fcmpvalidate cmp) +{ + void* res = NULL; + if (!cs->set) + cs->set = list_new(cs->sa, cs->destroy); + if((res = list_append_sorted(cs->set, elm, cmp)) != NULL) + return res; + if (flag == TR_NEW && !cs->nelm) + cs->nelm = cs->set->t; + return res; +} + void cs_add_before(changeset * cs, node *n, void *elm) { 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 @@ -160,6 +160,49 @@ list_append(list *l, void *data) return l; } +void* +list_append_sorted(list *l, void *data, fcmpvalidate cmp) +{ + node *n = node_create(l->sa, data), *m; + int first = 1, comp = 0; + void* err = NULL; + + if (n == NULL) + return NULL; + if (l->cnt == 0) { + l->h = n; + l->t = n; + } else { + for (m = l->h; m; m = m->next) { + err = cmp(m->data, data, &comp); + if(err) + return err; + if(comp > 0) + break; + first = 0; + } + if(first) + l->h = n; + if(!m) { + l->t->next = n; + l->t = n; + } else + m->next = n; + } + l->cnt++; + MT_lock_set(&l->ht_lock); + if (l->ht) { + int key = l->ht->key(data); + + if (hash_add(l->ht, key, data) == NULL) { + MT_lock_unset(&l->ht_lock); + return NULL; + } + } + MT_lock_unset(&l->ht_lock); + return NULL; +} + list * list_append_before(list *l, node *m, void *data) { diff --git a/sql/common/sql_mem.c b/sql/common/sql_mem.c --- a/sql/common/sql_mem.c +++ b/sql/common/sql_mem.c @@ -117,6 +117,37 @@ void *sa_alloc( sql_allocator *sa, size_ return r; } +void *sa_push( sql_allocator *sa, void *area, size_t sz ) +{ + sz = round16(sz); + if (sz > (SA_BLOCK-sa->used)) { + if (sa->nr >= sa->size) { + char **tmp; + sa->size *=2; + tmp = RENEW_ARRAY(char*,sa->blks,sa->size); + if (tmp == NULL) { + sa->size /= 2; /* undo */ + return NULL; + } + sa->blks = tmp; + } + if (sz > SA_BLOCK) { + sa->blks[sa->nr] = sa->blks[sa->nr-1]; + sa->blks[sa->nr-1] = area; + sa->nr ++; + sa->usedmem += sz; + } else { + sa->blks[sa->nr] = area; + sa->nr ++; + sa->used = sz; + sa->usedmem += SA_BLOCK; + } + } else { + sa->used += sz; + } + return area; +} + #undef sa_zalloc void *sa_zalloc( sql_allocator *sa, size_t sz ) { 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 @@ -103,7 +103,9 @@ #define EXCLUDE_TIES 3 #define EXCLUDE_NO_OTHERS 4 -#define PARTITION_NONE 0 +#define PARTITION_BY_COLUMN 1 +#define PARTITION_BY_EXPRESSION 2 + #define PARTITION_RANGE 1 #define PARTITION_LIST 2 @@ -198,6 +200,7 @@ typedef struct changeset { extern void cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy); extern void cs_destroy(changeset * cs); extern void cs_add(changeset * cs, void *elm, int flag); +extern void *cs_add_sorted(changeset * cs, void *elm, int flag, fcmpvalidate cmp); extern void cs_add_before(changeset * cs, node *n, void *elm); extern void cs_del(changeset * cs, node *elm, int flag); extern int cs_size(changeset * cs); @@ -509,9 +512,10 @@ typedef enum table_types { typedef struct sql_part { sql_base base; struct sql_table *t; /* cached value */ + int tpe; /* the column type */ union { - bat values; - struct sql_range { + bat values; /* partition by values/list */ + struct sql_range { /* partition by range */ ptr *minvalue; ptr *maxvalue; size_t minlength; @@ -623,6 +627,8 @@ extern sql_func *sql_trans_bind_func(sql extern sql_func *sql_trans_find_func(sql_trans *tr, int id); extern node *find_sql_func_node(sql_schema *s, int id); +extern void *sql_range_part_validate_and_insert(void *v1, void *v2, int* res); + typedef struct { BAT *b; char* name; diff --git a/sql/include/sql_list.h b/sql/include/sql_list.h --- a/sql/include/sql_list.h +++ b/sql/include/sql_list.h @@ -58,12 +58,14 @@ extern int list_traverse(list *l, traver * Returns 0 if data and key are equal * */ typedef int (*fcmp) (void *data, void *key); +typedef void *(*fcmpvalidate) (void *v1, void *v2, int *cmp); typedef int (*fcmp2) (void *data, void *v1, void *v2); typedef void *(*fdup) (void *data); typedef void *(*freduce) (void *v1, void *v2); typedef void *(*freduce2) (sql_allocator *sa, void *v1, void *v2); typedef void *(*fmap) (void *data, void *clientdata); +extern void *list_append_sorted(list *l, void *data, fcmpvalidate cmp); extern node *list_find(list *l, void *key, fcmp cmp); extern int list_position(list *l, void *val); extern void * list_fetch(list *l, int pos); diff --git a/sql/include/sql_mem.h b/sql/include/sql_mem.h --- a/sql/include/sql_mem.h +++ b/sql/include/sql_mem.h @@ -63,6 +63,7 @@ typedef struct sql_allocator { extern sql_allocator *sa_create(void); extern sql_allocator *sa_reset( sql_allocator *sa ); extern void *sa_alloc( sql_allocator *sa, size_t sz ); +extern void *sa_push( sql_allocator *sa, void *area, size_t sz ); extern void *sa_zalloc( sql_allocator *sa, size_t sz ); extern void *sa_realloc( sql_allocator *sa, void *ptr, size_t sz, size_t osz ); extern void sa_destroy( sql_allocator *sa ); diff --git a/sql/storage/sql_catalog.c b/sql/storage/sql_catalog.c --- a/sql/storage/sql_catalog.c +++ b/sql/storage/sql_catalog.c @@ -343,3 +343,18 @@ sql_trans_find_func(sql_trans *tr, int i } return t; } + +void* +sql_range_part_validate_and_insert(void *v1, void *v2, int* res) +{ + sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2; + + int res1 = ATOMcmp(pt->tpe, pt->part.range.minvalue, newp->part.range.maxvalue), + res2 = ATOMcmp(pt->tpe, newp->part.range.minvalue, pt->part.range.maxvalue); + if (res1 <= 0 && res2 <= 0) { //overlap: x1 <= y2 && y1 <= x2 + *res = 0; + return pt; + } + *res = res2; + return NULL; +} diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h --- a/sql/storage/sql_storage.h +++ b/sql/storage/sql_storage.h @@ -360,7 +360,7 @@ extern int sql_trans_drop_schema(sql_tra extern sql_table *sql_trans_create_table(sql_trans *tr, sql_schema *s, const char *name, const char *sql, int tt, bit system, int persistence, int commit_action, int sz); extern int sql_trans_set_partition_table(sql_trans *tr, sql_table *t); extern sql_table *sql_trans_add_table(sql_trans *tr, sql_table *mt, sql_table *pt); -extern int sql_trans_add_range_partition(sql_trans *tr, sql_table *mt, sql_table *pt, int tpe, ptr min, size_t smin, ptr max, size_t smax); +extern int sql_trans_add_range_partition(sql_trans *tr, sql_table *mt, sql_table *pt, int tpe, ptr min, size_t smin, ptr max, size_t smax, sql_part** err); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list