Changeset: d9f0fee8aee9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d9f0fee8aee9
Modified Files:
        sql/backends/monet5/sql_cat.c
        sql/backends/monet5/sql_cat.h
        sql/include/sql_catalog.h
        sql/include/sql_relation.h
        sql/server/rel_optimizer.c
        sql/server/rel_schema.c
        sql/server/sql_atom.c
        sql/server/sql_atom.h
        sql/server/sql_parser.y
        sql/storage/sql_storage.h
        sql/storage/store.c
Branch: merge-partitions
Log Message:

Progress on range partition tables


diffs (truncated from 561 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
@@ -100,33 +100,78 @@ rel_check_tables(sql_table *nt, sql_tabl
        return MAL_SUCCEED;
 }
 
+static char*
+valdidate_alter_table_add_table(mvc *sql, char* call, char *msname, char 
*mtname, char *psname, char *ptname, sql_table **mt, sql_table **pt)
+{
+       sql_schema *ms = mvc_bind_schema(sql, msname), *ps = 
mvc_bind_schema(sql, psname);
+       sql_table *rmt = NULL, *rpt = NULL;
+
+       if (ms)
+               rmt = mvc_bind_table(sql, ms, mtname);
+       if (ps)
+               rpt = mvc_bind_table(sql, ps, ptname);
+       *mt = rmt;
+       *pt = rpt;
+       if (rmt && (!isMergeTable(rmt) && !isReplicaTable(rmt)))
+               throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: cannot add table 
'%s.%s' to table '%s.%s'", psname, ptname, msname, mtname);
+       if (rmt && rpt) {
+               char *msg;
+               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);
+               if ((msg = rel_check_tables(rmt, rpt)) != NULL)
+                       return msg;
+               return MAL_SUCCEED;
+       } else if (rmt) {
+               throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: no such table '%s' 
in schema '%s'", ptname, psname);
+       } else {
+               throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: no such table '%s' 
in schema '%s'", mtname, msname);
+       }
+}
+
 static char *
 alter_table_add_table(mvc *sql, char *msname, char *mtname, char *psname, char 
*ptname)
 {
-       sql_schema *ms = mvc_bind_schema(sql, msname), *ps = 
mvc_bind_schema(sql, psname);
        sql_table *mt = NULL, *pt = NULL;
+       str msg = valdidate_alter_table_add_table(sql, 
"sql.alter_table_add_table", msname, mtname, psname, ptname, &mt, &pt);
+
+       if(msg == MAL_SUCCEED)
+               sql_trans_add_table(sql->session->tr, mt, pt);
+
+       return msg;
+}
+
+static char *
+alter_table_add_range_partition(mvc *sql, char *msname, char *mtname, char 
*psname, char *ptname, MalBlkPtr m, MalStkPtr s, InstrPtr p)
+{
+       sql_table *mt = NULL, *pt = NULL;
+       sql_column *col = NULL;
+       str msg = valdidate_alter_table_add_table(sql, 
"sql.alter_table_add_range_partition", msname, mtname, psname, ptname, &mt, 
&pt);
+       int tp1, tp2 = getArgType(m, p, 5), tp3 = getArgType(m, p, 6);
+       ptr min = *getArgReference_ptr(s, p, 5), max = *getArgReference_ptr(s, 
p, 6);
 
-       if (ms)
-               mt = mvc_bind_table(sql, ms, mtname);
-       if (ps)
-               pt = mvc_bind_table(sql, ps, ptname);
-       if (mt && (mt->type != tt_merge_table && mt->type != tt_replica_table))
-               throw(SQL,"sql.alter_table_add_table",SQLSTATE(42S02) "ALTER 
TABLE: cannot add table '%s.%s' to table '%s.%s'", psname, ptname, msname, 
mtname);
-       if (mt && pt) {
-               char *msg;
-               node *n = cs_find_id(&mt->members, pt->base.id);
+       if(msg != MAL_SUCCEED)
+               return msg;
+       if(mt->type != tt_range_partition) {
+               throw(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: cannot add range partition into a %s table",
+                       (mt->type == tt_merge_table)?"merge":"list partition");
+       }
 
-               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);
-               if ((msg = rel_check_tables(mt, pt)) != NULL)
-                       return msg;
-               sql_trans_add_table(sql->session->tr, mt, pt);
-       } else if (mt) {
-               throw(SQL,"sql.alter_table_add_table",SQLSTATE(42S02) "ALTER 
TABLE: no such table '%s' in schema '%s'", ptname, psname);
-       } else {
-               throw(SQL,"sql.alter_table_add_table",SQLSTATE(42S02) "ALTER 
TABLE: no such table '%s' in schema '%s'", mtname, msname);
+       col = mt->part;
+       tp1 = col->type.type->localtype;
+       if(tp1 != tp2) {
+               throw(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: type of range minimum value is not the same as the partition's 
column");
+       } else if(tp1 != tp3) {
+               throw(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: type of range maximum value is not the same as the partition's 
column");
+       } else if(ATOMcmp(tp1, min, max) > 0) {
+               throw(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) 
"ALTER TABLE: minimum value is higher than maximum value");
        }
-       return MAL_SUCCEED;
+
+       /* TODO search for a conflicting partition */
+       sql_trans_add_range_partition(sql->session->tr, mt, pt, min, max);
+
+       return msg;
 }
 
 static char *
@@ -1308,6 +1353,20 @@ SQLalter_add_table(Client cntxt, MalBlkP
 }
 
 str
+SQLalter_add_range_partition(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci)
+{      mvc *sql = NULL;
+       str msg;
+       str sname = *getArgReference_str(stk, pci, 1);
+       char *mtname = SaveArgReference(stk, pci, 2);
+       char *psname = SaveArgReference(stk, pci, 3);
+       char *ptname = SaveArgReference(stk, pci, 4);
+
+       initcontext();
+       msg = alter_table_add_range_partition(sql, sname, mtname, psname, 
ptname, mb, stk, pci);
+       return msg;
+}
+
+str
 SQLalter_del_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) 
 {      mvc *sql = NULL;
        str msg;
diff --git a/sql/backends/monet5/sql_cat.h b/sql/backends/monet5/sql_cat.h
--- a/sql/backends/monet5/sql_cat.h
+++ b/sql/backends/monet5/sql_cat.h
@@ -61,6 +61,7 @@ sql5_export str SQLcreate_function(Clien
 sql5_export str SQLcreate_trigger(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci) ;
 sql5_export str SQLdrop_trigger(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci) ;
 sql5_export str SQLalter_add_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
+sql5_export str SQLalter_add_range_partition(Client cntxt, MalBlkPtr mb, 
MalStkPtr stk, InstrPtr pci);
 sql5_export str SQLalter_del_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 sql5_export str SQLalter_set_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 
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
@@ -511,7 +511,7 @@ typedef struct sql_part {
                        ptr *minvalue;
                        ptr *maxvalue;
                } range;
-       };
+       } part;
 } sql_part;
 
 typedef struct sql_table {
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -133,6 +133,9 @@ typedef struct expression {
 #define DDL_ALTER_TABLE_DEL_TABLE  64
 #define DDL_ALTER_TABLE_SET_ACCESS 65
 
+#define DDL_ALTER_TABLE_ADD_RANGE_PARTITION 66
+#define DDL_ALTER_TABLE_ADD_LIST_PARTITION  67
+
 #define DDL_EMPTY 100
 
 #define MAXOPS 22
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -7907,7 +7907,7 @@ rel_merge_table_rewrite(int *changes, mv
                sql_table *t = rel->l;
 
                if (isMergeTable(t)) {
-                       /* instantiate merge tabel */
+                       /* instantiate merge table */
                        sql_rel *nrel = NULL;
                        char *tname = t->base.name;
                        list *cols = NULL, *low = NULL, *high = NULL;
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
@@ -84,6 +84,34 @@ rel_alter_table(sql_allocator *sa, int c
        return rel;
 }
 
+static sql_rel *
+rel_alter_table_add_partition_range(sql_allocator *sa, char *sname, char 
*tname, char *sname2, char *tname2, int action, ptr min, ptr max)
+{
+       sql_rel *rel = rel_create(sa);
+       list *exps = new_exp_list(sa);
+       if(!rel || !exps)
+               return NULL;
+
+       append(exps, exp_atom_clob(sa, sname));
+       append(exps, exp_atom_clob(sa, tname));
+       assert((sname2 && tname2) || (!sname2 && !tname2));
+       if (sname2) {
+               append(exps, exp_atom_clob(sa, sname2));
+               append(exps, exp_atom_clob(sa, tname2));
+       }
+       append(exps, exp_atom_int(sa, action));
+       append(exps, exp_atom_ptr(sa, min));
+       append(exps, exp_atom_ptr(sa, max));
+       rel->l = NULL;
+       rel->r = NULL;
+       rel->op = op_ddl;
+       rel->flag = DDL_ALTER_TABLE_ADD_RANGE_PARTITION;
+       rel->exps = exps;
+       rel->card = CARD_MULTI;
+       rel->nrcols = 0;
+       return rel;
+}
+
 sql_rel *
 rel_list(sql_allocator *sa, sql_rel *l, sql_rel *r) 
 {
@@ -1346,7 +1374,7 @@ get_schema_name( mvc *sql, char *sname, 
 }
 
 static sql_rel *
-sql_alter_table(mvc *sql, dlist *qname, symbol *te)
+sql_alter_table(mvc *sql, dlist *qname, symbol *te, symbol *extra)
 {
        char *sname = qname_schema(qname);
        char *tname = qname_table(qname);
@@ -1386,9 +1414,39 @@ sql_alter_table(mvc *sql, dlist *qname, 
                if (te && (te->token == SQL_TABLE || te->token == 
SQL_DROP_TABLE)) {
                        char *ntname = te->data.lval->h->data.sval;
 
-                       /* TODO partition sname */
                        if (te->token == SQL_TABLE) {
-                               return rel_alter_table(sql->sa, 
DDL_ALTER_TABLE_ADD_TABLE, sname, tname, sname, ntname, 0);
+                               if(!extra)
+                                       return rel_alter_table(sql->sa, 
DDL_ALTER_TABLE_ADD_TABLE, sname, tname, sname, ntname, 0);
+                               if(extra->token == SQL_PARTITION_RANGE) {
+                                       sql_column *col =  t->part;
+                                       dlist* ll = extra->data.lval;
+                                       symbol* min = ll->h->data.sym, *max = 
ll->h->next->data.sym;
+                                       ptr real_min = NULL, real_max = NULL;
+
+                                       if(t->type != tt_range_partition) {
+                                               return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add range partition into a %s table",
+                                                               (t->type == 
tt_merge_table)?"merge":"list partition");
+                                       }
+
+                                       if(min->token == SQL_MINVALUE) {
+                                               atom* amin = 
atom_absolute_min(sql->sa, &(col->type));
+                                               real_min = (ptr) 
VALptr(&(amin->data));
+                                       } else {
+                                               AtomNode *anm = (AtomNode *) 
min;
+                                               real_min = (ptr) 
VALptr(&(anm->a->data));
+                                       }
+                                       if(max->token == SQL_MAXVALUE) {
+                                               atom* amax = 
atom_absolute_max(sql->sa, &(col->type));
+                                               real_max = (ptr) 
VALptr(&(amax->data));
+                                       } else {
+                                               AtomNode *an = (AtomNode *) max;
+                                               real_max = (ptr) 
VALptr(&(an->a->data));
+                                       }
+                                       return 
rel_alter_table_add_partition_range(sql->sa, sname, tname, sname, ntname, 0, 
real_min, real_max);
+                               } else if(extra->token == SQL_PARTITION_LIST) {
+
+                               }
+                               assert(0);
                        } else {
                                int drop_action = 
te->data.lval->h->next->data.i_val;
 
@@ -1409,7 +1467,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                        return rel_alter_table(sql->sa, 
DDL_ALTER_TABLE_SET_ACCESS, sname, tname, NULL, NULL, state);
                }
 
-               nt = dup_sql_table(sql->sa, t);
+               nt = dup_sql_table(sql->sa, t);
                if (!nt || (te && table_element(sql, te, s, nt, 1) == SQL_ERR)) 
                        return NULL;
 
@@ -2392,7 +2450,8 @@ rel_schemas(mvc *sql, symbol *s)
 
                ret = sql_alter_table(sql, 
                        l->h->data.lval,      /* table name */
-                       l->h->next->data.sym);/* table element */
+                       l->h->next->data.sym, /* table element */
+                       l->h->next->next->data.sym);
        }       break;
        case SQL_GRANT_ROLES:
        {
diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c
--- a/sql/server/sql_atom.c
+++ b/sql/server/sql_atom.c
@@ -1345,3 +1345,167 @@ atom_is_true( atom *a )
        }
        return 0;
 }
+
+atom*
+atom_absolute_min(sql_allocator *sa, sql_subtype* tpe)
+{
+       void *ret = NULL;
+
+       switch (tpe->type->eclass) {
+               case EC_BIT:
+               {
+                       bit bval = GDK_bit_min;
+                       ret = &bval;
+                       break;
+               }
+               case EC_POS:
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to