Changeset: d09a8d31eefb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d09a8d31eefb
Modified Files:
        sql/server/rel_schema.c
        sql/server/sql_parser.y
        sql/test/sciql/Tests/00_syntax_error_02.stable.err
        sql/test/sciql/Tests/00_syntax_error_03.stable.err
        sql/test/sciql/Tests/01_create_03.sql
        sql/test/sciql/Tests/01_create_03.stable.err
        sql/test/sciql/Tests/01_create_03.stable.out
        sql/test/sciql/Tests/01_create_04.stable.err
        sql/test/sciql/Tests/01_create_04.stable.out
        sql/test/sciql/Tests/01_create_20.stable.err
        sql/test/sciql/Tests/01_create_20.stable.out
Branch: sciql
Log Message:

Allow the [<size>] shortcut for *INT dimensions to be given via a variable, see
for example the queries in test 01_create_03.

Modified the existing test 01_create_03 to test the cases '*INT
DIMENSION[<size>]' and '*INT DIMENSION[<var>]' (since the previous queries in
01_create_03 are redundant).

Approved stable out/err, also for the tests which err msgs are modified in the 
code


diffs (truncated from 750 to 300 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
@@ -606,8 +606,10 @@ get_dim_constraints(mvc *sql, sql_subtyp
 }
 
 
+/* checks if 'tpe' is one of the MonetDB int types */
+#define isAnInternIntType(tpe) (tpe == TYPE_bit || tpe == TYPE_bte || tpe == 
TYPE_sht || tpe == TYPE_int || tpe == TYPE_wrd || tpe == TYPE_lng)
 /* checks if 'tpe' is one of the SQL int types, i.e., TINYINT, SMALLINT, INT 
or BIGINT */
-#define isAnIntType(tpe, len) (tpe[len-3] == 'i' && tpe[len-2] == 'n' && 
tpe[len-1] == 't')
+#define isAnSQLIntType(tpe, len) (tpe[len-3] == 'i' && tpe[len-2] == 'n' && 
tpe[len-1] == 't')
 
 static int
 create_column(mvc *sql, symbol *s, sql_schema *ss, sql_table *t, int alter)
@@ -615,11 +617,13 @@ create_column(mvc *sql, symbol *s, sql_s
        dlist *l = s->data.lval;
        dlist *dim = NULL;
        char *cname = l->h->data.sval, *tname = NULL;
+       char *action = alter ? "ALTER":"CREATE";
        sql_subtype *ctype = &l->h->next->data.typeval;
        dlist *opt_list = NULL;
        int res = SQL_OK;
 
-(void)ss;
+       (void)ss;
+
        if (alter && !isTableOrArray(t)) {
                sql_error(sql, 02, "42000!ALTER %s: cannot add column to VIEW 
'%s'\n", isTable(t)?"TABLE":(isArray(t)?"ARRAY":"TABLE/ARRAY"), t->base.name);
                return SQL_ERR;
@@ -632,7 +636,7 @@ create_column(mvc *sql, symbol *s, sql_s
 
                cs = find_sql_column(t, cname);
                if (cs) {
-                       sql_error(sql, 02, "42S21!%s TABLE: a column named '%s' 
already exists\n", (alter)?"ALTER":"CREATE", cname);
+                       sql_error(sql, 02, "42S21!%s TABLE: a column named '%s' 
already exists\n", action, cname);
                        return SQL_ERR;
                }
 
@@ -641,63 +645,97 @@ create_column(mvc *sql, symbol *s, sql_s
                        /* this is a dimension, see its structure in 
parser.y/column_def */
                        assert(l->h->next->next->next->type == type_symbol && 
l->h->next->next->next->data.sym->token == SQL_DIMENSION);
                        if (!isArray(t)){
-                               sql_error(sql, 02, "%s %s: dimension column 
'%s' used in non-ARRAY\n", (alter)?"ALTER":"CREATE", 
(t->type==tt_table)?"TABLE":"OTHER_TT", cname);
+                               sql_error(sql, 02, "%s %s: dimensions ('%s') 
not allowed in non-ARRAY\n", action, (t->type==tt_table)?"TABLE":"OTHER_TT", 
cname);
+                               return SQL_ERR;
+                       }
+
+                       tname = ctype->type->sqlname;
+                       if(!isAnSQLIntType(tname, strlen(tname))) { /* TODO: 
update this check if more dimension types are supported. */
+                               sql_error(sql, 02, "%s ARRAY: dimension type 
'%s' not supported yet\n", action, tname);
                                return SQL_ERR;
                        }
 
                        t->ndims++;
 
-                       /* TODO: check if this is the correct place where the 
NULL
-                        * 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 = dim->h->data.lval; /* here starts the 
actual dimension constraints */
 
                                cs->dim = ZNEW(sql_dimspec);
                                switch (dim->cnt) {
-                                       case 1: {/* [size], [-size], [seqname] 
*/
-                                               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;
-                                               }
+                                       case 1: {/* [*], [size], [-size], 
[seqname], [varname (represent size)] */
+                                               if(dim->h->type == type_string) 
{
+                                                       void *ptr = NULL;
+                                                       if ((ptr = 
stack_get_var(sql, dim->h->data.sval))) { /* [varname] */
+                                                               ValRecord var;
+                                                               
VALcopy((ValPtr)&var, ptr); /* to prevent VALconvert overwriting the variable 
on the stack */
 
-                                               /* In cases [size] or [-size], 
the column's data type MUST be INT */
-                                               tname = ctype->type->sqlname;
-                                               if(!isAnIntType(tname, 
strlen(tname))) {
-                                                       sql_error(sql, 02, "%s 
ARRAY: syntax shortcut '[size]' only allowed for int typed dimensions, 
dimension column \"%s\" has type \"%s\"\n", (alter)?"ALTER":"CREATE", cname, 
tname);
-                                                       return SQL_ERR;
-                                               }
+                                                               /* In case that 
the [size] shortcut is given as a variable, the column's data type MUST be INT 
*/
+                                                               tname = 
ctype->type->sqlname;
+                                                               
if(!isAnSQLIntType(tname, strlen(tname))) {
+                                                                       
sql_error(sql, 02, "%s ARRAY: syntax shortcut '[size]' only allowed for int 
typed dimensions, dimension '%s' has type '%s'\n", action, cname, tname);
+                                                                       return 
SQL_ERR;
+                                                               }
+                                                               
if(!isAnInternIntType(var.vtype)) {
+                                                                       
sql_error(sql, 02, "%s ARRAY: syntax shortcut '[size]' expects an int typed 
value, but variable '%s' is of type '%d'\n", action, dim->h->data.sval, 
var.vtype);
+                                                                       return 
SQL_ERR; 
+                                                               }
 
-                                               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;
-                                                               
if(!isAnIntType(tname, strlen(tname))) {
-                                                                       
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);
+                                                               if (var.vtype > 
ctype->type->localtype) { /* TODO: ideally, even if (var.vtype > 
ctype->type->localtype), we should check if the value of 'var' fits into the 
type 'ctype.type->localtype' */
+                                                                       
sql_error(sql, 02, "%s ARRAY: type '%d' of variable '%s' does not match type 
'%d' of dimension '%s'\n", action, var.vtype, dim->h->data.sval, 
ctype->type->localtype, cname);
+                                                                       return 
SQL_ERR;
+                                                               }
+                                                               cs->dim->start 
= GDKstrdup("0");
+                                                               cs->dim->step = 
GDKstrdup("1");
+                                                               cs->dim->stop = 
VALconvert(TYPE_str, &var);
+                                                       } else if ((ptr = 
find_sql_sequence(cur_schema(sql), dim->h->data.sval))) { /* [seqname] */
+                                                               /* TODO 1: 
extend the parser to accept a [qname] as [seqname] */
+                                                               /* TODO 2: 
implementation: look up the constraints of the [seqname] */
+                                                               sql_error(sql, 
02, "%s ARRAY: SQL SEQUENCE (\'%s\') as dimension ('%s') constraint not 
implemented yet\n", action, dim->h->data.sval, cname);
+                                                               return SQL_ERR;
+                                                       } else {
+                                                               sql_error(sql, 
02, "%s ARRAY: identifier '%s' unknown\n", action, dim->h->data.sval);
+                                                               return SQL_ERR;
+                                                       }
+                                               } else {
+                                                       /* In cases [size] or 
[-size], the column's data type MUST be INT */
+                                                       tname = 
ctype->type->sqlname;
+                                                       
if(!isAnSQLIntType(tname, strlen(tname))) {
+                                                               sql_error(sql, 
02, "%s ARRAY: syntax shortcut '[size]' only allowed for int typed dimensions, 
dimension column '%s' has type '%s'\n", action, cname, tname);
+                                                               return SQL_ERR;
+                                                       }
+
+                                                       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;
+                                                                       
if(!isAnSQLIntType(tname, strlen(tname))) {
+                                                                               
sql_error(sql, 02, "%s ARRAY: constraints of dimension '%s' has invalid data 
type: expect int type, got '%s'\n", action, cname, tname);
+                                                                               
return SQL_ERR;
+                                                                       }
+
+                                                                       
cs->dim->start = GDKstrdup("0");
+                                                                       
cs->dim->step = GDKstrdup("1");
+                                                                       
cs->dim->stop = atom2string(sql->sa, 
((AtomNode*)dim->h->data.lval->h->data.sym)->a);
+                                                               } else {        
                                                                /* the case: 
[*] */
+                                                                       
cs->dim->start = GDKstrdup("");
+                                                                       
cs->dim->step = GDKstrdup("");
+                                                                       
cs->dim->stop = GDKstrdup("");
+                                                               }
+                                                       } 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->h->data.lval->h->next->data.sym)->a->tpe.type->sqlname;
+                                                               
if(!isAnSQLIntType(tname, strlen(tname))) {
+                                                                       
sql_error(sql, 02, "%s ARRAY: constraints of dimension column '%s' has invalid 
data type: expect int type, got '%s'\n", action, cname, tname);
                                                                        return 
SQL_ERR;
                                                                }
 
                                                                cs->dim->start 
= GDKstrdup("0");
-                                                               cs->dim->step = 
GDKstrdup("1");
-                                                               cs->dim->stop = 
atom2string(sql->sa, ((AtomNode*)dim->h->data.lval->h->data.sym)->a);
-                                                       } else {                
                                                        /* the case: [*] */
-                                                               cs->dim->start 
= GDKstrdup("");
-                                                               cs->dim->step = 
GDKstrdup("");
-                                                               cs->dim->stop = 
GDKstrdup("");
+                                                               cs->dim->step = 
GDKstrdup("-1");
+                                                               atom_neg( 
((AtomNode *) dim->h->data.lval->h->next->data.sym)->a );
+                                                               cs->dim->stop = 
atom2string(sql->sa, ((AtomNode*)dim->h->data.lval->h->next->data.sym)->a);
                                                        }
-                                               } 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->h->data.lval->h->next->data.sym)->a->tpe.type->sqlname;
-                                                       if(!isAnIntType(tname, 
strlen(tname))) {
-                                                               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 = 
GDKstrdup("0");
-                                                       cs->dim->step = 
GDKstrdup("-1");
-                                                       atom_neg( ((AtomNode *) 
dim->h->data.lval->h->next->data.sym)->a );
-                                                       cs->dim->stop = 
atom2string(sql->sa, ((AtomNode*)dim->h->data.lval->h->next->data.sym)->a);
                                                }
                                        } break;
                                        case 2: /* [start:stop] */
@@ -707,7 +745,7 @@ create_column(mvc *sql, symbol *s, sql_s
                                                        return res;
                                                tname = ctype->type->sqlname;
                                                /* For int-typed dimensions, we 
allow [start:stop] to be the shortcut of [start:1:stop] */
-                                               cs->dim->step = 
isAnIntType(tname, strlen(tname)) ? GDKstrdup("1") : GDKstrdup("");
+                                               cs->dim->step = 
isAnSQLIntType(tname, strlen(tname)) ? GDKstrdup("1") : GDKstrdup("");
                                                break;
                                        case 3: /* [start:step:stop] */
                                                if((res = 
get_dim_constraints(sql, ctype, dim->h->data.lval, &cs->dim->start, 0)) != 
SQL_OK)
@@ -718,11 +756,11 @@ create_column(mvc *sql, symbol *s, sql_s
                                                        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->cnt);
+                                               sql_error(sql, 02, "%s ARRAY: 
dimension '%s' has wrong number of range constraints %d\n", action, cname, 
dim->cnt);
                                                return SQL_ERR;
                                }
                        } else if (dim && dim->h->next) { /* TODO: the case 
"ARRAY dim_range_list" is not dealt with */
-                               sql_error(sql, 02, "%s ARRAY: dimension '%s' 
constraint with syntax 'ARRAY dim_range_list' not implemented yet\n", 
(alter)?"ALTER":"CREATE", cname);
+                               sql_error(sql, 02, "%s ARRAY: dimension '%s' 
constraint with syntax 'ARRAY dim_range_list' not implemented yet\n", action, 
cname);
                                return SQL_ERR;
                        } else { /* "DIMENSION" case: only allocate space for 
empty [start:step:stop] */
                                cs->dim = ZNEW(sql_dimspec);
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -1698,7 +1698,7 @@ dim_range:
        {
                $$= append_list(L(), $2);
        }
-       | '[' ident ']'  /* sequence name */
+       | '[' ident ']'  /* sequence name or variable name */
        {
                $$= append_string(L(), $2);
        }
diff --git a/sql/test/sciql/Tests/00_syntax_error_02.stable.err 
b/sql/test/sciql/Tests/00_syntax_error_02.stable.err
--- a/sql/test/sciql/Tests/00_syntax_error_02.stable.err
+++ b/sql/test/sciql/Tests/00_syntax_error_02.stable.err
@@ -30,15 +30,15 @@ stderr of test '00_syntax_error_02` in d
 # 13:43:49 >  mclient -lsql -ftest -i -e --host=jarl --port=37241 
 # 13:43:49 >  
 
-MAPI  = monetdb@riga:39460
+MAPI  = monetdb@riga:36718
 QUERY = create array err(x char dimension[1:128:1], v float);
-ERROR = !CREATE ARRAY: dimension type "char" unsupported yet
-MAPI  = monetdb@riga:39460
+ERROR = !CREATE ARRAY: dimension type 'char' not supported yet
+MAPI  = monetdb@riga:36718
 QUERY = create array err(s varchar(25) dimension['a':'z':1], v float);
-ERROR = !CREATE ARRAY: dimension type "varchar" unsupported yet
-MAPI  = monetdb@riga:39460
+ERROR = !CREATE ARRAY: dimension type 'varchar' not supported yet
+MAPI  = monetdb@riga:36718
 QUERY = create array err(s varchar(25) dimension[1:3:1], v float);
-ERROR = !CREATE ARRAY: dimension type "varchar" unsupported yet
+ERROR = !CREATE ARRAY: dimension type 'varchar' not supported yet
 
 # 13:43:49 >  
 # 13:43:49 >  Done.
diff --git a/sql/test/sciql/Tests/00_syntax_error_03.stable.err 
b/sql/test/sciql/Tests/00_syntax_error_03.stable.err
--- a/sql/test/sciql/Tests/00_syntax_error_03.stable.err
+++ b/sql/test/sciql/Tests/00_syntax_error_03.stable.err
@@ -30,9 +30,9 @@ stderr of test '00_syntax_error_03` in d
 # 13:45:43 >  mclient -lsql -ftest -i -e --host=jarl --port=30420 
 # 13:45:43 >  
 
-MAPI  = monetdb@riga:39460
+MAPI  = monetdb@riga:36718
 QUERY = create array err( x char dimension[128]);
-ERROR = !CREATE ARRAY: syntax short cut '[size]' only allowed for int typed 
dimensions, dimension column "x" has type "char"
+ERROR = !CREATE ARRAY: dimension type 'char' not supported yet
 
 # 13:45:43 >  
 # 13:45:43 >  Done.
diff --git a/sql/test/sciql/Tests/01_create_03.sql 
b/sql/test/sciql/Tests/01_create_03.sql
--- a/sql/test/sciql/Tests/01_create_03.sql
+++ b/sql/test/sciql/Tests/01_create_03.sql
@@ -1,7 +1,98 @@
--- create an unbounded array
-CREATE ARRAY ary (x INTEGER DIMENSION[*], v FLOAT DEFAULT 3.7);
+-- use the [size] shortcut for integer type dimensions
+CREATE ARRAY test_01_03_tinyint  (x TINYINT  DIMENSION[4], v FLOAT DEFAULT 
3.7);
+CREATE ARRAY test_01_03_smallint (x SMALLINT DIMENSION[4], v FLOAT DEFAULT 
3.7);
+CREATE ARRAY test_01_03_int      (x INTEGER  DIMENSION[4], v FLOAT DEFAULT 
3.7);
+CREATE ARRAY test_01_03_bigint   (x BIGINT   DIMENSION[4], v FLOAT DEFAULT 
3.7);
 
-SELECT * FROM ary;
+SELECT * FROM test_01_03_tinyint;
+SELECT * FROM test_01_03_smallint;
+SELECT * FROM test_01_03_int;
+SELECT * FROM test_01_03_bigint;
 
-DROP ARRAY ary;
+DROP ARRAY test_01_03_tinyint;
+DROP ARRAY test_01_03_smallint;
+DROP ARRAY test_01_03_int;
+DROP ARRAY test_01_03_bigint;
 
+-- use the [-size] shortcut for integer type dimensions
+CREATE ARRAY test_01_03_neg_tinyint  (x TINYINT  DIMENSION[-4], v FLOAT 
DEFAULT 3.7);
+CREATE ARRAY test_01_03_neg_smallint (x SMALLINT DIMENSION[-4], v FLOAT 
DEFAULT 3.7);
+CREATE ARRAY test_01_03_neg_int      (x INTEGER  DIMENSION[-4], v FLOAT 
DEFAULT 3.7);
+CREATE ARRAY test_01_03_neg_bigint   (x BIGINT   DIMENSION[-4], v FLOAT 
DEFAULT 3.7);
+
+SELECT * FROM test_01_03_neg_tinyint;
+SELECT * FROM test_01_03_neg_smallint;
+SELECT * FROM test_01_03_neg_int;
+SELECT * FROM test_01_03_neg_bigint;
+
+DROP ARRAY test_01_03_neg_tinyint;
+DROP ARRAY test_01_03_neg_smallint;
+DROP ARRAY test_01_03_neg_int;
+DROP ARRAY test_01_03_neg_bigint;
+
+-- use the [varname] shortcut for integer type dimensions
+DECLARE vTinyint  TINYINT;  SET vTinyint = 6;
+DECLARE vSmallint SMALLINT; SET vSmallint = 6;
+DECLARE vInt      INTEGER;  SET vInt = 6;
+DECLARE vBigint   BIGINT;   SET vBigint = 6;
+
+CREATE ARRAY test_01_03_tinyint_tinyint   (x TINYINT  DIMENSION[vTinyint],  v 
FLOAT DEFAULT 3.7);
+CREATE ARRAY test_01_03_smallint_tinyint  (x SMALLINT DIMENSION[vTinyint],  v 
FLOAT DEFAULT 3.7);
+CREATE ARRAY test_01_03_int_tinyint       (x INTEGER  DIMENSION[vTinyint],  v 
FLOAT DEFAULT 3.7);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to