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