Changeset: 101bbd12b00d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/101bbd12b00d
Modified Files:
sql/server/rel_rel.c
sql/server/rel_unnest.c
sql/test/prepare/Tests/sqlancer_prepare.sql
sql/test/prepare/Tests/sqlancer_prepare.stable.err
sql/test/prepare/Tests/sqlancer_prepare.stable.err.int128
Branch: Jan2022
Log Message:
In some rare cases, a type must be known for an identity function call, so
disable parameters as inputs
diffs (128 lines):
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -1425,7 +1425,7 @@ static sql_rel *
_rel_add_identity(mvc *sql, sql_rel *rel, sql_exp **exp)
{
list *exps = rel_projections(sql, rel, NULL, 1, 1);
- sql_exp *e;
+ sql_exp *e = NULL;
if (list_empty(exps)) {
*exp = NULL;
@@ -1433,7 +1433,16 @@ static sql_rel *
}
if (!is_simple_project(rel->op) || need_distinct(rel) ||
!list_empty(rel->r) || rel_is_ref(rel))
rel = rel_project(sql->sa, rel, exps);
- e = rel->exps->h->data;
+ /* filter parameters out */
+ for (node *n = rel->exps->h ; n && !e ; n = n->next) {
+ sql_exp *re = n->data;
+
+ if (exp_subtype(re))
+ e = re;
+ }
+ if (!e)
+ return sql_error(sql, 10, SQLSTATE(42000) "Query projection
must have at least one parameter with known SQL type");
+
e = exp_column(sql->sa, exp_relname(e), exp_name(e), exp_subtype(e),
rel->card, has_nil(e), is_unique(e), is_intern(e));
e = exp_unop(sql->sa, e, sql_bind_func(sql, "sys", "identity",
exp_subtype(e), NULL, F_FUNC));
set_intern(e);
@@ -1468,7 +1477,8 @@ rel_add_identity2(mvc *sql, sql_rel *rel
sql_rel *o = rel;
sql_exp *id;
- p->l = _rel_add_identity(sql, l, exp);
+ if (!(p->l = _rel_add_identity(sql, l, exp)))
+ return NULL;
l = p->l;
id = exp_ref(sql, *exp);
while (o && o != l) {
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -1092,7 +1092,8 @@ push_up_groupby(mvc *sql, sql_rel *rel,
/* move groupby up, ie add attributes of left + the old
expression list */
if (l && list_length(a) > 1 && !need_distinct(l)) { /*
add identity call only if there's more than one column in the groupby */
- rel->l = rel_add_identity(sql, l, &id); /* add
identity call for group by */
+ if (!(rel->l = rel_add_identity(sql, l, &id)))
/* add identity call for group by */
+ return NULL;
assert(id);
}
@@ -1425,7 +1426,8 @@ push_up_table(mvc *sql, sql_rel *rel, li
if (l->l) {
sql_exp *tfe = tf->r;
list *ops = tfe->l;
- rel->l = d = rel_add_identity(sql, d,
&id);
+ if (!(rel->l = d =
rel_add_identity(sql, d, &id)))
+ return NULL;
id = exp_ref(sql, id);
l = tf->l = rel_crossproduct(sql->sa,
rel_dup(d), l, op_join);
set_dependent(l);
@@ -2185,7 +2187,8 @@ rewrite_or_exp(visitor *v, sql_rel *rel)
rel_destroy(rel);
rel = l;
}
- rel = rel_add_identity(v->sql, rel,
&id); /* identity function needed */
+ if (!(rel = rel_add_identity(v->sql,
rel, &id))) /* identity function needed */
+ return NULL;
const char *idrname = exp_relname(id),
*idname = exp_name(id);
list *tids = NULL, *exps =
rel_projections(v->sql, rel, NULL, 1, 1);
@@ -2701,7 +2704,8 @@ rewrite_anyequal(visitor *v, sql_rel *re
/* we introduced extra selects */
assert(is_project(rel->op) ||
is_select(rel->op));
- rsq = rel_add_identity2(sql, rsq, &rid);
+ if (!(rsq = rel_add_identity2(sql, rsq, &rid)))
+ return NULL;
rid = exp_ref(sql, rid);
if (!lsq)
@@ -2710,7 +2714,8 @@ rewrite_anyequal(visitor *v, sql_rel *re
lid = exp_atom_lng(sql->sa, 1);
} else {
exps = rel_projections(sql, lsq, NULL,
1/*keep names */, 1);
- lsq = rel_add_identity(sql, lsq, &lid);
+ if (!(lsq = rel_add_identity(sql, lsq,
&lid)))
+ return NULL;
if (!sq)
rel->l = lsq;
lid = exp_ref(sql, lid);
diff --git a/sql/test/prepare/Tests/sqlancer_prepare.sql
b/sql/test/prepare/Tests/sqlancer_prepare.sql
--- a/sql/test/prepare/Tests/sqlancer_prepare.sql
+++ b/sql/test/prepare/Tests/sqlancer_prepare.sql
@@ -73,3 +73,9 @@ PREPARE SELECT 1 FROM idontexist(?,16);
PREPARE WITH x(a) AS (SELECT ?) SELECT x.a FROM x; --error, cannot define type
for the parameter
PREPARE WITH x(a) AS (SELECT ?) SELECT CAST(x.a AS INT) FROM x;
EXEC **(1);
+
+START TRANSACTION;
+CREATE TABLE t0 (c0 INT);
+-- In order to compute the OR, an identity function call is needed, but the
projection only contains parameters
+PREPARE WITH x(x) AS (SELECT ?) SELECT 1 FROM x WHERE COALESCE(FALSE, TRUE) OR
(SELECT TRUE FROM t0); --error
+ROLLBACK;
diff --git a/sql/test/prepare/Tests/sqlancer_prepare.stable.err
b/sql/test/prepare/Tests/sqlancer_prepare.stable.err
--- a/sql/test/prepare/Tests/sqlancer_prepare.stable.err
+++ b/sql/test/prepare/Tests/sqlancer_prepare.stable.err
@@ -40,3 +40,7 @@ MAPI = (monetdb) /var/tmp/mtest-185783/
QUERY = PREPARE WITH x(a) AS (SELECT ?) SELECT x.a FROM x; --error, cannot
define type for the parameter
ERROR = !Could not determine type for argument number 1
CODE = 42000
+MAPI = (monetdb) /var/tmp/mtest-185783/.s.monetdb.32587
+QUERY = PREPARE WITH x(x) AS (SELECT ?) SELECT 1 FROM x WHERE COALESCE(FALSE,
TRUE) OR (SELECT TRUE FROM t0); --error
+ERROR = !Query projection must have at least one parameter with known SQL type
+CODE = 42000
diff --git a/sql/test/prepare/Tests/sqlancer_prepare.stable.err.int128
b/sql/test/prepare/Tests/sqlancer_prepare.stable.err.int128
--- a/sql/test/prepare/Tests/sqlancer_prepare.stable.err.int128
+++ b/sql/test/prepare/Tests/sqlancer_prepare.stable.err.int128
@@ -44,3 +44,7 @@ MAPI = (monetdb) /var/tmp/mtest-185783/
QUERY = PREPARE WITH x(a) AS (SELECT ?) SELECT x.a FROM x; --error, cannot
define type for the parameter
ERROR = !Could not determine type for argument number 1
CODE = 42000
+MAPI = (monetdb) /var/tmp/mtest-185783/.s.monetdb.32587
+QUERY = PREPARE WITH x(x) AS (SELECT ?) SELECT 1 FROM x WHERE COALESCE(FALSE,
TRUE) OR (SELECT TRUE FROM t0); --error
+ERROR = !Query projection must have at least one parameter with known SQL type
+CODE = 42000
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list