Changeset: d3b399699f6b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d3b399699f6b
Added Files:
        sql/test/sciql/Tests/07_tiling_04.sql
        sql/test/sciql/Tests/07_tiling_04.stable.err
        sql/test/sciql/Tests/07_tiling_04.stable.out
        sql/test/sciql/Tests/08_subquery_01.sql
        sql/test/sciql/Tests/08_subquery_01.stable.err
        sql/test/sciql/Tests/08_subquery_01.stable.out
Modified Files:
        monetdb5/modules/mal/array.mx
        sql/server/rel_select.c
        sql/test/sciql/Tests/00_syntax_error_01.stable.err
        sql/test/sciql/Tests/00_syntax_error_02.stable.err
        sql/test/sciql/Tests/00_syntax_error_03.stable.err
        sql/test/sciql/Tests/00_syntax_error_04.stable.err
        sql/test/sciql/Tests/00_syntax_error_05.stable.err
        sql/test/sciql/Tests/All
Branch: sciql
Log Message:

Fixes in array tiling group by code

rel_select.c
- Sovled the problem of "no such array" in SciQL group by over an array 
returned by a subquery by adding function that find the base name of a relation 
give the alias
- implemented the SciQL group by case '[*]'

array.mx:
- remove implementation of OID, since it's not an SQL datatype
- a rather stupid error in computing the total cnt.
- check input values and better error msg in array.series

Added + approved two test queries for the fixes above


diffs (truncated from 1724 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
@@ -49,7 +49,6 @@ end series_;
 
 @mal
 module array;
-@:array_mdefs(oid)@
 @:array_mdefs(bte)@
 @:array_mdefs(sht)@
 @:array_mdefs(int)@
@@ -58,6 +57,7 @@ module array;
 @:array_mdefs(dbl)@
 @-
 to be dealt with differently
+@:array_mdefs(oid)@
 @:array_mdefs(date)@
 @:array_mdefs(daytime)@
 @:array_mdefs(timestamp)@
@@ -206,7 +206,6 @@ array_export str ARRAYseries_@1(int *ret
 array_export str ARRAYtilesSum_@1(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 array_export str ARRAYtilesAvg_@1(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 @h
-@:array_defs(oid)@
 @:array_defs(bte)@
 @:array_defs(sht)@
 @:array_defs(int)@
@@ -215,6 +214,7 @@ array_export str ARRAYtilesAvg_@1(Client
 @:array_defs(dbl)@
 @-
 to be dealt with differently
+@:array_defs(oid)@
 @:array_defs(date)@
 @:array_defs(daytime)@
 @:array_defs(timestamp)@
@@ -245,13 +245,15 @@ ARRAYseries_@1(int *ret, @1 *start, @1 *
        BUN cnt= 0;
        int s,g;
 
-       if ( *start < *stop && *step > 0) {
+       if ( *group < 1 )
+               throw(MAL, "array.series", "#groups must be > 0,  got (%d)", 
*group);
+       if ( *series < 1 )
+               throw(MAL, "array.series", "#series must be > 0,  got (%d)", 
*series);
+
+       if ( (*start < *stop && *step > 0) || (*start > *stop && *step < 0) ) {
                cnt =  (BUN) ceil(((*stop * 1.0 - *start) / *step)) * *group * 
*series ;
        } else
-       if ( abs(*start) < abs(*stop) && abs(*step) > 0) {
-               cnt =  (BUN) ceil(((*stop * 1.0 + *start) / *step)) * *group * 
*series ;
-       } else
-               throw(MAL, "array.series", "illegal range");
+               throw(MAL, "array.series", "Illegal dimension range, 
[start:step:stop] have values: [@2:@2:@2]", *start, *step, *stop);
        bn = BATnew(TYPE_void, TYPE_@1, cnt);
        if ( bn == NULL)
                throw(MAL, "array.series", MAL_MALLOC_FAIL);
@@ -285,15 +287,15 @@ ARRAYseries_@1(int *ret, @1 *start, @1 *
 }
 
 @c
-@:dim_wrapper_impl(oid)@
-@:dim_wrapper_impl(bte)@
-@:dim_wrapper_impl(sht)@
-@:dim_wrapper_impl(int)@
-@:dim_wrapper_impl(lng)@
-@:dim_wrapper_impl(flt)@
-@:dim_wrapper_impl(dbl)@
+@:dim_wrapper_impl(bte,%d)@
+@:dim_wrapper_impl(sht,%d)@
+@:dim_wrapper_impl(int,%d)@
+@:dim_wrapper_impl(lng,%lld)@
+@:dim_wrapper_impl(flt,%f)@
+@:dim_wrapper_impl(dbl,%f)@
 @-
 to be dealt with differently
+@:dim_wrapper_impl(oid," OIDFMT ")@
 @:dim_wrapper_impl(date)@
 @:dim_wrapper_impl(daytime)@
 @:dim_wrapper_impl(timestamp)@
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
@@ -1954,6 +1954,22 @@ get_dimension(mvc *sql, sql_table *a, ch
        return sql_error(sql, 02, "SELECT: dimension '%s' not found in array 
'%s'", dname, a->base.name);
 }
 
+static sql_column *
+get_nth_dimension(sql_table *a, int nth)
+{
+       int i = 0;
+       node *cn = a->columns.set->h;
+
+       for (; cn; cn = cn->next) {
+               if(((sql_column *) cn->data)->dim) {
+                       if (i == nth)
+                               return cn->data;
+                       i++;
+               }
+       }
+       return NULL;
+}
+
 static int
 check_tiling_dimension(mvc *sql, char *dimnm, symbol *dim_ref)
 {
@@ -1977,6 +1993,96 @@ check_tiling_dimension(mvc *sql, char *d
        return 1;
 }
 
+static char *
+_get_base_name(sql_exp *exp, char *alias)
+{
+       char *bnm = NULL;
+       node *n = NULL;
+
+       if (!exp || !alias)
+               return NULL;
+
+       switch(exp->type) {
+       case e_func:
+       case e_aggr:
+               for (n = ((list*)exp->l)->h; n; n = n->next) {
+                       bnm = _get_base_name(n->data, alias);
+                       if (bnm)
+                               return bnm;
+               }
+               return NULL;
+       case e_convert:
+               return _get_base_name(exp->l, alias);
+       case e_cmp:
+               if(!(bnm = _get_base_name(exp->l, alias)))
+                       return _get_base_name(exp->r, alias);
+               return bnm;
+       case e_column:
+               if (exp->rname && strcmp(exp->rname, alias) == 0) {
+                       return exp->l;
+               }
+               return NULL;
+       default:
+               return NULL;
+       }
+       return NULL;
+}
+
+/* Given the alias of a table/array, find in all expressions contained in 'rel'
+ * the original name of the base table/array.
+ */
+static char *
+get_base_name(sql_rel *rel, char *alias)
+{
+       char *bnm = NULL;
+       node *n = rel->exps->h;
+
+       if (!rel || !alias)
+               return NULL;
+
+       for ( ; n; n = n->next) {
+               bnm = _get_base_name(n->data, alias);
+               if (bnm)
+                       return bnm;
+       }
+
+       switch(rel->op) {
+       case op_select:
+       case op_topn:
+       case op_sample:
+               return get_base_name(rel->l, alias);
+               break;
+       case op_join:
+       case op_left:
+       case op_right:
+       case op_full:
+       case op_semi:
+       case op_anti:
+       case op_union:
+       case op_except:
+       case op_inter:
+               if(!(bnm = get_base_name(rel->l, alias)))
+                       return get_base_name(rel->r, alias);
+               break;
+       case op_table:
+       case op_project:
+       case op_groupby:
+               if(!(bnm = get_base_name(rel->l, alias))) {
+                       if (!rel->r || !((list*)rel->r)->h)
+                               return NULL;
+                       for (n = ((list*)rel->r)->h; n; n = n->next) {
+                               bnm = _get_base_name(n->data, alias);
+                               if (bnm)
+                                       return bnm;
+                       }
+               }
+               break;
+       default:
+               return NULL;
+       }
+       return bnm;
+}
+
 #define ARRAY_TILING_MAX_DIMS 3
 
 static list *
@@ -1984,11 +2090,12 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
 {
        list *exps = new_exp_list(sql->sa), *offsets = NULL;
        dlist *qname = NULL, *idx_exps = NULL;
-       char *sname = NULL, *aname = NULL, *opnm = NULL;
+       char *sname = NULL, *aname = NULL, *aalias = NULL, *opnm = NULL;
        dnode *n =  NULL;
        symbol *sym_tsta = NULL, *sym_tsto =  NULL, *opl = NULL, *opr = NULL;
        sql_schema *s = NULL;
        sql_table *a = NULL;
+       int nth = 0; /* the n-th tiled dimension, needed for the '[*]' case, in 
which we don't have the dimension name */
 
        assert(rel && *rel && tile_def->token == SQL_ARRAY_DIM_SLICE && 
tile_def->type == type_list && dlist_length(tile_def->data.lval) == 2);
        
@@ -1996,12 +2103,12 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
        switch(dlist_length(qname)) {
        case 1:
                assert(qname->h->type == type_string);
-               aname = qname->h->data.sval;
+               aalias = qname->h->data.sval;
                break;
        case 2:
                assert(qname->h->type == type_string && qname->h->next->type == 
type_string);
                sname = qname->h->data.sval;
-               aname = qname->h->next->data.sval;
+               aalias = qname->h->next->data.sval;
                break;
        case 3:
                return sql_error(sql, 02, "SELECT: array names of level > 2 not 
supported");
@@ -2013,8 +2120,11 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
        if (sname && !(s=mvc_bind_schema(sql,sname)))
                return sql_error(sql, 02, "3F000!SELECT: no such schema '%s'", 
sname);
        if (!s) s = cur_schema(sql);
-       if (!(a = mvc_bind_table(sql, s, aname)))
-               return sql_error(sql, 02, "42S02!SELECT: no such array 
'%s.%s'", s->base.name, aname);
+       if (!(a = mvc_bind_table(sql, s, aalias))) {
+               if (!(aname = get_base_name(*rel, aalias)) || !(a = 
mvc_bind_table(sql, s, aname))) {
+                       return sql_error(sql, 02, "42S02!SELECT: no such array 
'%s.%s'", s->base.name, aalias);
+               }
+       }
        if (a->ndims > ARRAY_TILING_MAX_DIMS)
                return sql_error(sql, 02, "SELECT: TODO: array tiling over 
arrays with >%d dimensions", ARRAY_TILING_MAX_DIMS);
 
@@ -2025,112 +2135,123 @@ rel_arraytiling(mvc *sql, sql_rel **rel,
                return sql_error(sql, 02, "SELECT: #dimensions (%d) in array 
tiling fewer than #dimensions (%d) in the array --- not supported (yet?)", 
dlist_length(idx_exps), a->ndims);
        if (dlist_length(idx_exps) > ARRAY_TILING_MAX_DIMS)
                return sql_error(sql, 02, "SELECT: TODO: array tiling over >%d 
dimensions", ARRAY_TILING_MAX_DIMS);
-       for (n = idx_exps->h; n; n = n->next) {
+       for (n = idx_exps->h; n; n = n->next, nth++) {
                sql_exp *exp = NULL, *exp_os_sta = NULL, *exp_os_ste = NULL, 
*exp_os_sto = NULL;
                sql_column *dim = NULL;
                exp_kind ek = {type_value, card_value, FALSE};
                offsets = new_exp_list(sql->sa);
 
                assert(n->type == type_list);
-               /* The first is always the start of the range, to handle the 
first 'index_term':
-                * 1) extract and bind the dimension, which also checks if the
-                *    dimension exists in the array 'aname';
-                * 2) extract the start-offset expression from the 'index_term',
-                *    create an exp_atom with "0" if not specified (case
-                *    SQL_COLUMN), and append it to 'exp->f'.
-                */
-               sym_tsta = n->data.lval->h->data.sym;
-               switch (sym_tsta->token) {
-                       case SQL_COLUMN: /* '<column>' */
-                               if (!(exp = get_tiling_dimension(sql, *rel, 
aname, sym_tsta, f)))
-                                       return NULL;
-                               if (!(dim = get_dimension(sql, a, exp->name)))
-                                       return NULL;
-                               exp_os_sta = exp_atom(sql->sa, 
atom_general(sql->sa, &dim->type, "0"));
-                               break;
-                       case SQL_BINOP: /* '<column> <BINOP> <exp>' or '<exp> 
<BINOP> <column>' */
-                               /* sym_tsta->data.lval->h: a list of a single 
string, operator name
-                                * sym_tsta->data.lval->h->next: the symbol of 
the left operand
-                                * sym_tsta->data.lval->h->next->next: the 
symbol of the right operand
-                                */
-                               opnm = 
sym_tsta->data.lval->h->data.lval->h->data.sval;
-                               opl = sym_tsta->data.lval->h->next->data.sym;
-                               opr = 
sym_tsta->data.lval->h->next->next->data.sym;
-                               /* the <exp> could also be a SQL_COLUMN, but 
then opl->data.sym->data.lval->h->type == type_int */
-                               if (opl->token == SQL_COLUMN && 
opl->data.lval->h->type == type_string) { /* '<column> +/- <exp>' */
-                                       if (!(exp = get_tiling_dimension(sql, 
*rel, aname, opl, f)))
+               if (n->data.lval->h->data.sym) {
+                       sym_tsta = n->data.lval->h->data.sym;
+                       /* The first is always the start of the range, to 
handle the first 'index_term':
+                        * 1) extract and bind the dimension, which also checks 
if the
+                        *    dimension exists in the array 'aname';
+                        * 2) extract the start-offset expression from the 
'index_term',
+                        *    create an exp_atom with "0" if not specified (case
+                        *    SQL_COLUMN), and append it to 'exp->f'.
+                        */
+                       switch (sym_tsta->token) {
+                               case SQL_COLUMN: /* '<column>' */
+                                       if (!(exp = get_tiling_dimension(sql, 
*rel, aalias, sym_tsta, f)))
                                                return NULL;
                                        if (!(dim = get_dimension(sql, a, 
exp->name)))
                                                return NULL;
-                                       if (is_addition(opnm)) {
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to