Changeset: bace66e067ee for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bace66e067ee
Added Files:
        sql/server/sql_partition.c
        sql/server/sql_partition.h
        sql/test/merge-partitions/Tests/mergepart20.sql
Modified Files:
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_cat.c
        sql/include/sql_catalog.h
        sql/server/Makefile.ag
        sql/server/rel_propagate.c
        sql/server/rel_schema.c
        sql/server/rel_updates.c
        sql/server/rel_updates.h
        sql/server/sql_mvc.c
        sql/server/sql_parser.y
        sql/server/sql_semantic.c
        sql/storage/sql_catalog.c
        sql/storage/store.c
        sql/test/merge-partitions/Tests/All
Branch: merge-partitions
Log Message:

Making progress for expressions handling.

So far it compiles expressions, now they should be added in the relational plan.


diffs (truncated from 749 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
@@ -337,6 +337,8 @@ create_table_or_view(mvc *sql, char *sna
                if(isPartitionedByColumnTable(t) && c == t->part.pcol)
                        nt->part.pcol = copied;
        }
+       if(isPartitionedByExpressionTable(t))
+               nt->part.pexp->exp = sa_strdup(sql->session->tr->sa, 
t->part.pexp->exp);
        if(sql_trans_set_partition_table(sql->session->tr, nt))
                throw(SQL, "sql.catalog", SQLSTATE(42000) "CREATE TABLE: %s_%s: 
an internal error occurred", s->base.name, t->base.name);
 
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
@@ -18,7 +18,7 @@
 #include "sql_scenario.h"
 #include "sql_mvc.h"
 #include "sql_qc.h"
-#include "sql_optimizer.h"
+#include "sql_partition.h"
 #include "mal_namespace.h"
 #include "opt_prelude.h"
 #include "querylog.h"
@@ -210,7 +210,8 @@ alter_table_add_range_partition(mvc *sql
                goto finish;
        }
 
-       find_partition_type(&tpe, mt);
+       if((msg = find_partition_type(sql, &tpe, mt)))
+               goto finish;
        tp1 = tpe.type->localtype;
        if(ATOMcmp(TYPE_str, min, ATOMnilptr(TYPE_str))) {
                if (tp1 == TYPE_str) {
@@ -355,7 +356,8 @@ alter_table_add_value_partition(mvc *sql
                goto finish;
        }
 
-       find_partition_type(&tpe, mt);
+       if((msg = find_partition_type(sql, &tpe, mt)))
+               goto finish;
        tp1 = tpe.type->localtype;
        ninserts = pci->argc - pci->retc - 6;
        if(ninserts <= 0 && !with_nills) {
@@ -367,7 +369,6 @@ alter_table_add_value_partition(mvc *sql
                size_t len = 0;
                str next = *getArgReference_str(stk, pci, i);
                sql_part_value *nextv = NULL;
-               void *prev;
 
                if(escaped) {
                        GDKfree(escaped);
@@ -405,7 +406,7 @@ alter_table_add_value_partition(mvc *sql
                memcpy(nextv->value, pnext, len);
                nextv->length = len;
 
-               if((prev = list_append_sorted(values, nextv, 
sql_values_list_element_validate_and_insert)) != NULL) {
+               if(list_append_sorted(values, nextv, 
sql_values_list_element_validate_and_insert) != NULL) {
                        GDKfree(pnext);
                        msg = 
createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
                                                                        "ALTER 
TABLE: there are duplicated values in the list");
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
@@ -541,6 +541,12 @@ typedef struct sql_part {
        } part;
 } sql_part;
 
+typedef struct sql_expression {
+       sql_subtype type;
+       char *exp;
+       list *cols;
+} sql_expression;
+
 typedef struct sql_table {
        sql_base base;
        sht type;               /* table, view, etc */
@@ -566,8 +572,8 @@ typedef struct sql_table {
 
        struct sql_table *p;     /* The table is part of this merge table */
        union {
-               struct sql_column *pcol;  /* If it is partitioned on a column */
-               struct sql_subfunc *pexp; /* If it is partitioned by an 
expression */
+               struct sql_column *pcol; /* If it is partitioned on a column */
+               struct sql_expression *pexp; /* If it is partitioned by an 
expression */
        } part;
 } sql_table;
 
@@ -622,8 +628,6 @@ extern node *list_find_name(list *l, con
 extern node *list_find_id(list *l, int id);
 extern node *list_find_base_id(list *l, int id);
 
-extern void find_partition_type(sql_subtype *res, sql_table *t);
-
 extern sql_key *find_sql_key(sql_table *t, const char *kname);
 
 extern sql_idx *find_sql_idx(sql_table *t, const char *kname);
diff --git a/sql/server/Makefile.ag b/sql/server/Makefile.ag
--- a/sql/server/Makefile.ag
+++ b/sql/server/Makefile.ag
@@ -31,6 +31,7 @@ lib_sqlserver = {
                sql_symbol.c \
                sql_scan.c \
                sql_parser.y \
+               sql_partition.c \
                sql_mvc.c \
                sql_env.c \
                sql_privileges.c \
@@ -58,5 +59,5 @@ lib_sqlserver = {
                rel_updates.h rel_psm.h rel_xml.h sql_atom.h sql_datetime.h \
                sql_decimal.h sql_env.h sql_mvc.h sql_parser.h \
                sql_privileges.h sql_qc.h sql_scan.h \
-               sql_semantic.h sql_symbol.h
+               sql_semantic.h sql_symbol.h sql_partition.h
 }
diff --git a/sql/server/rel_propagate.c b/sql/server/rel_propagate.c
--- a/sql/server/rel_propagate.c
+++ b/sql/server/rel_propagate.c
@@ -15,6 +15,7 @@
 #include "rel_select.h"
 #include "rel_updates.h"
 #include "sql_mvc.h"
+#include "sql_partition.h"
 
 extern sql_rel *rel_list(sql_allocator *sa, sql_rel *l, sql_rel *r);
 
@@ -68,13 +69,14 @@ rel_alter_table_add_partition_range(mvc*
        list *exps = new_exp_list(sql->sa);
        sql_exp *exception, *aggr, *anti_exp = NULL, *anti_le, *e1, *e2, 
*anti_nils;
        sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count", 
NULL);
-       char buf[BUFSIZ], *pmin = min ? atom2string(sql->sa, min): NULL, *pmax 
= max ? atom2string(sql->sa, max) : NULL;
+       char buf[BUFSIZ], *pmin = min ? atom2string(sql->sa, min): NULL, *pmax 
= max ? atom2string(sql->sa, max) : NULL, *err;
        sql_subtype tpe;
 
        if(!rel_psm || !exps)
                return NULL;
 
-       find_partition_type(&tpe, mt);
+       if((err = find_partition_type(sql, &tpe, mt)))
+               return sql_error(sql, 02,"%s", err);
 
        anti_rel = rel_basetable(sql, pt, tname2);
        anti_le = rel_get_anti_expression(anti_rel, mt);
@@ -149,13 +151,14 @@ rel_alter_table_add_partition_list(mvc *
        sql_exp *exception, *aggr, *anti_exp, *anti_le, *anti_nils;
        sql_subaggr *cf = sql_bind_aggr(sql->sa, sql->session->schema, "count", 
NULL);
        int with_nills = 0;
-       char buf[BUFSIZ];
+       char buf[BUFSIZ], *err;
        sql_subtype tpe;
 
        if(!rel_psm || !exps)
                return NULL;
 
-       find_partition_type(&tpe, mt);
+       if((err = find_partition_type(sql, &tpe, mt)))
+               return sql_error(sql, 02,"%s", err);
 
        anti_rel = rel_basetable(sql, pt, tname2);
        anti_le = rel_get_anti_expression(anti_rel, mt);
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
@@ -18,6 +18,7 @@
 #include "rel_propagate.h"
 #include "sql_parser.h"
 #include "sql_privileges.h"
+#include "sql_partition.h"
 
 #define qname_index(qname) qname_table(qname)
 #define qname_func(qname) qname_table(qname)
@@ -901,13 +902,15 @@ table_element(mvc *sql, symbol *s, sql_s
 }
 
 static int
-create_partition_definition(mvc *sql, sql_table *t, int tt, symbol* 
partition_def)
+create_partition_definition(mvc *sql, sql_table *t, int tt, symbol 
*partition_def)
 {
+       char *err = NULL;
+
        if(partition_def) {
+               dlist *list = partition_def->data.lval;
+               symbol *type = list->h->next->data.sym;
+               dlist *list2 = type->data.lval;
                if(tt == tt_list_partition_col || tt == tt_range_partition_col) 
{
-                       dlist *list = partition_def->data.lval;
-                       symbol *type = list->h->next->data.sym;
-                       dlist *list2 = type->data.lval;
                        str colname = list2->h->data.sval;
                        node *n;
                        int sql_ec;
@@ -924,7 +927,7 @@ create_partition_definition(mvc *sql, sq
                        }
                        sql_ec = t->part.pcol->type.type->eclass;
                        if(!(sql_ec == EC_BIT || EC_VARCHAR(sql_ec) || 
EC_TEMP(sql_ec) || EC_NUMBER(sql_ec) || sql_ec == EC_BLOB)) {
-                               char *err = 
sql_subtype_string(&(t->part.pcol->type));
+                               err = sql_subtype_string(&(t->part.pcol->type));
                                if (!err) {
                                        sql_error(sql, 02, SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
                                } else {
@@ -934,8 +937,15 @@ create_partition_definition(mvc *sql, sq
                                return SQL_ERR;
                        }
                } else if(tt == tt_list_partition_exp || tt == 
tt_range_partition_exp) {
-                       sql_error(sql, 02, SQLSTATE(42000) "CREATE MERGE TABLE: 
partition by expression not supported at the moment");
-                       return SQL_ERR;
+                       char *query = symbol2string(sql, list2->h->data.sym, 
&err);
+                       if (!query) {
+                               (void) sql_error(sql, 02, SQLSTATE(42000) 
"CREATE MERGE TABLE: error compiling expression '%s'", err?err:"");
+                               if (err) _DELETE(err);
+                               return SQL_ERR;
+                       }
+                       t->part.pexp = SA_ZNEW(sql->sa, sql_expression);
+                       t->part.pexp->exp = sa_strdup(sql->sa, query);
+                       _DELETE(query);
                }
        }
        return SQL_OK;
@@ -993,7 +1003,7 @@ rel_create_table(mvc *sql, sql_schema *s
                dnode *n;
                dlist *columns = table_elements_or_subquery->data.lval;
                sql_table *t;
-              
+
                if (tt == tt_remote) {
                        if (!mapiuri_valid(loc))
                                return sql_error(sql, 02, SQLSTATE(42000) 
"CREATE TABLE: incorrect uri '%s' for remote table '%s'", loc, name);
@@ -1436,6 +1446,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                if(!extra)
                                        return rel_alter_table(sql->sa, 
DDL_ALTER_TABLE_ADD_TABLE, sname, tname, sname, ntname, 0);
                                if(extra->token == SQL_PARTITION_RANGE) {
+                                       char *err;
                                        sql_subtype tpe;
                                        dlist* ll = extra->data.lval;
                                        symbol* min = ll->h->data.sym, *max = 
ll->h->next->data.sym;
@@ -1447,7 +1458,8 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                                                (t->type == 
tt_merge_table)?"merge":"list partition");
                                        }
 
-                                       find_partition_type(&tpe, t);
+                                       if((err = find_partition_type(sql, 
&tpe, t)))
+                                               return sql_error(sql, 02, "%s", 
err);
 
                                        if(min && min->token == SQL_MINVALUE) {
                                                amin = 
atom_absolute_min(sql->sa, &tpe);
@@ -1532,7 +1544,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                sql_column *c = n->data;
                                if (c->def) {
                                        char *d = sql_message("select %s;", 
c->def);
-                                       e = rel_parse_val(sql, d, sql->emode);
+                                       e = rel_parse_val(sql, d, sql->emode, 
NULL);
                                        _DELETE(d);
                                } else {
                                        e = exp_atom(sql->sa, 
atom_general(sql->sa, &c->type, NULL));
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -25,7 +25,7 @@ insert_value(mvc *sql, sql_column *c, sq
                return exp_atom(sql->sa, atom_general(sql->sa, &c->type, NULL));
        } else if (s->token == SQL_DEFAULT) {
                if (c->def) {
-                       sql_exp *e = rel_parse_val(sql, sa_message(sql->sa, 
"select CAST(%s AS %s);", c->def, c->type.type->sqlname), sql->emode);
+                       sql_exp *e = rel_parse_val(sql, sa_message(sql->sa, 
"select CAST(%s AS %s);", c->def, c->type.type->sqlname), sql->emode, NULL);
                        if (!e || (e = rel_check_type(sql, &c->type, e, 
type_equal)) == NULL)
                                return NULL;
                        return e;
@@ -352,7 +352,7 @@ rel_inserts(mvc *sql, sql_table *t, sql_
 
                                                if (c->def) {
                                                        char *q = 
sa_message(sql->sa, "select %s;", c->def);
-                                                       e = rel_parse_val(sql, 
q, sql->emode);
+                                                       e = rel_parse_val(sql, 
q, sql->emode, NULL);
                                                        if (!e || (e = 
rel_check_type(sql, &c->type, e, type_equal)) == NULL)
                                                                return NULL;
                                                } else {
@@ -1021,7 +1021,7 @@ update_table(mvc *sql, dlist *qname, dli
                                        char *colname = 
assignment->h->next->data.sval;
                                        sql_column *col = mvc_bind_column(sql, 
t, colname);
                                        if (col->def) {
-                                               v = rel_parse_val(sql, 
sa_message(sql->sa, "select CAST(%s AS %s);", col->def, 
col->type.type->sqlname), sql->emode);
+                                               v = rel_parse_val(sql, 
sa_message(sql->sa, "select CAST(%s AS %s);", col->def, 
col->type.type->sqlname), sql->emode, NULL);
                                        } else {
                                                return sql_error(sql, 02, 
SQLSTATE(42000) "UPDATE: column '%s' has no valid default value", 
col->base.name);
                                        }
@@ -1727,7 +1727,7 @@ copyto(mvc *sql, symbol *sq, str filenam
 }
 
 sql_exp *
-rel_parse_val(mvc *m, char *query, char emode)
+rel_parse_val(mvc *m, char *query, char emode, sql_table *from)
 {
        mvc o = *m;
        sql_exp *e = NULL;
@@ -1785,6 +1785,8 @@ rel_parse_val(mvc *m, char *query, char 
                if (sn->selection->h->data.sym->token == SQL_COLUMN) {
                        int is_last = 0;
                        sql_rel *r = NULL;
+                       if(from)
+                               r = rel_basetable(m, from, from->base.name);
                        symbol* sq = 
sn->selection->h->data.sym->data.lval->h->data.sym;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to