diff --git a/src/Interpreters/RewriteArrayExistsFunctionVisitor.cpp b/src/Interpreters/RewriteArrayExistsFunctionVisitor.cpp index 8d1a37647ad..eb392cd90a8 100644 --- a/src/Interpreters/RewriteArrayExistsFunctionVisitor.cpp +++ b/src/Interpreters/RewriteArrayExistsFunctionVisitor.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace DB { @@ -76,4 +77,22 @@ void RewriteArrayExistsFunctionMatcher::visit(const ASTFunction & func, ASTPtr & } } +bool RewriteArrayExistsFunctionMatcher::needChildVisit(const ASTPtr & ast, const ASTPtr & child) +{ + /// SELECT ... JOIN ... ON arrayExists(x -> x = 1, arr) + /// A JOIN on expression is invalid, ignore it to avoid segmentation fault + + if (auto * join = ast->as()) + { + if (auto * func = child->as()) + { + if (func->name == "arrayExists") + return false; + } + } + + return true; +} + + } diff --git a/src/Interpreters/RewriteArrayExistsFunctionVisitor.h b/src/Interpreters/RewriteArrayExistsFunctionVisitor.h index 763dd2d4df2..ea9363ccee9 100644 --- a/src/Interpreters/RewriteArrayExistsFunctionVisitor.h +++ b/src/Interpreters/RewriteArrayExistsFunctionVisitor.h @@ -18,7 +18,7 @@ public: static void visit(ASTPtr & ast, Data &); static void visit(const ASTFunction &, ASTPtr & ast, Data &); - static bool needChildVisit(const ASTPtr &, const ASTPtr &) { return true; } + static bool needChildVisit(const ASTPtr & ast, const ASTPtr & child); }; using RewriteArrayExistsFunctionVisitor = InDepthNodeVisitor; diff --git a/tests/queries/0_stateless/02834_array_exists_segfault.reference b/tests/queries/0_stateless/02834_array_exists_segfault.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/02834_array_exists_segfault.sql b/tests/queries/0_stateless/02834_array_exists_segfault.sql new file mode 100644 index 00000000000..e691cf36505 --- /dev/null +++ b/tests/queries/0_stateless/02834_array_exists_segfault.sql @@ -0,0 +1,2 @@ +CREATE TABLE 02834_t (id UInt64, arr Array(UInt64)) ENGINE = MergeTree ORDER BY id; +WITH subquery AS (SELECT []) SELECT t.* FROM 02834_t AS t JOIN subquery ON arrayExists(x -> x = 1, t.arr); -- { serverError INVALID_JOIN_ON_EXPRESSION }