Backport #72179 to 24.9: Fix bugs when using UDF in join on expression with the old analyzer

This commit is contained in:
robot-clickhouse 2024-11-22 20:09:25 +00:00
parent c04c150ae3
commit d9c6d915ec
10 changed files with 88 additions and 19 deletions

View File

@ -12,7 +12,7 @@ tests/ci/cancel_and_rerun_workflow_lambda/app.py
- Backward Incompatible Change
- Build/Testing/Packaging Improvement
- Documentation (changelog entry is not required)
- Critical Bug Fix (crash, LOGICAL_ERROR, data loss, RBAC)
- Critical Bug Fix (crash, data loss, RBAC) or LOGICAL_ERROR
- Bug Fix (user-visible misbehavior in an official stable release)
- CI Fix or Improvement (changelog entry is not required)
- Not for changelog (changelog entry is not required)

View File

@ -26,14 +26,6 @@ void UserDefinedSQLFunctionVisitor::visit(ASTPtr & ast)
{
chassert(ast);
if (const auto * function = ast->template as<ASTFunction>())
{
std::unordered_set<std::string> udf_in_replace_process;
auto replace_result = tryToReplaceFunction(*function, udf_in_replace_process);
if (replace_result)
ast = replace_result;
}
for (auto & child : ast->children)
{
if (!child)
@ -48,6 +40,14 @@ void UserDefinedSQLFunctionVisitor::visit(ASTPtr & ast)
if (new_ptr != old_ptr)
ast->updatePointerToChild(old_ptr, new_ptr);
}
if (const auto * function = ast->template as<ASTFunction>())
{
std::unordered_set<std::string> udf_in_replace_process;
auto replace_result = tryToReplaceFunction(*function, udf_in_replace_process);
if (replace_result)
ast = replace_result;
}
}
void UserDefinedSQLFunctionVisitor::visit(IAST * ast)

View File

@ -70,7 +70,7 @@ struct JoinedElement
join->strictness = JoinStrictness::All;
join->on_expression = on_expression;
join->children.push_back(join->on_expression);
join->children = {join->on_expression};
return true;
}

View File

@ -130,12 +130,25 @@ void ASTColumnDeclaration::formatImpl(const FormatSettings & format_settings, Fo
void ASTColumnDeclaration::forEachPointerToChild(std::function<void(void **)> f)
{
f(reinterpret_cast<void **>(&default_expression));
f(reinterpret_cast<void **>(&comment));
f(reinterpret_cast<void **>(&codec));
f(reinterpret_cast<void **>(&statistics_desc));
f(reinterpret_cast<void **>(&ttl));
f(reinterpret_cast<void **>(&collation));
f(reinterpret_cast<void **>(&settings));
auto visit_child = [&f](ASTPtr & member)
{
IAST * new_member_ptr = member.get();
f(reinterpret_cast<void **>(&new_member_ptr));
if (new_member_ptr != member.get())
{
if (new_member_ptr)
member = new_member_ptr->ptr();
else
member.reset();
}
};
visit_child(default_expression);
visit_child(comment);
visit_child(codec);
visit_child(statistics_desc);
visit_child(ttl);
visit_child(collation);
visit_child(settings);
}
}

View File

@ -61,6 +61,29 @@ ASTPtr ASTTableJoin::clone() const
return res;
}
void ASTTableJoin::forEachPointerToChild(std::function<void(void **)> f)
{
IAST * new_using_expression_list = using_expression_list.get();
f(reinterpret_cast<void **>(&new_using_expression_list));
if (new_using_expression_list != using_expression_list.get())
{
if (new_using_expression_list)
using_expression_list = new_using_expression_list->ptr();
else
using_expression_list.reset();
}
IAST * new_on_expression = on_expression.get();
f(reinterpret_cast<void **>(&new_on_expression));
if (new_on_expression != on_expression.get())
{
if (new_on_expression)
on_expression = new_on_expression->ptr();
else
on_expression.reset();
}
}
void ASTArrayJoin::updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const
{
hash_state.update(kind);

View File

@ -80,6 +80,9 @@ struct ASTTableJoin : public IAST
void formatImplAfterTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state, bool ignore_aliases) const override;
protected:
void forEachPointerToChild(std::function<void(void **)> f) override;
};
/// Specification of ARRAY JOIN.

View File

@ -56,7 +56,9 @@ LABEL_CATEGORIES = {
"Bug Fix (user-visible misbehaviour in official stable or prestable release)",
"Bug Fix (user-visible misbehavior in official stable or prestable release)",
],
"pr-critical-bugfix": ["Critical Bug Fix (crash, LOGICAL_ERROR, data loss, RBAC)"],
"pr-critical-bugfix": [
"Critical Bug Fix (crash, data loss, RBAC) or LOGICAL_ERROR"
],
"pr-build": [
"Build/Testing/Packaging Improvement",
"Build Improvement",

View File

@ -1,4 +1,4 @@
-- Tags: no-parallel
-- Tags: no-fasttest, no-parallel
-- Tag no-parallel -- due to failpoints
create table data_r1 (key Int, value String) engine=ReplicatedMergeTree('/tables/{database}/data', '{table}') order by tuple();

View File

@ -0,0 +1,7 @@
SELECT 1
FROM
(
SELECT 1 AS c0
) AS v0
ALL INNER JOIN v0 AS vx ON c0 = vx.c0
1

View File

@ -0,0 +1,21 @@
#!/usr/bin/env bash
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CUR_DIR"/../shell_config.sh
$CLICKHOUSE_CLIENT -q "
CREATE VIEW v0 AS SELECT 1 AS c0;
CREATE FUNCTION ${CLICKHOUSE_DATABASE}_second AS (x, y) -> y;
CREATE FUNCTION ${CLICKHOUSE_DATABASE}_equals AS (x, y) -> x = y;
SET optimize_rewrite_array_exists_to_has = 1;
EXPLAIN SYNTAX SELECT 1 FROM v0 JOIN v0 vx ON ${CLICKHOUSE_DATABASE}_second(v0.c0, vx.c0); -- { serverError INVALID_JOIN_ON_EXPRESSION }
EXPLAIN SYNTAX SELECT 1 FROM v0 JOIN v0 vx ON ${CLICKHOUSE_DATABASE}_equals(v0.c0, vx.c0);
SELECT 1 FROM v0 JOIN v0 vx ON ${CLICKHOUSE_DATABASE}_equals(v0.c0, vx.c0);
DROP view v0;
DROP FUNCTION ${CLICKHOUSE_DATABASE}_second;
DROP FUNCTION ${CLICKHOUSE_DATABASE}_equals;
"