diff --git a/src/Storages/tests/gtest_transform_query_for_external_database.cpp b/src/Storages/tests/gtest_transform_query_for_external_database.cpp index 749a154c19d..1b2a4187c94 100644 --- a/src/Storages/tests/gtest_transform_query_for_external_database.cpp +++ b/src/Storages/tests/gtest_transform_query_for_external_database.cpp @@ -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)"); diff --git a/src/Storages/transformQueryForExternalDatabase.cpp b/src/Storages/transformQueryForExternalDatabase.cpp index 84a696a1e9c..fd3c47e0e3f 100644 --- a/src/Storages/transformQueryForExternalDatabase.cpp +++ b/src/Storages/transformQueryForExternalDatabase.cpp @@ -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(argument.get()); + UInt64 value; + if (literal_expr && literal_expr->value.tryGet(value) && (value == 0 || value == 1)) + { + /// 1 -> 1=1, 0 -> 1=0. + if (value) + argument = makeASTFunction("equals", std::make_shared(1), std::make_shared(1)); + else + argument = makeASTFunction("equals", std::make_shared(1), std::make_shared(0)); + } + } + } + } +}; + +using ReplaceLiteralToExprVisitor = InDepthNodeVisitor, 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));