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