Changeset: bd51d8adb278 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bd51d8adb278
Modified Files:
        sql/server/rel_schema.c
Branch: sciql
Log Message:

deal with different dimension data types when constructing sql_rel tree
CHAR, VARCHAR, DATE, TIME and TIMESTAMP are not supported yet, give an error


diffs (256 lines):

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
@@ -548,16 +548,22 @@
  * interval.
  */
 static int
-get_dim_constraints(mvc *sql, sql_subtype *ctype, dlist *lst, char **dimcstr)
+get_dim_constraints(mvc *sql, sql_subtype *ctype, dlist *lst, char **dimcstr, 
int isStep)
 {
-       int res = SQL_OK;
        sql_exp *exp = NULL;
        atom *a = NULL;
 
        assert(lst->h->type == type_string || lst->h->type == type_symbol);
 
        if(lst->h->type == type_symbol && !lst->h->data.sym)
-               return res; /* '*' case: nothing to do */
+               return SQL_OK; /* '*' case: nothing to do */
+
+       if (isStep && (strcmp(ctype->type->base.name, "str") == 0 || 
strcmp(ctype->type->base.name, "date") == 0 || strcmp(ctype->type->base.name, 
"daytime") == 0 || strcmp(ctype->type->base.name, "timestamp") == 0 ))
+       {
+               /* TODO: for these type of dimensions, their step size should 
always be an int-typed value */
+               sql_error(sql, 02, "CREATE ARRAY: dimension type \"%s\" 
unsupported yet", ctype->type->sqlname);
+               return SQL_ERR;
+       }
 
        if (lst->h->type == type_string) { /* handle negative (numerical) value 
*/
                a = ((AtomNode *) lst->h->next->data.sym)->a;
@@ -568,9 +574,9 @@
        exp = exp_atom(sql->sa, a);
        if (!(exp = rel_check_type(sql, ctype, exp, type_equal)))
                return SQL_ERR;
-       a = (atom *) exp->l; /* see rel_exp.c:exp_atom() */
+       /* TODO: do we want to convert the atom? */
        *dimcstr = GDKstrdup(atom2string(sql->sa, a));
-       return res;
+       return SQL_OK;
 }
 
 static int
@@ -618,7 +624,7 @@
                                dim = dim->h->data.lval; /* here starts the 
actual dimension constraints */
 
                                cs->dim = ZNEW(sql_dimspec);
-                               switch (dim->cnt) { /* TODO: what if '-' is 
used in a non-numeric dim_exp? */
+                               switch (dim->cnt) {
                                        case 1: {/* [size], [-size], [seqname] 
*/
                                                size_t len = 0;
                                                char *tname = NULL;
@@ -668,17 +674,17 @@
                                                }
                                        } break;
                                        case 2: /* [start:stop] */
-                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start)) != SQL_OK)
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start, 0)) != 
SQL_OK)
                                                        return res;
-                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->data.lval, &cs->dim->stop)) != 
SQL_OK)
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->data.lval, &cs->dim->stop, 0)) != 
SQL_OK)
                                                        return res;
                                                break;
                                        case 3: /* [start:step:stop] */
-                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start)) != SQL_OK)
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start, 0)) != 
SQL_OK)
                                                        return res;
-                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->data.lval, &cs->dim->step)) != 
SQL_OK)
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->data.lval, &cs->dim->step, 1)) != 
SQL_OK)
                                                        return res;
-                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->next->data.lval, &cs->dim->stop)) 
!= SQL_OK)
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->next->data.lval, &cs->dim->stop, 
0)) != SQL_OK)
                                                        return res;
                                                break;
                                        default:
@@ -938,6 +944,11 @@
                sql_table *t = mvc_create_table(sql, s, name, tt, 0, 
SQL_DECLARED_TABLE, commit_action, -1);
                dnode *n;
                dlist *columns = table_elements_or_subquery->data.lval;
+               sql_rel *res = NULL;
+               list *rp = new_exp_list(sql->sa);
+               node *col = NULL;
+               int i = 0, j = 0, cnt = 0, *N, *M;
+               lng cntall = 1;
 
                for (n = columns->h; n; n = n->next) {
                        symbol *sym = n->data.sym;
@@ -950,90 +961,96 @@
                        return sql_error(sql, 02, "CREATE ARRAY: an array must 
have at least one dimension");
 
                temp = (tt == tt_table || tt == tt_array)?temp:SQL_PERSIST;
-               /* For unbounded arrays we don't immediately create the columns 
*/
+               /* For tables and unbounded arrays we are done */
                if ((tt == tt_table) || (tt == tt_array && !t->fixed)) {
                        /* TODO: DDL_CREATE_TABLE looks sufficient for arrays 
for now */
                        return rel_table(sql, DDL_CREATE_TABLE, sname, t, temp);
-               } else { /* For fixed arrays, we immediately create and fill in 
BATs
-                                       for dimensions with dimension values, 
and for non-dim.
-                                       attributes with default values */
-                       sql_rel *res = NULL;
-                       list *rp = new_exp_list(sql->sa);
-                       node *col = NULL;
-                       int i = 0, j = 0, cnt = 0, *N, *M;
-                       lng cntall = 1;
+               }
+               
+               /* For fixed arrays, we immediately create and fill in BATs for 
dimensions with dimension values, and for non-dim. attributes with default 
values */
+               assert(tt == tt_array && t->fixed);
 
-                       assert(tt == tt_array && t->fixed);
+               /* To compute N (the #times each value is repeated), multiply 
the size of dimensions defined after the current dimension.  For the last 
dimension, its N is 1.  To compute M (the #times each value group is repeated), 
multiply the size of dimensions defined before the current dimension.  For the 
first dimension, its M is 1. */
+               N = GDKmalloc(sizeof(lng) * t->ndims);
+               M = GDKmalloc(sizeof(lng) * t->ndims);
+               if(!N || !M) {
+                       if(N) GDKfree(N);
+                       if(M) GDKfree(M);
+                       return sql_error(sql, 02, "CREATE ARRAY: failed to 
allocate space");
+               }
+               for(i = 0; i < t->ndims; i++) N[i] = M[i] = 1;
 
-                       N = GDKmalloc(sizeof(lng) * t->ndims);
-                       M = GDKmalloc(sizeof(lng) * t->ndims);
-                       if(!N || !M) {
-                               if(N) GDKfree(N);
-                               if(M) GDKfree(M);
-                               return sql_error(sql, 02, "CREATE ARRAY: failed 
to allocate space");
+               for (col = t->columns.set->h, i = 0; col; col = col->next){
+                       sql_column *sc = (sql_column *) col->data;
+                       atom *a_sta = atom_general(sql->sa, &sc->type, 
sc->dim->start);
+                       atom *a_ste = atom_general(sql->sa, &sc->type, 
sc->dim->step);
+                       atom *a_sto = atom_general(sql->sa, &sc->type, 
sc->dim->stop);
+                       if (sc->dim){
+                               switch(a_sto->data.vtype){
+                               case TYPE_bte:
+                                       cnt = (*(bte *)VALget(&a_sto->data) - 
*(bte *)VALget(&a_sta->data)) / *(bte *)VALget(&a_ste->data); break;
+                               case TYPE_sht:
+                                       cnt = (*(sht *)VALget(&a_sto->data) - 
*(sht *)VALget(&a_sta->data)) / *(sht *)VALget(&a_ste->data); break;
+                               case TYPE_int:
+                                       cnt = (*(int *)VALget(&a_sto->data) - 
*(int *)VALget(&a_sta->data)) / *(int *)VALget(&a_ste->data); break;
+                               case TYPE_flt:
+                                       cnt = (*(flt *)VALget(&a_sto->data) - 
*(flt *)VALget(&a_sta->data)) / *(flt *)VALget(&a_ste->data); break;
+                               case TYPE_dbl:
+                                       cnt = (*(dbl *)VALget(&a_sto->data) - 
*(dbl *)VALget(&a_sta->data)) / *(dbl *)VALget(&a_ste->data); break;
+                               case TYPE_lng:
+                                       cnt = (*(lng *)VALget(&a_sto->data) - 
*(lng *)VALget(&a_sta->data)) / *(lng *)VALget(&a_ste->data); break;
+                               default: /* should not reach here */
+                                       GDKfree(N); GDKfree(M);
+                                       return sql_error(sql, 02, "CREATE 
ARRAY: unsupported data type \"%s\"", sc->type.type->sqlname);
+                               }
+                               for (j = 0; j < i; j++) N[j] = N[j] * cnt;
+                               for (j = t->ndims; j > i; j--) M[j] = M[j] * 
cnt;
+                               cntall *= cnt;
+                               i++;
                        }
-                       for(i = 0; i < t->ndims; i++) N[i] = M[i] = 1;
+               }
+               if (i != t->ndims) {
+                       GDKfree(N); GDKfree(M);
+                       return sql_error(sql, 02, "CREATE ARRAY: expected 
number of dimension columns (%d) does not match actual numbre of dimension 
columns (%d)", t->ndims, i);
+               }
 
-                       for (col = t->columns.set->h, i = 0; col; col = 
col->next){
-                               sql_column *sc = (sql_column *) col->data;
-                               if (sc->dim){
-                                       cnt = (*sc->dim->stop - 
*sc->dim->start) / *sc->dim->step;
-                                       for (j = 0; j < i; j++) N[j] = N[j] * 
cnt;
-                                       for (j = t->ndims; j > i; j--) M[j] = 
M[j] * cnt;
-                                       cntall *= cnt;
-                                       i++;
+               /* create and fill all columns */
+               for (col = t->columns.set->h, i = 0; col; col = col->next){
+                       sql_column *sc = (sql_column *) col->data;
+                       list *args = new_exp_list(sql->sa);
+                       sql_exp *e = NULL;
+
+                       if (sc->dim){
+                               /* TODO: can we avoid computing these 
'atom_general' twice? */
+                               append(args, exp_atom(sql->sa, 
atom_general(sql->sa, &sc->type, sc->dim->start)));
+                               append(args, exp_atom(sql->sa, 
atom_general(sql->sa, &sc->type, sc->dim->step)));
+                               append(args, exp_atom(sql->sa, 
atom_general(sql->sa, &sc->type, sc->dim->stop)));
+                               append(args, exp_atom_int(sql->sa, N[i]));
+                               append(args, exp_atom_int(sql->sa, M[i]));
+                               append(rp, exp_op(sql->sa, args, 
sql_bind_func_(sql->sa, sql->session->schema, "array_series", 
exps_subtype(args))));
+                               i++;
+                       } else {
+                               if (sc->def) {
+                                       char *q = sql_message("select %s;", 
sc->def);
+                                       e = rel_parse_val(sql, q, sql->emode);
+                                       _DELETE(q);
+                                       if (!e || (e = rel_check_type(sql, 
&sc->type, e, type_equal)) == NULL)
+                                               return NULL;
+                               } else {
+                                       atom *a = atom_general(sql->sa, 
&sc->type, NULL);
+                                       e = exp_atom(sql->sa, a);
                                }
+                               append(args, exp_atom_lng(sql->sa, cntall));
+                               append(args, e);
+                               append(rp, exp_op(sql->sa, args, 
sql_bind_func_(sql->sa, sql->session->schema, "array_filler", 
exps_subtype(args))));
                        }
-                       if (i != t->ndims) {
-                               GDKfree(N); GDKfree(M);
-                               return sql_error(sql, 02, "CREATE ARRAY: 
expected number of dimension columns (%d) does not match actual numbre of 
dimension columns (%d)", t->ndims, i);
-                       }
-
-                       /* Create columns for the dimentional attributes */
-                       for (col = t->columns.set->h, i = 0; col; col = 
col->next){
-                               sql_column *sc = (sql_column *) col->data;
-                               list *args = new_exp_list(sql->sa);
-                               if (sc->dim){
-                                       append(args, exp_atom_int(sql->sa, 
*sc->dim->start));
-                                       append(args, exp_atom_int(sql->sa, 
*sc->dim->step));
-                                       append(args, exp_atom_int(sql->sa, 
*sc->dim->stop));
-                                       append(args, exp_atom_int(sql->sa, 
N[i]));
-                                       append(args, exp_atom_int(sql->sa, 
M[i]));
-                                       append(rp, exp_op(sql->sa, args, 
sql_bind_func_(sql->sa, sql->session->schema, "array_series", 
exps_subtype(args))));
-                                       i++;
-                               }
-                       }
-                       if (i != t->ndims) {
-                               GDKfree(N); GDKfree(M);
-                               return sql_error(sql, 02, "CREATE ARRAY: 
expected number of dimension columns (%d) does not match actual numbre of 
dimension columns (%d)", t->ndims, i);
-                       }
-
-                       /* Create columns for the non-dimentional attributes */
-                       for (col = t->columns.set->h, i = 0; col; col = 
col->next){
-                               sql_column *sc = (sql_column *) col->data;
-                               list *args = new_exp_list(sql->sa);
-                               if (!sc->dim){
-                                       sql_exp *e = NULL;
-
-                                       if (sc->def) {
-                                               char *q = sql_message("select 
%s;", sc->def);
-                                               e = rel_parse_val(sql, q, 
sql->emode);
-                                               _DELETE(q);
-                                               if (!e || (e = 
rel_check_type(sql, &sc->type, e, type_equal)) == NULL)
-                                                       return NULL;
-                                       } else {
-                                               atom *a = atom_general(sql->sa, 
&sc->type, NULL);
-                                               e = exp_atom(sql->sa, a);
-                                       }
-                                       append(args, exp_atom_lng(sql->sa, 
cntall));
-                                       append(args, e);
-                                       append(rp, exp_op(sql->sa, args, 
sql_bind_func_(sql->sa, sql->session->schema, "array_filler", 
exps_subtype(args))));
-                               }
-                       }
-
-                       res = rel_table(sql, DDL_CREATE_TABLE, sname, t, temp);
-                       return rel_insert(sql, res, rel_project(sql->sa, NULL, 
rp));
                }
+               if (i != t->ndims) {
+                       GDKfree(N); GDKfree(M);
+                       return sql_error(sql, 02, "CREATE ARRAY: expected 
number of dimension columns (%d) does not match actual numbre of dimension 
columns (%d)", t->ndims, i);
+               }
+               res = rel_table(sql, DDL_CREATE_TABLE, sname, t, temp);
+               return rel_insert(sql, res, rel_project(sql->sa, NULL, rp));
        } else { /* [col name list] as subquery with or without data */
                /* TODO: handle create_array_as_subquery??? */
                sql_rel *sq = NULL, *res = NULL;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to