Changeset: ad378d127873 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ad378d127873
Added Files:
        sql/test/merge-partitions/Tests/mergepart05.sql
        sql/test/merge-partitions/Tests/mergepart05.stable.err
        sql/test/merge-partitions/Tests/mergepart05.stable.out
Modified Files:
        sql/backends/monet5/sql_statement.c
        sql/server/rel_dump.c
        sql/server/rel_schema.c
        sql/server/sql_atom.c
        sql/server/sql_atom.h
        sql/test/merge-partitions/Tests/All
Branch: merge-partitions
Log Message:

Testing partition ranges with non-numeric values


diffs (truncated from 492 to 300 lines):

diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -3315,7 +3315,7 @@ const char *
                return st->op4.cval->base.name;
        case st_atom:
                if (st->op4.aval->data.vtype == TYPE_str)
-                       return atom2string(sa, st->op4.aval);
+                       return atom2string(sa, st->op4.aval, 0);
                /* fall through */
        case st_var:
        case st_temp:
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
@@ -118,7 +118,7 @@ exp_print(mvc *sql, stream *fout, sql_ex
                                        t->base.name);
                        } else {
                                char *t = sql_subtype_string(atom_type(a));
-                               char *s = atom2string(sql->sa, a);
+                               char *s = atom2string(sql->sa, a, 0);
                                mnstr_printf(fout, "%s \"%s\"", t, s);
                                _DELETE(t);
                        }
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
@@ -89,7 +89,7 @@ rel_alter_table_add_partition_range(sql_
 {
        sql_rel *rel = rel_create(sa);
        list *exps = new_exp_list(sa);
-       char *pmin = atom2string(sa, min), *pmax = atom2string(sa, max);
+       char *pmin = atom2string(sa, min, 1), *pmax = atom2string(sa, max, 1);
        if(!rel || !exps || !pmin || !pmax)
                return NULL;
 
@@ -130,7 +130,7 @@ rel_alter_table_add_partition_list(sql_a
        }
        for (n = ll->h; n ; n = n->next) {
                symbol* next = n->data.sym;
-               char *nvalue = atom2string(sa, ((AtomNode *) next)->a);
+               char *nvalue = atom2string(sa, ((AtomNode *) next)->a, 1);
                append(exps, exp_atom_clob(sa, nvalue));
        }
        rel->l = NULL;
@@ -523,7 +523,7 @@ column_option(
                        if (a->data.vtype == TYPE_str) {
                                mvc_default(sql, cs, a->data.val.sval);
                        } else {
-                               char *r = atom2string(sql->sa, a);
+                               char *r = atom2string(sql->sa, a, 0);
 
                                mvc_default(sql, cs, r);
                        }
@@ -1455,7 +1455,7 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                        sql_column *col =  t->pcol;
                                        dlist* ll = extra->data.lval;
                                        symbol* min = ll->h->data.sym, *max = 
ll->h->next->data.sym;
-                                       atom *amin, *amax;
+                                       atom *amin = NULL, *amax = NULL;
 
                                        if(t->type != tt_range_partition) {
                                                return sql_error(sql, 
02,SQLSTATE(42000) "ALTER TABLE: cannot add a range partition into a %s table",
@@ -1464,6 +1464,12 @@ sql_alter_table(mvc *sql, dlist *qname, 
 
                                        if(min->token == SQL_MINVALUE) {
                                                amin = 
atom_absolute_min(sql->sa, &(col->type));
+                                               if(!amin) {
+                                                       char *err = 
sql_subtype_string(&(col->type));
+                                                       if(!err)
+                                                               return 
sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+                                                       return sql_error(sql, 
02, SQLSTATE(HY001) "ALTER TABLE: absolute minimum value not available for %s 
type", err);
+                                               }
                                        } else {
                                                amin = ((AtomNode *) min)->a;
                                        }
@@ -1471,6 +1477,12 @@ sql_alter_table(mvc *sql, dlist *qname, 
                                                amax = 
atom_absolute_max(sql->sa, &(col->type));
                                        } else {
                                                amax = ((AtomNode *) max)->a;
+                                               if(!amin) {
+                                                       char *err = 
sql_subtype_string(&(col->type));
+                                                       if(!err)
+                                                               return 
sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+                                                       return sql_error(sql, 
02, SQLSTATE(HY001) "ALTER TABLE: absolute maximum value not available for %s 
type", err);
+                                               }
                                        }
                                        return 
rel_alter_table_add_partition_range(sql->sa, sname, tname, sname, ntname, amin, 
amax);
                                } else if(extra->token == SQL_PARTITION_LIST) {
diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c
--- a/sql/server/sql_atom.c
+++ b/sql/server/sql_atom.c
@@ -303,7 +303,7 @@ atom_ptr( sql_allocator *sa, sql_subtype
 }
 
 char *
-atom2string(sql_allocator *sa, atom *a)
+atom2string(sql_allocator *sa, atom *a, int quote)
 {
        char buf[BUFSIZ], *p = NULL;
        void *v;
@@ -345,9 +345,33 @@ atom2string(sql_allocator *sa, atom *a)
                sprintf(buf, "%f", a->data.val.dval);
                break;
        case TYPE_str:
-               if (a->data.val.sval)
-                       return sa_strdup(sa, a->data.val.sval);
-               else
+               if (a->data.val.sval) {
+                       if(!quote)
+                               return sa_strdup(sa, a->data.val.sval);
+                       else { /* always produce a string between quotes, 
placing them if they do not exist */
+                               int plus = 0, off = 0;
+                               char *res;
+                               if(a->data.val.sval[0] != '"')
+                                       plus++;
+                               if(a->data.len == 0 || 
a->data.val.sval[a->data.len - 1] != '"')
+                                       plus++;
+                               res = sa_alloc(sa, a->data.len + plus + 1);
+                               if(res) {
+                                       if(a->data.val.sval[0] != '"') {
+                                               res[off] = '"';
+                                               off++;
+                                       }
+                                       strcpy(res + off, a->data.val.sval);
+                                       off += a->data.len;
+                                       if(a->data.len == 0 || 
a->data.val.sval[a->data.len - 1] != '"') {
+                                               res[off] = '"';
+                                               off++;
+                                       }
+                                       res[off] = '\0';
+                               }
+                               return res;
+                       }
+               } else
                        sprintf(buf, "NULL");
                break;
         default:  
@@ -1350,6 +1374,9 @@ atom*
 atom_absolute_min(sql_allocator *sa, sql_subtype* tpe)
 {
        void *ret = NULL;
+       atom *res = atom_create(sa);
+       if(!res)
+               return NULL;
 
        switch (tpe->type->eclass) {
                case EC_BIT:
@@ -1419,19 +1446,25 @@ atom_absolute_min(sql_allocator *sa, sql
                case EC_DATE:
                case EC_TIME:
                case EC_TIMESTAMP:
-               case EC_CHAR:
-               case EC_STRING:
-               case EC_BLOB:
-               default:
+               default: /* EC_CHAR, EC_STRING, EC_BLOB, ... */
                        return NULL;
        }
-       return atom_ptr(sa, tpe, ret);
+
+       res->tpe = *tpe;
+       res->isnull = 0;
+       res->data.vtype = tpe->type->localtype;
+       VALset(&res->data, res->data.vtype, ret);
+
+       return res;
 }
 
 atom*
 atom_absolute_max(sql_allocator *sa, sql_subtype* tpe)
 {
        void *ret = NULL;
+       atom *res = atom_create(sa);
+       if(!res)
+               return NULL;
 
        switch (tpe->type->eclass) {
                case EC_BIT:
@@ -1501,11 +1534,14 @@ atom_absolute_max(sql_allocator *sa, sql
                case EC_DATE:
                case EC_TIME:
                case EC_TIMESTAMP:
-               case EC_CHAR:
-               case EC_STRING:
-               case EC_BLOB:
-               default:
-                       return NULL;
+               default: /* EC_CHAR, EC_STRING, EC_BLOB, ... */
+               return NULL;
        }
-       return atom_ptr(sa, tpe, ret);
+
+       res->tpe = *tpe;
+       res->isnull = 0;
+       res->data.vtype = tpe->type->localtype;
+       VALset(&res->data, res->data.vtype, ret);
+
+       return res;
 }
diff --git a/sql/server/sql_atom.h b/sql/server/sql_atom.h
--- a/sql/server/sql_atom.h
+++ b/sql/server/sql_atom.h
@@ -48,7 +48,7 @@ extern atom *atom_dup( sql_allocator *sa
 /* cast atom a to type tp (success == 1, fail == 0) */
 extern int atom_cast(sql_allocator *sa, atom *a, sql_subtype *tp);
 
-extern char *atom2string(sql_allocator *sa, atom *a);
+extern char *atom2string(sql_allocator *sa, atom *a, int quote);
 extern char *atom2sql(atom *a);
 extern sql_subtype *atom_type(atom *a);
 
diff --git a/sql/test/merge-partitions/Tests/All 
b/sql/test/merge-partitions/Tests/All
--- a/sql/test/merge-partitions/Tests/All
+++ b/sql/test/merge-partitions/Tests/All
@@ -3,3 +3,4 @@ mergepart01
 mergepart02
 mergepart03
 mergepart04
+mergepart05
diff --git a/sql/test/merge-partitions/Tests/mergepart05.sql 
b/sql/test/merge-partitions/Tests/mergepart05.sql
new file mode 100644
--- /dev/null
+++ b/sql/test/merge-partitions/Tests/mergepart05.sql
@@ -0,0 +1,58 @@
+CREATE MERGE TABLE listparts (b varchar(32)) PARTITION BY RANGE (b);
+CREATE TABLE subtable1 (b varchar(32));
+
+ALTER TABLE listparts ADD TABLE subtable1 AS PARTITION BETWEEN MINVALUE AND 
'something'; --error
+SELECT minimum, maximum FROM range_partitions;
+
+ALTER TABLE listparts ADD TABLE subtable1 AS PARTITION BETWEEN 'hello' AND 
'world';
+SELECT minimum, maximum FROM range_partitions;
+ALTER TABLE listparts DROP TABLE subtable1;
+
+ALTER TABLE listparts ADD TABLE subtable1 AS PARTITION BETWEEN '"hello"' AND 
'"world"';
+SELECT minimum, maximum FROM range_partitions;
+ALTER TABLE listparts DROP TABLE subtable1;
+
+ALTER TABLE listparts ADD TABLE subtable1 AS PARTITION BETWEEN 'hello"' AND 
'"world';
+SELECT minimum, maximum FROM range_partitions;
+ALTER TABLE listparts DROP TABLE subtable1;
+
+INSERT INTO subtable1 VALUES ('wrong');
+ALTER TABLE listparts ADD TABLE subtable1 AS PARTITION BETWEEN '"hello' AND 
'world"'; --error
+SELECT minimum, maximum FROM range_partitions;
+
+DROP TABLE listparts;
+DROP TABLE subtable1;
+
+CREATE MERGE TABLE testtimestamps (b timestamp) PARTITION BY RANGE (b);
+CREATE TABLE subtime (b timestamp);
+
+ALTER TABLE testtimestamps ADD TABLE subtime AS PARTITION BETWEEN timestamp 
'2002-01-01 00:00' AND timestamp '2001-01-01 00:00'; --error
+
+ALTER TABLE testtimestamps ADD TABLE subtime AS PARTITION BETWEEN MINVALUE AND 
MAXVALUE; --error
+
+INSERT INTO subtime VALUES (timestamp '2018-02-01 00:00');
+ALTER TABLE testtimestamps ADD TABLE subtime AS PARTITION BETWEEN timestamp 
'2018-01-01 00:00' AND timestamp '2019-01-01 00:00';
+ALTER TABLE testtimestamps DROP TABLE subtime;
+
+DELETE FROM subtime;
+INSERT INTO subtime VALUES (timestamp '2050-01-01 00:00');
+ALTER TABLE testtimestamps ADD TABLE subtime AS PARTITION BETWEEN timestamp 
'2048-01-01 00:00' AND timestamp '2049-01-01 00:00'; --error
+
+DROP TABLE testtimestamps;
+DROP TABLE subtime;
+
+CREATE MERGE TABLE testrangelimits (a int) PARTITION BY RANGE (a);
+CREATE TABLE sublimits (a int);
+
+ALTER TABLE testrangelimits ADD TABLE sublimits AS PARTITION BETWEEN MINVALUE 
AND MAXVALUE;
+ALTER TABLE testrangelimits DROP TABLE sublimits;
+
+INSERT INTO sublimits VALUES (0);
+ALTER TABLE testrangelimits ADD TABLE sublimits AS PARTITION BETWEEN MINVALUE 
AND 0;
+ALTER TABLE testrangelimits DROP TABLE sublimits;
+
+INSERT INTO sublimits VALUES (1);
+ALTER TABLE testrangelimits ADD TABLE sublimits AS PARTITION BETWEEN MINVALUE 
AND 0; --error
+
+DROP TABLE testrangelimits;
+DROP TABLE sublimits;
diff --git a/sql/test/merge-partitions/Tests/mergepart05.stable.err 
b/sql/test/merge-partitions/Tests/mergepart05.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/test/merge-partitions/Tests/mergepart05.stable.err
@@ -0,0 +1,60 @@
+stderr of test 'mergepart05` in directory 'sql/test/merge-partitions` itself:
+
+
+# 17:44:52 >  
+# 17:44:52 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=30658" "--set" 
"mapi_usock=/var/tmp/mtest-3693/.s.monetdb.30658" "--set" "monet_prompt=" 
"--forcemito" 
"--dbpath=/home/ferreira/repositories/MonetDB-merge-partitions/BUILD/var/MonetDB/mTests_sql_test_merge-partitions"
 "--set" "embedded_r=yes" "--set" "embedded_py=true"
+# 17:44:52 >  
+
+# builtin opt  gdk_dbpath = 
/home/ferreira/repositories/MonetDB-merge-partitions/BUILD/var/monetdb5/dbfarm/demo
+# builtin opt  gdk_debug = 0
+# builtin opt  gdk_vmtrim = no
+# builtin opt  monet_prompt = >
+# builtin opt  monet_daemon = no
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to