Merge pull request #56456 from ucasfl/fix-mysql

Fix transfer query to MySQL compatible query
This commit is contained in:
Sema Checherinda 2023-11-13 15:25:58 +01:00 committed by GitHub
commit 7f3a082c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 3 deletions

View File

@ -279,9 +279,13 @@ TEST(TransformQueryForExternalDatabase, MultipleAndSubqueries)
{
const State & state = State::instance();
check(state, 1, {"column"},
"SELECT column FROM test.table WHERE 1 = 1 AND toString(column) = '42' AND column = 42 AND left(toString(column), 10) = RIGHT(toString(column), 10) AND column IN (1, 42) AND SUBSTRING(toString(column) FROM 1 FOR 2) = 'Hello' AND column != 4",
R"(SELECT "column" FROM "test"."table" WHERE 1 AND ("column" = 42) AND ("column" IN (1, 42)) AND ("column" != 4))");
check(
state,
1,
{"column"},
"SELECT column FROM test.table WHERE 1 = 1 AND toString(column) = '42' AND column = 42 AND left(toString(column), 10) = "
"RIGHT(toString(column), 10) AND column IN (1, 42) AND SUBSTRING(toString(column) FROM 1 FOR 2) = 'Hello' AND column != 4",
R"(SELECT "column" FROM "test"."table" WHERE (1 = 1) AND ("column" = 42) AND ("column" IN (1, 42)) AND ("column" != 4))");
check(state, 1, {"column"},
"SELECT column FROM test.table WHERE toString(column) = '42' AND left(toString(column), 10) = RIGHT(toString(column), 10) AND column = 42",
R"(SELECT "column" FROM "test"."table" WHERE "column" = 42)");

View File

@ -75,6 +75,33 @@ public:
}
};
struct ReplaceLiteralToExprVisitorData
{
using TypeToVisit = ASTFunction;
void visit(ASTFunction & func, ASTPtr &) const
{
if (func.name == "and" || func.name == "or")
{
for (auto & argument : func.arguments->children)
{
auto * literal_expr = typeid_cast<ASTLiteral *>(argument.get());
UInt64 value;
if (literal_expr && literal_expr->value.tryGet<UInt64>(value) && (value == 0 || value == 1))
{
/// 1 -> 1=1, 0 -> 1=0.
if (value)
argument = makeASTFunction("equals", std::make_shared<ASTLiteral>(1), std::make_shared<ASTLiteral>(1));
else
argument = makeASTFunction("equals", std::make_shared<ASTLiteral>(1), std::make_shared<ASTLiteral>(0));
}
}
}
}
};
using ReplaceLiteralToExprVisitor = InDepthNodeVisitor<OneTypeMatcher<ReplaceLiteralToExprVisitorData>, true>;
class DropAliasesMatcher
{
public:
@ -288,6 +315,10 @@ String transformQueryForExternalDatabaseImpl(
{
replaceConstantExpressions(original_where, context, available_columns);
/// Replace like WHERE 1 AND 1 to WHERE 1 = 1 AND 1 = 1
ReplaceLiteralToExprVisitor::Data replace_literal_to_expr_data;
ReplaceLiteralToExprVisitor(replace_literal_to_expr_data).visit(original_where);
if (isCompatible(original_where))
{
select->setExpression(ASTSelectQuery::Expression::WHERE, std::move(original_where));