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

Reply via email to