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

Reply via email to