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