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

Reply via email to