Changeset: 58e31783ae0f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=58e31783ae0f
Modified Files:
monetdb5/modules/mal/array.mx
sql/server/rel_dump.c
sql/server/rel_exp.c
sql/server/rel_select.c
sql/test/sciql/Tests/teleios_noa_bsm.sql
Branch: SciQL-2
Log Message:
handle non-rectangular array tiles
- accept either interval tile range, or point tile ragnes, no mix of them
- multiple tile ranges are appended to e_column->f, thus e_column->f list can
have more than 3 items.
- to distinguish a point range from an interval range: a point range only has
one expr., while an interval range has three
array.mx:
- save the values for the error message, since the lists are freed in
AGGR_CLEANUP
- disable the check on (max - min + 1 = size), since it only holds for stepsize
= 1.
maybe we should just remove this check, since we don't have step size in the
tiling aggr impl. functions, do we?
teleios_noa_bsm.sql:
now we can get rid of the workarounds
more tests needed...
diffs (truncated from 389 to 300 lines):
diff --git a/monetdb5/modules/mal/array.mx b/monetdb5/modules/mal/array.mx
--- a/monetdb5/modules/mal/array.mx
+++ b/monetdb5/modules/mal/array.mx
@@ -658,8 +658,9 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
}
dSize[i] = *(int*)getArgReference(stk,pci,2+i*3+2);
if (dSize[i] <= 0) {
+ int sz = (int) dSize[i];
AGGR_CLEANUP();
- throw(MAL, "array.@4", "size of dimension %d (%d) must
not be <= 0", i, (int) dSize[i]);
+ throw(MAL, "array.@4", "size of dimension %d (%d) must
not be <= 0", i, sz);
}
arrsze *= dSize[i];
}
@@ -751,29 +752,34 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
BBPunfix(slice->batCacheid);
if (bDimsT[i][p] != dMin[i]) {
+ int di = (int) bDimsT[i][p], mi = (int)
dMin[i];
AGGR_CLEANUP();
throw(MAL, "array.@4", "first value of
slice "BUNFMT" of dimension %d (%d) is not the minimum (%d)",
- p / arrsze, i, (int)
bDimsT[i][p], (int) dMin[i]);
+ p / arrsze, i, di, mi);
}
if (bDimsT[i][r-1] != dMax[i]) {
+ int di = (int) bDimsT[i][r-1], ma =
(int) dMax[i];
AGGR_CLEANUP();
throw(MAL, "array.@4", "last value of
slice "BUNFMT" of dimension %d (%d) is not the maximum (%d)",
- p / arrsze, i, (int)
bDimsT[i][r-1], (int) dMax[i]);
+ p / arrsze, i, di, ma);
}
}
}
if (dMin[i] > dMax[i]) {
+ int mi = (int) dMin[i], ma = (int) dMax[i];
AGGR_CLEANUP();
throw(MAL, "array.@4", "minimum value of dimension BAT
%d (%d) must not be larger than its maximum value (%d)",
- i, (int) dMin[i], (int) dMax[i]);
+ i, mi, ma);
}
+ /*
if ((int) (dMax[i] - dMin[i] + 1) != dSize[i]) {
+ int rng = (int) (dMax[i] - dMin[i] + 1), sz = dSize[i];
AGGR_CLEANUP();
throw(MAL, "array.@4", "range of dimension BAT %d (%d)
does not match its size (%d)",
- i, (int) (dMax[i] - dMin[i] + 1), dSize[i]);
+ i, rng, sz);
}
-
+ */
arrsze /= dSize[i];
assert(arrsze);
}
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -153,7 +153,7 @@ exp_print(mvc *sql, stream *fout, sql_ex
if (e->f) { /* the dimension constraints */
list *range = NULL;
- assert(list_length(e->f) == 3);
+ assert(list_length(e->f) >= 3);
/* If a slicing has been applied on this dimension,
print the sliced range; otherwise the original range */
range = list_length(((list*)e->f)->h->next->data) ?
((list*)e->f)->h->next->data : ((list*)e->f)->h->data;
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -397,7 +397,7 @@ exp_column(sql_allocator *sa, char *rnam
if (drngs) { /* dimension ranges */
node *n = NULL;
- assert(list_length(drngs) == 3);
+ assert(list_length(drngs) >= 3);
e->f = sa_list(sa);
n = drngs->h;
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -818,7 +818,7 @@ rel_arrayslice(mvc *sql, sql_table *t, c
sf = sql_bind_func_(sql->sa, mvc_bind_schema(sql, "sys"),
"array_slice", exps_subtype(slc_args), F_FILT);
if (!sf)
- return sql_error(sql, 02, "failed to bind to the SQL
function \"array_slice\"");
+ return sql_error(sql, 02, "failed to bind to the SciQL
function \"array_slice\"");
/* apply our array_slice filter function on all columns of the
sliced array */
for (cn = cols->h; cn; cn = cn->next) {
@@ -2389,7 +2389,7 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
* it as an expression; otherwise get the step value from the
dimension range */
exp_os_ste = (dlist_length(dn->data.lval) == 3) ?
rel_check_type(sql, exp_subtype(d_rng->h->next->data),
rel_value_exp(sql, rel, dn->data.lval->h->next->data.sym, sql_where, ek),
type_cast) :
- exp_copy(sql->sa, d_rng->h->next->data);
+ (dlist_length(dn->data.lval) == 2)? exp_copy(sql->sa,
d_rng->h->next->data) : NULL;
/* array tiling range stop, which, in case of a single
<index_term>, is
* just 'start+step' to make the range only include '0'.
@@ -2401,10 +2401,7 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
* an exp_atom with "0" if not specified (case SQL_COLUMN),
and
* append it to 'offsets'.
*/
- if (dlist_length(dn->data.lval) == 1) {
- exp_os_sto = exp_binop(sql->sa, exp_copy(sql->sa,
exp_os_sta), exp_copy(sql->sa, exp_os_ste),
- sql_bind_func(sql->sa,
sql->session->schema, "sql_add", st, st, F_FUNC));
- } else {
+ if (dlist_length(dn->data.lval) > 1) {
sym_tsto = (dlist_length(dn->data.lval) == 2) ?
dn->data.lval->h->next->data.sym : dn->data.lval->h->next->next->data.sym;
switch (sym_tsto->token) {
case SQL_COLUMN: /* '<column>' */
@@ -2438,9 +2435,13 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
return sql_error(sql, 02, "SELECT:
expressions in array tiling specification other than \"<column> [ '+' | '-'
<exp> ]\" are not supported yet");
}
}
+
append(offsets, exp_os_sta);
- append(offsets, exp_os_ste);
- append(offsets, exp_os_sto);
+ if (exp_os_ste != NULL) {
+ assert(exp_os_sto != NULL);
+ append(offsets, exp_os_ste);
+ append(offsets, exp_os_sto);
+ }
((list*)exp->f)->h->next->next->data = offsets;
}
@@ -2451,7 +2452,9 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
/* This dimension has no tiling range, i.e., the '[*]'
case or an
* omitted dimension. Use the slicing/original range
as the tiling
* range to get the whole column included in a tile */
- ((list*)ce->f)->h->next->next->data =
list_length(((list*)ce->f)->h->next->data) ? ((list*)ce->f)->h->next->data :
((list*)ce->f)->h->data;
+ ((list*)ce->f)->h->next->next->data =
+ list_length(((list*)ce->f)->h->next->data) > 0 ?
+ ((list*)ce->f)->h->next->data :
((list*)ce->f)->h->data;
}
}
@@ -4297,7 +4300,7 @@ add_columns(list *exps, sql_exp *exp)
static sql_exp *
_rel_tiling_aggr(mvc *sql, sql_rel **rel, sql_rel *groupby, int distinct, char
*aggrstr, symbol *sym, int f)
{
- sql_exp *exp = NULL, *re_sta = NULL, *re_ste = NULL, *re_sto = NULL,
**dim = NULL, **oss = NULL;
+ sql_exp *exp = NULL, *re_sta = NULL, *re_ste = NULL, *re_sto = NULL,
**dim = NULL;
sql_exp **os_sta = NULL, **os_ste = NULL, **os_sto = NULL; /*
start/step/stop of the OffSet */
sql_exp **nrep = NULL, **ngrp = NULL, **dsize = NULL;
sql_subfunc *sf = NULL;
@@ -4342,11 +4345,10 @@ static sql_exp *
os_sta = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
os_ste = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
os_sto = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
- oss = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
dsize = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
nrep = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
ngrp = SA_NEW_ARRAY(sql->sa, sql_exp*, t->valence);
- if (!dim || !os_sta || !os_ste || !os_sto || !oss || !dsize || !nrep ||
!ngrp) {
+ if (!dim || !os_sta || !os_ste || !os_sto || !dsize || !nrep || !ngrp) {
return sql_error(sql, 02, "SELECT: failed to allocate space");
}
@@ -4355,9 +4357,7 @@ static sql_exp *
/* get all groupby dimension columns, and the ranges of each dimension
and the tile on it */
for (cn = ((list*)groupby->r)->h, i = 0; cn; cn = cn->next, i++) {
-
dim[i] = cn->data;
- assert(list_length(dim[i]->f) == 3);
/* If the dimension has been sliced, use the sliced range;
otherwise the original range */
rng = list_length(((list*)dim[i]->f)->h->next->data) ?
((list*)dim[i]->f)->h->next->data : ((list*)dim[i]->f)->h->data;
@@ -4382,8 +4382,8 @@ static sql_exp *
rng = ((list*)dim[i]->f)->h->next->next->data;
os_sta[i] = rng->h->data;
- os_ste[i] = rng->h->next->data;
- os_sto[i] = rng->h->next->next->data;
+ os_ste[i] = list_length(rng)==3?rng->h->next->data:NULL;
+ os_sto[i] = list_length(rng)==3?rng->h->next->next->data:NULL;
}
/* Compute the repeatings, see the formula in rel_schema.c.
@@ -4392,29 +4392,31 @@ static sql_exp *
for (i = 0; i < t->valence; i++)
nrep[i] = ngrp[i] = exp_atom_int(sql->sa, 1);
for (i = 0; i < t->valence; i++){
- if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"sql_sub", exp_subtype(os_sto[i]), exp_subtype(os_sta[i]), F_FUNC)))
- return sql_error(sql, 02, "failed to bind to the SQL
function \"-\"");
- exp = exp_binop(sql->sa, os_sto[i], os_sta[i], sf);
-
- if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"sql_div", &st_flt, &st_flt, F_FUNC)))
- return sql_error(sql, 02, "failed to bind to the SQL
function \"/\"");
- exp = exp_binop(sql->sa,
- rel_check_type(sql, &st_flt, exp, type_cast),
- rel_check_type(sql, &st_flt, exp_copy(sql->sa,
os_ste[i]), type_cast), sf);
-
- if (!(sf = sql_bind_func(sql->sa, sql->session->schema, "ceil",
exp_subtype(exp), NULL, F_FUNC)))
- return sql_error(sql, 02, "failed to bind to the SQL
function \"ceil\"");
- exp = rel_check_type(sql, &st_int, exp_op(sql->sa,
append(new_exp_list(sql->sa), exp), sf), type_cast);
-
- for (j = 0; j < i; j++) {
- if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"sql_mul", exp_subtype(nrep[j]), exp_subtype(exp), F_FUNC)))
- return sql_error(sql, 02, "failed to bind to
the SQL function \"*\"");
- nrep[j] = exp_binop(sql->sa, nrep[j], exp, sf);
- }
- for (j = t->valence-1; j > i; j--) {
- if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"sql_mul", exp_subtype(ngrp[j]), exp_subtype(exp), F_FUNC)))
- return sql_error(sql, 02, "failed to bind to
the SQL function \"*\"");
- ngrp[j] = exp_binop(sql->sa, ngrp[j], exp, sf);
+ if (os_ste[i] != NULL) { /* otherwise, it's a point-range, and
nrep[i] and ngrp[i] are just 1 */
+ if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"sql_sub", exp_subtype(os_sto[i]), exp_subtype(os_sta[i]), F_FUNC)))
+ return sql_error(sql, 02, "failed to bind to
the SQL function \"-\"");
+ exp = exp_binop(sql->sa, os_sto[i], os_sta[i], sf);
+
+ if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"sql_div", &st_flt, &st_flt, F_FUNC)))
+ return sql_error(sql, 02, "failed to bind to
the SQL function \"/\"");
+ exp = exp_binop(sql->sa,
+ rel_check_type(sql, &st_flt, exp,
type_cast),
+ rel_check_type(sql, &st_flt,
exp_copy(sql->sa, os_ste[i]), type_cast), sf);
+
+ if (!(sf = sql_bind_func(sql->sa, sql->session->schema,
"ceil", exp_subtype(exp), NULL, F_FUNC)))
+ return sql_error(sql, 02, "failed to bind to
the SQL function \"ceil\"");
+ exp = rel_check_type(sql, &st_int, exp_op(sql->sa,
append(new_exp_list(sql->sa), exp), sf), type_cast);
+
+ for (j = 0; j < i; j++) {
+ if (!(sf = sql_bind_func(sql->sa,
sql->session->schema, "sql_mul", exp_subtype(nrep[j]), exp_subtype(exp),
F_FUNC)))
+ return sql_error(sql, 02, "failed to
bind to the SQL function \"*\"");
+ nrep[j] = exp_binop(sql->sa, nrep[j], exp, sf);
+ }
+ for (j = t->valence-1; j > i; j--) {
+ if (!(sf = sql_bind_func(sql->sa,
sql->session->schema, "sql_mul", exp_subtype(ngrp[j]), exp_subtype(exp),
F_FUNC)))
+ return sql_error(sql, 02, "failed to
bind to the SQL function \"*\"");
+ ngrp[j] = exp_binop(sql->sa, ngrp[j], exp, sf);
+ }
}
}
@@ -4427,17 +4429,25 @@ static sql_exp *
append(aggr_types, exp_subtype(dim[i]));
/* The offset column */
-
- /* Build a list of args 'srs_args' with all parameters to
- * 'array_series1' to compute the materialised offsets 'oss' for
- * each dimension */
- append(srs_args, os_sta[i]);
- append(srs_args, os_ste[i]);
- append(srs_args, os_sto[i]);
- append(srs_args, nrep[i]);
- append(srs_args, ngrp[i]);
- if (!(sf = sql_bind_func_(sql->sa, mvc_bind_schema(sql, "sys"),
"array_series1", exps_subtype(srs_args), F_FUNC)))
- return sql_error(sql, 02, "failed to bind to the SQL
function \"array_series1\"");
+ if (os_ste[i] != NULL) {
+ /* Build a list of args 'srs_args' with all parameters
to
+ * 'array_series1' to compute the materialised offsets
for each
+ * dimension */
+ append(srs_args, os_sta[i]);
+ append(srs_args, os_ste[i]);
+ append(srs_args, os_sto[i]);
+ append(srs_args, nrep[i]);
+ append(srs_args, ngrp[i]);
+ if (!(sf = sql_bind_func_(sql->sa, mvc_bind_schema(sql,
"sys"), "array_series1", exps_subtype(srs_args), F_FUNC)))
+ return sql_error(sql, 02, "failed to bind to
the SciQL function \"array_series1\"");
+ } else {
+ for (cn = ((list*)dim[i]->f)->h->next->next; cn; cn =
cn->next) {
+ append(srs_args, ((list*)cn->data)->h->data);
+ }
+ if (!(sf = sql_bind_func_(sql->sa, mvc_bind_schema(sql,
"sys"), "array_offsets", exps_subtype(srs_args), F_FUNC)))
+ return sql_error(sql, 02, "failed to bind to
the SciQL function \"array_offsets\"");
+ }
+
/* have to build the list of types "by hand", since the call to
* 'array_series1' is of the type "bat", which causes the
* sql_bind_func_ below to fail */
@@ -4449,7 +4459,7 @@ static sql_exp *
append(aggr_types, &st_int);
}
if (!(sf = sql_bind_func_(sql->sa, mvc_bind_schema(sql, "sys"),
aggrstr2, aggr_types, F_FUNC)))
- return sql_error(sql, 02, "failed to bind to the SQL function
\"%s\"", aggrstr2);
+ return sql_error(sql, 02, "failed to bind to the SciQL function
\"%s\"", aggrstr2);
exp = exp_op(sql->sa, aggr_args, sf);
if (!exp->name) {
char name[16], *nme = NULL;
@@ -4908,6 +4918,32 @@ rel_selection_ref(mvc *sql, sql_rel *rel
}
static list *
+add_tiling_ranges(mvc *sql, list *l, list *r)
+{
+ node *nl = NULL, *nr = NULL;
+
+ assert(l && r && list_length(l) == list_length(r));
+
+ /* Walk over all dimensions. For each dimension, merge the new tiling
+ * ranges in 'r' into existing ranges in 'l'.
+ */
+ for (nl = l->h, nr = r->h; nl && nr; nl = nl->next, nr = nr->next) {
+ sql_exp *cl = nl->data, *cr = nr->data;
+
+ assert(cl->type == e_column && cl->f && cr->type == e_column &&
cr->f);
+ if (list_length(((list*)cr->f)->h->next->next->data) > 1) {
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list