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

store dimension constraints 'start', 'step' and 'stop' as 'char *',
since 'lng *' is not sufficient to support all data types allowed as a
dimension data type.

also added check if the dimension constraints conform the column data type
(except for TIMESTAMP).


diffs (222 lines):

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
@@ -195,9 +195,9 @@
 } sql_subtype;
 
 typedef struct sql_dimspec {
-       lng *start; /* NULL means unbounded */
-       lng *step;
-       lng *stop;
+       char *start; /* NULL means unbounded */
+       char *step;
+       char *stop;
 } sql_dimspec;
 
 /* sql_func need type transform rules types are equal if underlying
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
@@ -539,11 +539,45 @@
        return res;
 }
 
+/**
+ * Get the string value of a dimension constraint 'dimcstr' out of the parse
+ * tree 'lst'.  Also check if the data type of this dimension constraint
+ * conforms the data type of the column 'ctype'.
+ *
+ * TODO: deal with TIMESTAMP dimensions differently, since the 'step' is an
+ * interval.
+ */
+static int
+get_dim_constraints(mvc *sql, sql_subtype *ctype, dlist *lst, char **dimcstr)
+{
+       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 */
+
+       if (lst->h->type == type_string) { /* handle negative (numerical) value 
*/
+               a = ((AtomNode *) lst->h->next->data.sym)->a;
+               atom_neg(a);
+       } else { /* handle non-negative value */
+               a = ((AtomNode *) lst->h->data.sym)->a;
+       }
+       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() */
+       *dimcstr = GDKstrdup(atom2string(sql->sa, a));
+       return res;
+}
+
 static int
 create_column(mvc *sql, symbol *s, sql_schema *ss, sql_table *t, int alter)
 {
        dlist *l = s->data.lval;
-       dlist *dim = NULL, *dim_range = NULL, *dim_start = NULL, *dim_step = 
NULL, *dim_stop = NULL;
+       dlist *dim = NULL;
        char *cname = l->h->data.sval;
        sql_subtype *ctype = &l->h->next->data.typeval;
        dlist *opt_list = NULL;
@@ -581,15 +615,15 @@
                         * dim_range list of the "DIMENSION" case is denoted */
                        dim = l->h->next->next->next->data.sym->data.lval;
                        if (dim && !dim->h->next) { /* "DIMENSION dim_range" 
case */
-                               dim_range = dim->h->data.lval;
+                               dim = dim->h->data.lval; /* here starts the 
actual dimension constraints */
 
                                cs->dim = ZNEW(sql_dimspec);
-                               switch (dim_range->cnt) { /* TODO: what if '-' 
is used in a non-numeric dim_exp? */
+                               switch (dim->cnt) { /* TODO: what if '-' is 
used in a non-numeric dim_exp? */
                                        case 1: {/* [size], [-size], [seqname] 
*/
                                                size_t len = 0;
                                                char *tname = NULL;
-                                               if(dim_range->h->type == 
type_string) { /* TODO: implementation: look up the constraints of the [seq] */
-                                                       sql_error(sql, 02, "%s 
ARRAY: dimension column '%s' uses sequence \"%s\" as constraint, not 
implemented yet\n", (alter)?"ALTER":"CREATE", cname, dim_range->h->data.sval);
+                                               if(dim->h->type == type_string) 
{ /* TODO: implementation: look up the constraints of the [seq] */
+                                                       sql_error(sql, 02, "%s 
ARRAY: dimension column '%s' uses sequence \"%s\" as constraint, not 
implemented yet\n", (alter)?"ALTER":"CREATE", cname, dim->h->data.sval);
                                                        return SQL_ERR;
                                                }
 
@@ -601,89 +635,54 @@
                                                        return SQL_ERR;
                                                }
 
-                                               assert(dim_range->h->type == 
type_list);
-                                               if 
(dim_range->h->data.lval->h->type == type_symbol){
-                                                       if 
(dim_range->h->data.lval->h->data.sym) {             /* the case: [size] */
-                                                               tname = 
((AtomNode*)dim_range->h->data.lval->h->data.sym)->a->tpe.type->sqlname;
+                                               assert(dim->h->type == 
type_list);
+                                               if (dim->h->data.lval->h->type 
== type_symbol){
+                                                       if 
(dim->h->data.lval->h->data.sym) {           /* the case: [size] */
+                                                               tname = 
((AtomNode*)dim->h->data.lval->h->data.sym)->a->tpe.type->sqlname;
                                                                len = 
strlen(tname);
                                                                if(tname[len-3] 
!= 'i' || tname[len-2] != 'n' || tname[len-1] != 't') {
                                                                        
sql_error(sql, 02, "%s ARRAY: constraints of dimension column '%s' has invalid 
data type: expect int type, got \"%s\"\n", (alter)?"ALTER":"CREATE", cname, 
tname);
                                                                        return 
SQL_ERR;
                                                                }
 
-                                                               cs->dim->start 
= ZNEW(lng); *cs->dim->start = 0; /* TODO: make this configurable */
-                                                               cs->dim->step = 
ZNEW(lng); *cs->dim->step = 1;
-                                                               cs->dim->stop = 
ZNEW(lng); *cs->dim->stop = 
atom_get_int(((AtomNode*)dim_range->h->data.lval->h->data.sym)->a);
-                                                       }                       
                                                                                
/* else the case [*]: nothing to do */
-                                               } else {                        
                                                                        /* the 
case: [-size] */
-                                                       
assert(dim_range->h->data.lval->h->type == type_string && 
strcmp(dim_range->h->data.lval->h->data.sval, "sql_neg")==0);
+                                                               cs->dim->start 
= GDKstrdup("0");
+                                                               cs->dim->step = 
GDKstrdup("1");
+                                                               cs->dim->step = 
GDKstrdup(atom2string(sql->sa, ((AtomNode*)dim->h->data.lval->h->data.sym)->a));
+                                                       } else {                
                                                        /* the case [*]: 
nothing to do */
+                                                               /* TODO: check 
*/
+                                                       }
+                                               } else {                        
                                                        /* the case: [-size] */
+                                                       
assert(dim->h->data.lval->h->type == type_string && 
strcmp(dim->h->data.lval->h->data.sval, "sql_neg")==0);
 
-                                                       tname = 
((AtomNode*)dim_range->h->data.lval->h->next->data.sym)->a->tpe.type->sqlname;
+                                                       tname = 
((AtomNode*)dim->h->data.lval->h->next->data.sym)->a->tpe.type->sqlname;
                                                        len = strlen(tname);
                                                        if(tname[len-3] != 'i' 
|| tname[len-2] != 'n' || tname[len-1] != 't') {
                                                                sql_error(sql, 
02, "%s ARRAY: constraints of dimension column '%s' has invalid data type: 
expect int type, got \"%s\"\n", (alter)?"ALTER":"CREATE", cname, tname);
                                                                return SQL_ERR;
                                                        }
 
-                                                       cs->dim->start = 
ZNEW(lng); *cs->dim->start = 0; /* TODO: make this configurable */
-                                                       cs->dim->step = 
ZNEW(lng); *cs->dim->step = -1;
-                                                       atom_neg( ((AtomNode *) 
dim_range->h->data.lval->h->next->data.sym)->a );
-                                                       cs->dim->stop = 
ZNEW(lng); *cs->dim->stop = 
atom_get_int(((AtomNode*)dim_range->h->data.lval->h->next->data.sym)->a);
+                                                       cs->dim->start = 
GDKstrdup("0");
+                                                       cs->dim->step = 
GDKstrdup("-1");
+                                                       atom_neg( ((AtomNode *) 
dim->h->data.lval->h->next->data.sym)->a );
+                                                       cs->dim->step = 
GDKstrdup(atom2string(sql->sa, 
((AtomNode*)dim->h->data.lval->h->next->data.sym)->a));
                                                }
                                        } break;
                                        case 2: /* [start:stop] */
-                                               dim_start = 
dim_range->h->data.lval;
-                                               if (dim_start->h->type == 
type_string) { /* handle negative (numerical) value */
-                                                       cs->dim->start = 
ZNEW(lng);
-                                                       atom_neg( ((AtomNode *) 
dim_start->h->next->data.sym)->a );
-                                                       *cs->dim->start = 
atom_get_int( ((AtomNode *) dim_start->h->next->data.sym)->a );
-                                               } else if 
(dim_start->h->data.lval) { /* handle non-negative value */
-                                                       cs->dim->start = 
ZNEW(lng);
-                                                       *cs->dim->start = 
atom_get_int(((AtomNode *) dim_start->h->data.sym)->a);
-                                               } /* else start == '*': nothing 
to do */
-
-                                               dim_stop = 
dim_range->h->next->data.lval;
-                                               if (dim_stop->h->type == 
type_string) { /* handle negative (numerical) value */
-                                                       cs->dim->stop = 
ZNEW(lng);
-                                                       atom_neg( ((AtomNode *) 
dim_stop->h->next->data.sym)->a );
-                                                       *cs->dim->stop = 
atom_get_int( ((AtomNode *) dim_stop->h->next->data.sym)->a );
-                                               } else if 
(dim_stop->h->data.lval) { /* handle non-negative value */
-                                                       cs->dim->stop = 
ZNEW(lng);
-                                                       *cs->dim->stop = 
atom_get_int(((AtomNode *) dim_stop->h->data.sym)->a);
-                                               } /* else stop == '*': nothing 
to do */
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start)) != SQL_OK)
+                                                       return res;
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->data.lval, &cs->dim->stop)) != 
SQL_OK)
+                                                       return res;
                                                break;
                                        case 3: /* [start:step:stop] */
-                                               dim_start = 
dim_range->h->data.lval;
-                                               if (dim_start->h->type == 
type_string) { /* handle negative (numerical) value */
-                                                       cs->dim->start = 
ZNEW(lng);
-                                                       atom_neg( ((AtomNode *) 
dim_start->h->next->data.sym)->a );
-                                                       *cs->dim->start = 
atom_get_int( ((AtomNode *) dim_start->h->next->data.sym)->a );
-                                               } else if 
(dim_start->h->data.lval) { /* handle non-negative value */
-                                                       cs->dim->start = 
ZNEW(lng);
-                                                       *cs->dim->start = 
atom_get_int(((AtomNode *) dim_start->h->data.sym)->a);
-                                               } /* else start == '*': nothing 
to do */
-
-                                               dim_step = 
dim_range->h->next->data.lval;
-                                               if (dim_step->h->type == 
type_string) { /* handle negative (numerical) value */
-                                                       cs->dim->step = 
ZNEW(lng);
-                                                       *cs->dim->step = 
atom_get_int( ((AtomNode *) dim_step->h->next->data.sym)->a );
-                                               } else if 
(dim_step->h->data.lval) { /* handle non-negative value */
-                                                       cs->dim->step = 
ZNEW(lng);
-                                                       *cs->dim->step = 
atom_get_int(((AtomNode *) dim_step->h->data.sym)->a);
-                                               } /* else step == '*': nothing 
to do */
-
-                                               dim_stop = 
dim_range->h->next->next->data.lval;
-                                               if (dim_stop->h->type == 
type_string) { /* handle negative (numerical) value */
-                                                       cs->dim->stop = 
ZNEW(lng);
-                                                       atom_neg( ((AtomNode *) 
dim_stop->h->next->data.sym)->a );
-                                                       *cs->dim->stop = 
atom_get_int( ((AtomNode *) dim_stop->h->next->data.sym)->a );
-                                               } else if 
(dim_stop->h->data.lval) { /* handle non-negative value */
-                                                       cs->dim->stop = 
ZNEW(lng);
-                                                       *cs->dim->stop = 
atom_get_int(((AtomNode *) dim_stop->h->data.sym)->a);
-                                               } /* else stop == '*': nothing 
to do */
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start)) != SQL_OK)
+                                                       return res;
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->data.lval, &cs->dim->step)) != 
SQL_OK)
+                                                       return res;
+                                               if((res = 
get_dim_constraints(sql, ctype, dim->h->next->next->data.lval, &cs->dim->stop)) 
!= SQL_OK)
+                                                       return res;
                                                break;
                                        default:
-                                               sql_error(sql, 02, "%s ARRAY: 
dimension '%s' has wrong number of range constraints %d\n", 
(alter)?"ALTER":"CREATE", cname, dim_range->cnt);
+                                               sql_error(sql, 02, "%s ARRAY: 
dimension '%s' has wrong number of range constraints %d\n", 
(alter)?"ALTER":"CREATE", cname, dim->cnt);
                                                return SQL_ERR;
                                }
                        } else if (dim && dim->h->next) {
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -502,11 +502,11 @@
        if (dim_rid != oid_nil){ /* this is a dimension column */
                c->dim = ZNEW(sql_dimspec);
                if((v = table_funcs.column_find_value(tr, 
find_sql_column(dimensions, "start"), dim_rid)))
-                       c->dim->start = ZNEW(lng); *c->dim->start = *(lng *)v; 
_DELETE(v);
+                       c->dim->start = GDKstrdup((char *)v); _DELETE(v);
                if((v = table_funcs.column_find_value(tr, 
find_sql_column(dimensions, "step"), dim_rid)))
-                       c->dim->step = ZNEW(lng); *c->dim->step = *(lng *)v; 
_DELETE(v);
+                       c->dim->step = GDKstrdup((char *)v); _DELETE(v);
                if((v = table_funcs.column_find_value(tr, 
find_sql_column(dimensions, "stop"), dim_rid)))
-                       c->dim->stop = ZNEW(lng); *c->dim->stop = *(lng *)v; 
_DELETE(v);
+                       c->dim->stop = GDKstrdup((char *)v); _DELETE(v);
        }
 
        c->def = NULL;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to