mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-21 09:10:48 +00:00
Fixed issue #3540 (in progress)
This commit is contained in:
parent
5352b53671
commit
dd9e993a87
@ -367,6 +367,6 @@ if (ENABLE_TESTS AND USE_GTEST)
|
||||
# attach all dbms gtest sources
|
||||
grep_gtest_sources(${ClickHouse_SOURCE_DIR}/dbms dbms_gtest_sources)
|
||||
add_executable(unit_tests_dbms ${dbms_gtest_sources})
|
||||
target_link_libraries(unit_tests_dbms PRIVATE ${GTEST_BOTH_LIBRARIES} dbms clickhouse_common_zookeeper)
|
||||
target_link_libraries(unit_tests_dbms PRIVATE ${GTEST_BOTH_LIBRARIES} clickhouse_functions dbms clickhouse_common_zookeeper)
|
||||
add_check(unit_tests_dbms)
|
||||
endif ()
|
||||
|
@ -12,15 +12,25 @@
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Databases/DatabaseMemory.h>
|
||||
#include <Storages/StorageMemory.h>
|
||||
#include <Functions/registerFunctions.h>
|
||||
|
||||
|
||||
using namespace DB;
|
||||
|
||||
|
||||
void check(const std::string & query, const std::string & expected, const Context & context, const NamesAndTypesList & columns)
|
||||
{
|
||||
ParserSelectQuery parser;
|
||||
ASTPtr ast = parseQuery(parser, query, 1000);
|
||||
std::string transformed_query = transformQueryForExternalDatabase(*ast, columns, IdentifierQuotingStyle::DoubleQuotes, "test", "table", context);
|
||||
|
||||
EXPECT_EQ(transformed_query, expected);
|
||||
}
|
||||
|
||||
|
||||
TEST(transformQueryForExternalDatabase, InWithSingleElement)
|
||||
{
|
||||
using namespace DB;
|
||||
|
||||
std::string query = "SELECT column FROM test.table WHERE 1 IN (1)"; /// Parentheses around rhs of IN must be retained after transformation.
|
||||
ParserSelectQuery parser;
|
||||
ASTPtr ast = parseQuery(parser, query, 1000);
|
||||
registerFunctions();
|
||||
|
||||
Context context = Context::createGlobal();
|
||||
DatabasePtr database = std::make_shared<DatabaseMemory>("test");
|
||||
@ -29,7 +39,6 @@ TEST(transformQueryForExternalDatabase, InWithSingleElement)
|
||||
context.addDatabase("test", database);
|
||||
context.setCurrentDatabase("test");
|
||||
|
||||
std::string transformed_query = transformQueryForExternalDatabase(*ast, columns, IdentifierQuotingStyle::DoubleQuotes, "test", "table", context);
|
||||
|
||||
EXPECT_EQ(transformed_query, "SELECT \"column\" FROM \"test\".\"table\" WHERE 1 IN (1)");
|
||||
check("SELECT column FROM test.table WHERE 1 IN (1)", "SELECT \"column\" FROM \"test\".\"table\" WHERE 1 IN (1)", context, columns);
|
||||
check("SELECT column FROM test.table WHERE column IN (1, 2)", "SELECT \"column\" FROM \"test\".\"table\" WHERE \"column\" IN (1, 2)", context, columns);
|
||||
}
|
||||
|
@ -16,6 +16,11 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
static void replaceConstFunction(IAST & node, const Context & context, const NamesAndTypesList & all_columns)
|
||||
{
|
||||
for (size_t i = 0; i < node.children.size(); ++i)
|
||||
@ -44,19 +49,33 @@ static bool isCompatible(const IAST & node)
|
||||
{
|
||||
if (const auto * function = node.as<ASTFunction>())
|
||||
{
|
||||
if (function->parameters)
|
||||
return false;
|
||||
|
||||
if (!function->arguments)
|
||||
throw Exception("Logical error: function->arguments is not set", ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
String name = function->name;
|
||||
|
||||
if (!(name == "and"
|
||||
|| name == "or"
|
||||
|| name == "not"
|
||||
|| name == "equals"
|
||||
|| name == "notEquals"
|
||||
|| name == "less"
|
||||
|| name == "greater"
|
||||
|| name == "lessOrEquals"
|
||||
|| name == "greaterOrEquals"
|
||||
|| name == "like"
|
||||
|| name == "notLike"
|
||||
|| name == "in"
|
||||
|| name == "greater"
|
||||
|| name == "less"
|
||||
|| name == "lessOrEquals"
|
||||
|| name == "greaterOrEquals"))
|
||||
|| name == "notIn"
|
||||
|| name == "tuple"))
|
||||
return false;
|
||||
|
||||
/// A tuple with zero or one elements is represented by a function tuple(x) and is not compatible,
|
||||
/// but a normal tuple with more than one element is represented as a parenthesed expression (x, y) and is perfectly compatible.
|
||||
if (name == "tuple" && function->arguments->children.size() <= 1)
|
||||
return false;
|
||||
|
||||
for (const auto & expr : function->arguments->children)
|
||||
|
Loading…
Reference in New Issue
Block a user