Changeset: 431e1b9348a1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/431e1b9348a1
Modified Files:
sql/server/rel_exp.c
sql/server/rel_optimizer.c
sql/server/rel_rel.c
sql/test/SQLancer/Tests/sqlancer17.test
Branch: default
Log Message:
Defensive lines to bind attribute expressions, fixes sqlancer crash
diffs (192 lines):
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -1678,11 +1678,13 @@ rel_find_exp_and_corresponding_rel_(sql_
ne = e;
} else if (rel_base_bind_column_(rel, e->r))
ne = e;
- } else if (rel->exps && (is_project(rel->op) ||
is_base(rel->op))) {
+ } else if ((!list_empty(rel->exps) && (is_project(rel->op) ||
is_base(rel->op))) ||
+ (!list_empty(rel->attr) &&
is_join(rel->op))) {
+ list *l = rel->attr ? rel->attr : rel->exps;
if (e->l) {
- ne = exps_bind_column2(rel->exps, e->l, e->r,
NULL);
+ ne = exps_bind_column2(l, e->l, e->r, NULL);
} else {
- ne = exps_bind_column(rel->exps, e->r, NULL,
NULL, 1);
+ ne = exps_bind_column(l, e->r, NULL, NULL, 1);
}
}
if (ne && res)
@@ -1745,8 +1747,6 @@ rel_find_exp_and_corresponding_rel(sql_r
ne = rel_find_exp_and_corresponding_rel(rel->l, e,
subexp, res, under_join);
if (!ne && is_join(rel->op))
ne = rel_find_exp_and_corresponding_rel(rel->r,
e, subexp, res, under_join);
- if (ne && under_join && is_join(rel->op))
- *under_join = true;
break;
case op_table:
case op_basetable:
@@ -1756,6 +1756,8 @@ rel_find_exp_and_corresponding_rel(sql_r
ne = rel_find_exp_and_corresponding_rel(rel->l,
e, subexp, res, under_join);
}
}
+ if (ne && under_join && is_join(rel->op))
+ *under_join = true;
return ne;
}
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -124,6 +124,12 @@ name_find_column( sql_rel *rel, const ch
case op_anti:
if (!c)
c = name_find_column( rel->l, rname, name, pnr, bt);
+ if (!c && !list_empty(rel->attr)) {
+ if (rname)
+ alias = exps_bind_column2(rel->attr, rname,
name, NULL);
+ else
+ alias = exps_bind_column(rel->attr, name, NULL,
NULL, 1);
+ }
return c;
case op_select:
case op_topn:
@@ -169,7 +175,7 @@ name_find_column( sql_rel *rel, const ch
case op_merge:
break;
}
- if (alias) { /* we found an expression with the correct name, but
+ if (alias && !is_join(rel->op)) { /* we found an expression with the
correct name, but
we need sql_columns */
if (rel->l && alias->type == e_column) /* real alias */
return name_find_column(rel->l, alias->l, alias->r,
pnr, bt);
@@ -1204,6 +1210,8 @@ exp_rename(mvc *sql, sql_exp *e, sql_rel
{
sql_exp *ne = NULL;
+ assert(is_project(f->op));
+
switch(e->type) {
case e_column:
if (e->l) {
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
@@ -336,6 +336,11 @@ rel_bind_column( mvc *sql, sql_rel *rel,
if (e1 && e2 && !is_dependent(rel))
return sql_error(sql, ERR_AMBIGUOUS,
SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
}
+ if (!e1 && !e2 && !list_empty(rel->attr)) {
+ e1 = exps_bind_column(rel->attr, cname, &ambiguous,
&multi, no_tname);
+ if (ambiguous || multi)
+ return sql_error(sql, ERR_AMBIGUOUS,
SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
+ }
res = e1 ? e1 : e2;
if (res)
set_not_unique(res);
@@ -417,6 +422,12 @@ rel_bind_column2( mvc *sql, sql_rel *rel
if (e && (is_left(rel->op) || is_full(rel->op)))
set_has_nil(e);
}
+ if (!e && !list_empty(rel->attr)) {
+ e = exps_bind_column2(rel->attr, tname, cname, &multi);
+ if (multi)
+ return sql_error(sql, ERR_AMBIGUOUS,
SQLSTATE(42000) "SELECT: identifier '%s.%s' ambiguous",
+ tname, cname);
+ }
if (e)
set_not_unique(e);
return e;
@@ -1088,6 +1099,12 @@ rel_bind_path_(mvc *sql, sql_rel *rel, s
found = rel_bind_path_(sql, rel->r, e, path);
if (!found)
found = rel_bind_path_(sql, rel->l, e, path);
+ if (!found && !list_empty(rel->attr)) {
+ if (e->l && exps_bind_column2(rel->attr, e->l, e->r,
NULL))
+ found = 1;
+ if (!found && !e->l && exps_bind_column(rel->attr,
e->r, NULL, NULL, 1))
+ found = 1;
+ }
break;
case op_semi:
case op_anti:
@@ -1487,20 +1504,27 @@ rel_add_identity2(mvc *sql, sql_rel *rel
return _rel_add_identity(sql, rel, exp);
}
+static sql_exp *
+rel_find_column_(sql_allocator *sa, list *exps, const char *tname, const char
*cname)
+{
+ int ambiguous = 0, multi = 0;
+ sql_exp *e = exps_bind_column2(exps, tname, cname, &multi);
+ if (!e && cname[0] == '%' && !tname)
+ e = exps_bind_column(exps, cname, &ambiguous, &multi, 0);
+ if (e && !ambiguous && !multi)
+ return exp_alias(sa, exp_relname(e), exp_name(e),
exp_relname(e), cname, exp_subtype(e), e->card, has_nil(e), is_unique(e),
is_intern(e));
+ return NULL;
+}
+
sql_exp *
-rel_find_column( sql_allocator *sa, sql_rel *rel, const char *tname, const
char *cname )
+rel_find_column(sql_allocator *sa, sql_rel *rel, const char *tname, const char
*cname )
{
+ sql_exp *e = NULL;
+
if (!rel)
return NULL;
-
- if (rel->exps && (is_project(rel->op) || is_base(rel->op))) {
- int ambiguous = 0, multi = 0;
- sql_exp *e = exps_bind_column2(rel->exps, tname, cname, &multi);
- if (!e && cname[0] == '%' && !tname)
- e = exps_bind_column(rel->exps, cname, &ambiguous,
&multi, 0);
- if (e && !ambiguous && !multi)
- return exp_alias(sa, exp_relname(e), exp_name(e),
exp_relname(e), cname, exp_subtype(e), e->card, has_nil(e), is_unique(e),
is_intern(e));
- }
+ if (rel->exps && (is_project(rel->op) || is_base(rel->op)) && (e =
rel_find_column_(sa, rel->exps, tname, cname)))
+ return e;
if ((is_simple_project(rel->op) || is_groupby(rel->op)) && rel->l) {
if (!is_processed(rel))
return rel_find_column(sa, rel->l, tname, cname);
@@ -1508,7 +1532,7 @@ rel_find_column( sql_allocator *sa, sql_
assert(is_processed(rel));
return NULL;
} else if (is_join(rel->op)) {
- sql_exp *e = rel_find_column(sa, rel->l, tname, cname);
+ e = rel_find_column(sa, rel->l, tname, cname);
if (e && (is_right(rel->op) || is_full(rel->op)))
set_has_nil(e);
@@ -1517,6 +1541,8 @@ rel_find_column( sql_allocator *sa, sql_
if (e && (is_left(rel->op) || is_full(rel->op)))
set_has_nil(e);
}
+ if (!e && !list_empty(rel->attr))
+ e = rel_find_column_(sa, rel->attr, tname, cname);
if (e)
set_not_unique(e);
return e;
diff --git a/sql/test/SQLancer/Tests/sqlancer17.test
b/sql/test/SQLancer/Tests/sqlancer17.test
--- a/sql/test/SQLancer/Tests/sqlancer17.test
+++ b/sql/test/SQLancer/Tests/sqlancer17.test
@@ -566,6 +566,19 @@ statement ok
START TRANSACTION
statement ok
+CREATE TABLE t2 (c0 VARCHAR(217))
+
+query I nosort
+SELECT 1 FROM t2 WHERE (SELECT tx.c0 = ANY(SELECT 'a' FROM t2) FROM t2 AS tx)
+----
+
+statement ok
+ROLLBACK
+
+statement ok
+START TRANSACTION
+
+statement ok
CREATE TABLE "rt0" ("c0" REAL,"c1" DECIMAL(18,3))
statement ok
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list