Changeset: 353bbbcccaf4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=353bbbcccaf4
Modified Files:
sql/backends/monet5/sql.c
sql/backends/monet5/sql_cat.c
sql/include/sql_catalog.h
sql/server/rel_psm.c
sql/server/rel_schema.c
sql/server/rel_schema.h
sql/server/sql_parser.h
sql/server/sql_parser.y
sql/storage/store.c
Branch: merge-partitions
Log Message:
First steps into merge tables partitions by column using list or range of values
diffs (truncated from 421 to 300 lines):
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -331,10 +331,12 @@ create_table_or_view(mvc *sql, char *sna
nt = sql_trans_create_table(sql->session->tr, s, t->base.name,
t->query, t->type, t->system, temp, t->commit_action, t->sz);
for (n = t->columns.set->h; n; n = n->next) {
- sql_column *c = n->data;
- if (mvc_copy_column(sql, nt, c) == NULL)
+ sql_column *c = n->data, *copied = mvc_copy_column(sql, nt, c);
+
+ if (copied == NULL)
throw(SQL, "sql.catalog", SQLSTATE(42000) "CREATE
TABLE: %s_%s_%s conflicts", s->base.name, t->base.name, c->base.name);
-
+ if(c == t->part)
+ nt->part = copied;
}
if (t->idxs.set) {
for (n = t->idxs.set->h; n; n = n->next) {
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
@@ -163,7 +163,7 @@ alter_table_set_access(mvc *sql, char *s
if (s)
t = mvc_bind_table(sql, s, tname);
if (t) {
- if (t->type == tt_merge_table)
+ if (isMergeTable(t))
throw(SQL,"sql.alter_table_set_access",SQLSTATE(42S02)
"ALTER TABLE: read only MERGE TABLES are not supported");
if (t->access != access) {
if (access && table_has_updates(sql->session->tr, t))
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,6 +103,10 @@
#define EXCLUDE_TIES 3
#define EXCLUDE_NO_OTHERS 4
+#define PARTITION_NONE 0
+#define PARTITION_RANGE 1
+#define PARTITION_LIST 2
+
#define cur_user 1
#define cur_role 2
@@ -122,7 +126,9 @@ typedef enum temp_t {
SQL_MERGE_TABLE = 4,
SQL_STREAM = 5,
SQL_REMOTE = 6,
- SQL_REPLICA_TABLE = 7
+ SQL_REPLICA_TABLE = 7,
+ SQL_MERGE_LIST_PARTITION = 8,
+ SQL_MERGE_RANGE_PARTITION = 9
} temp_t;
typedef enum comp_type {
@@ -478,12 +484,14 @@ typedef enum table_types {
tt_merge_table = 3, /* multiple tables form one table */
tt_stream = 4, /* stream */
tt_remote = 5, /* stored on a remote server */
- tt_replica_table = 6 /* multiple replica of the same table */
+ tt_replica_table = 6, /* multiple replica of the same table */
+ tt_list_partition = 7,
+ tt_range_partition = 8
} table_types;
#define isTable(x) (x->type==tt_table)
#define isView(x) (x->type==tt_view)
-#define isMergeTable(x) (x->type==tt_merge_table)
+#define isMergeTable(x) (x->type==tt_merge_table ||
x->type==tt_list_partition || x->type==tt_range_partition)
#define isStream(x) (x->type==tt_stream)
#define isRemote(x) (x->type==tt_remote)
#define isReplicaTable(x) (x->type==tt_replica_table)
@@ -497,6 +505,13 @@ typedef enum table_types {
typedef struct sql_part {
sql_base base;
struct sql_table *t; /* cached value */
+ union {
+ bat values;
+ struct sql_range {
+ ptr *minvalue;
+ ptr *maxvalue;
+ } range;
+ };
} sql_part;
typedef struct sql_table {
@@ -522,6 +537,7 @@ typedef struct sql_table {
struct sql_schema *s;
struct sql_table *p; /* The table is part of this merge table */
struct sql_table *po; /* the outer transactions table */
+ struct sql_column *part; /* if it is partitioned on a column */
} sql_table;
typedef struct res_col {
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -214,7 +214,7 @@ rel_psm_declare_table(mvc *sql, dnode *n
assert(n->next->next->next->type == type_int);
- rel = rel_create_table(sql, cur_schema(sql), SQL_DECLARED_TABLE, NULL,
name, n->next->next->data.sym, n->next->next->next->data.i_val, NULL, 0);
+ rel = rel_create_table(sql, cur_schema(sql), SQL_DECLARED_TABLE, NULL,
name, n->next->next->data.sym, n->next->next->next->data.i_val, NULL, 0, NULL);
if (!rel || rel->op != op_ddl || rel->flag != DDL_CREATE_TABLE)
return 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
@@ -187,8 +187,10 @@ mvc_create_table_as_subquery( mvc *sql,
{
int tt =(temp == SQL_REMOTE)?tt_remote:
(temp == SQL_STREAM)?tt_stream:
- (temp == SQL_MERGE_TABLE)?tt_merge_table:
- (temp == SQL_REPLICA_TABLE)?tt_replica_table:tt_table;
+ (temp == SQL_MERGE_TABLE)?tt_merge_table:
+ (temp == SQL_REPLICA_TABLE)?tt_replica_table:
+ (temp == SQL_MERGE_LIST_PARTITION)?tt_list_partition:
+ (temp == SQL_MERGE_RANGE_PARTITION)?tt_range_partition:tt_table;
sql_table *t = mvc_create_table(sql, s, tname, tt, 0,
SQL_DECLARED_TABLE, commit_action, -1);
if (as_subquery( sql, t, sq, column_spec, "CREATE TABLE") != 0)
@@ -895,8 +897,28 @@ table_element(mvc *sql, symbol *s, sql_s
return res;
}
+static int
+create_partition_column(mvc *sql, int tt, dlist* partition, sql_table *t) {
+ if((tt == tt_list_partition || tt == tt_range_partition) && partition) {
+ str colname = partition->h->next->data.sval;
+ node *n;
+ for (n = t->columns.set->h; n ; n = n->next) {
+ sql_column *col = n->data;
+ if(strcmp(col->base.name, colname)) {
+ t->part = col;
+ break;
+ }
+ }
+ if(!t->part) {
+ sql_error(sql, 02, SQLSTATE(42000) "CREATE MERGE TABLE:
the partition column '%s' is not part of the table", colname);
+ return SQL_ERR;
+ }
+ }
+ return SQL_OK;
+}
+
sql_rel *
-rel_create_table(mvc *sql, sql_schema *ss, int temp, const char *sname, const
char *name, symbol *table_elements_or_subquery, int commit_action, const char
*loc, int if_not_exists)
+rel_create_table(mvc *sql, sql_schema *ss, int temp, const char *sname, const
char *name, symbol *table_elements_or_subquery, int commit_action, const char
*loc, int if_not_exists, dlist* partition)
{
sql_schema *s = NULL;
@@ -905,8 +927,10 @@ rel_create_table(mvc *sql, sql_schema *s
int create = (!instantiate && !deps);
int tt = (temp == SQL_REMOTE)?tt_remote:
(temp == SQL_STREAM)?tt_stream:
- (temp == SQL_MERGE_TABLE)?tt_merge_table:
- (temp == SQL_REPLICA_TABLE)?tt_replica_table:tt_table;
+ (temp == SQL_MERGE_TABLE)?tt_merge_table:
+ (temp == SQL_REPLICA_TABLE)?tt_replica_table:
+ (temp == SQL_MERGE_LIST_PARTITION)?tt_list_partition:
+ (temp ==
SQL_MERGE_RANGE_PARTITION)?tt_range_partition:tt_table;
(void)create;
if (sname && !(s = mvc_bind_schema(sql, sname)))
@@ -961,6 +985,10 @@ rel_create_table(mvc *sql, sql_schema *s
if (res == SQL_ERR)
return NULL;
}
+
+ if(create_partition_column(sql, tt, partition, t) != SQL_OK)
+ return NULL;
+
temp = (tt == tt_table)?temp:SQL_PERSIST;
return rel_table(sql, DDL_CREATE_TABLE, sname, t, temp);
} else { /* [col name list] as subquery with or without data */
@@ -976,8 +1004,9 @@ rel_create_table(mvc *sql, sql_schema *s
if (!sq)
return NULL;
- if ((tt == tt_merge_table || tt == tt_remote || tt ==
tt_replica_table) && with_data)
- return sql_error(sql, 02, SQLSTATE(42000) "CREATE
TABLE: cannot create %s table 'with data'", tt == tt_merge_table?"MERGE
TABLE":tt == tt_remote?"REMOTE TABLE":"REPLICA TABLE");
+ if ((tt == tt_merge_table || tt == tt_list_partition || tt ==
tt_range_partition || tt == tt_remote || tt == tt_replica_table) && with_data)
+ return sql_error(sql, 02, SQLSTATE(42000) "CREATE
TABLE: cannot create %s table 'with data'",
+ tt == tt_merge_table?"MERGE TABLE":tt ==
tt_remote?"REMOTE TABLE":tt == tt_list_partition?"LIST PARTITION TABLE":tt ==
tt_range_partition?"RANGE PARTITION TABLE":"REPLICA TABLE");
/* create table */
if ((t = mvc_create_table_as_subquery( sql, sq, s, name,
column_spec, temp, commit_action)) == NULL) {
@@ -985,6 +1014,9 @@ rel_create_table(mvc *sql, sql_schema *s
return NULL;
}
+ if(create_partition_column(sql, tt, partition, t) != SQL_OK)
+ return NULL;
+
/* insert query result into this table */
temp = (tt == tt_table)?temp:SQL_PERSIST;
res = rel_table(sql, DDL_CREATE_TABLE, sname, t, temp);
@@ -2314,7 +2346,8 @@ rel_schemas(mvc *sql, symbol *s)
ret = rel_create_table(sql, cur_schema(sql), temp, sname, name,
l->h->next->next->data.sym,
l->h->next->next->next->data.i_val,
l->h->next->next->next->next->data.sval,
-
l->h->next->next->next->next->next->data.i_val); /* if not exists */
+
l->h->next->next->next->next->next->data.i_val, /* if not exists */
+
l->h->next->next->next->next->next->next->data.lval);
} break;
case SQL_CREATE_VIEW:
{
diff --git a/sql/server/rel_schema.h b/sql/server/rel_schema.h
--- a/sql/server/rel_schema.h
+++ b/sql/server/rel_schema.h
@@ -14,7 +14,7 @@
extern sql_rel *rel_schemas(mvc *sql, symbol *sym);
-extern sql_rel *rel_create_table(mvc *sql, sql_schema *ss, int temp, const
char *sname, const char *name, symbol *table_elements_or_subquery, int
commit_action, const char *loc, int if_not_exists);
+extern sql_rel *rel_create_table(mvc *sql, sql_schema *ss, int temp, const
char *sname, const char *name, symbol *table_elements_or_subquery, int
commit_action, const char *loc, int if_not_exists, dlist* partition);
extern sql_rel *rel_list(sql_allocator *sa, sql_rel *l, sql_rel *r);
extern sql_table * mvc_create_table_as_subquery( mvc *sql, sql_rel *sq,
sql_schema *s, const char *tname, dlist *column_spec, int temp, int
commit_action );
diff --git a/sql/server/sql_parser.h b/sql/server/sql_parser.h
--- a/sql/server/sql_parser.h
+++ b/sql/server/sql_parser.h
@@ -180,7 +180,10 @@ typedef enum tokens {
SQL_XMLQUERY,
SQL_XMLTEXT,
SQL_XMLVALIDATE,
- SQL_XMLNAMESPACES
+ SQL_XMLNAMESPACES,
+ SQL_MERGE_PARTITION,
+ SQL_PARTITION_LIST,
+ SQL_PARTITION_RANGE
} tokens;
typedef enum jt {
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -300,6 +300,12 @@ int yydebug=1;
XML_value_expression
XML_primary
opt_comma_string_value_expression
+ opt_partition_by
+ opt_as_partition
+ opt_partition_spec
+ partition_list_value
+ partition_range_from
+ partition_range_to
%type <type>
data_type
@@ -432,6 +438,7 @@ int yydebug=1;
window_frame_between
routine_designator
drop_routine_designator
+ partition_list
%type <i_val>
any_all_some
@@ -483,6 +490,7 @@ int yydebug=1;
window_frame_units
window_frame_exclusion
subgeometry_type
+ opt_partition_type
%type <l_val>
lngval
@@ -1052,10 +1060,11 @@ alter_statement:
append_list(l, $3);
append_symbol(l, $6);
$$ = _symbol_create_list( SQL_ALTER_TABLE, l ); }
- | ALTER TABLE qname ADD TABLE qname
+ | ALTER TABLE qname ADD TABLE qname opt_as_partition
{ dlist *l = L();
append_list(l, $3);
append_symbol(l, _symbol_create_list( SQL_TABLE, $6));
+ append_symbol(l, $7);
$$ = _symbol_create_list( SQL_ALTER_TABLE, l ); }
| ALTER TABLE qname ALTER alter_table_element
{ dlist *l = L();
@@ -1342,7 +1351,7 @@ table_opt_storage:
;
table_def:
- TABLE if_not_exists qname table_content_source table_opt_storage
+ TABLE if_not_exists qname table_content_source table_opt_storage
{ int commit_action = CA_COMMIT;
dlist *l = L();
@@ -1353,6 +1362,7 @@ table_def:
append_string(l, NULL);
append_int(l, $2);
append_list(l, $5);
+ append_list(l, NULL); /* only used for merge table */
$$ = _symbol_create_list( SQL_CREATE_TABLE, l ); }
| TABLE if_not_exists qname FROM sqlLOADER func_ref
{
@@ -1371,10 +1381,12 @@ table_def:
append_int(l, commit_action);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list