ISSUES-4006 remove unused code

This commit is contained in:
zhang2014 2020-07-01 13:56:24 +08:00
parent 54c3db0567
commit 1583f67681
7 changed files with 26 additions and 465 deletions

View File

@ -16,7 +16,6 @@
# include <Formats/MySQLBlockInputStream.h>
# include <IO/ReadBufferFromString.h>
# include <Interpreters/Context.h>
# include <Interpreters/MySQL/CreateQueryVisitor.h>
# include <Interpreters/executeQuery.h>
# include <Parsers/parseQuery.h>
# include <Storages/StorageMergeTree.h>

View File

@ -14,7 +14,6 @@
# include <Databases/IDatabase.h>
# include <Databases/MySQL/MaterializeMetadata.h>
# include <Databases/MySQL/MaterializeMySQLSettings.h>
# include <Interpreters/MySQL/CreateQueryVisitor.h>
# include <Parsers/ASTCreateQuery.h>
# include <mysqlxx/Pool.h>
# include <mysqlxx/PoolWithFailover.h>

View File

@ -1,178 +0,0 @@
#include <IO/Operators.h>
#include <Interpreters/MySQL/CreateQueryVisitor.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/MySQL/ASTDeclareIndex.h>
#include <Parsers/MySQL/ASTDeclareOption.h>
#include <Parsers/queryToString.h>
#include <Poco/String.h>
#include <DataTypes/DataTypeFactory.h>
#include <DataTypes/DataTypeNullable.h>
#include <Interpreters/ExpressionActions.h>
#include <Interpreters/InterpreterCreateQuery.h>
namespace DB
{
namespace ErrorCodes
{
extern const int UNKNOWN_TYPE;
extern const int NOT_IMPLEMENTED;
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
}
namespace MySQLVisitor
{
void CreateQueryMatcher::visit(ASTPtr & ast, Data & data)
{
if (auto * t = ast->as<MySQLParser::ASTCreateQuery>())
visit(*t, ast, data);
}
void CreateQueryMatcher::visit(const MySQLParser::ASTCreateQuery & create, const ASTPtr &, Data & data)
{
if (create.like_table)
throw Exception("Cannot convert create like statement to ClickHouse SQL", ErrorCodes::NOT_IMPLEMENTED);
if (create.columns_list)
visit(*create.columns_list->as<MySQLParser::ASTCreateDefines>(), create.columns_list, data);
if (create.partition_options)
visit(*create.partition_options->as<MySQLParser::ASTDeclarePartitionOptions>(), create.partition_options, data);
data.table_name = create.table;
data.database_name = create.database;
data.if_not_exists = create.if_not_exists;
}
void CreateQueryMatcher::visit(const MySQLParser::ASTDeclareIndex & declare_index, const ASTPtr &, Data & data)
{
if (startsWith(declare_index.index_type, "PRIMARY_KEY_"))
data.addPrimaryKey(declare_index.index_columns);
}
void CreateQueryMatcher::visit(const MySQLParser::ASTCreateDefines & create_defines, const ASTPtr &, Data & data)
{
if (!create_defines.columns || create_defines.columns->children.empty())
throw Exception("Missing definition of columns.", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED);
if (create_defines.indices)
{
for (auto & index : create_defines.indices->children)
visit(*index->as<MySQLParser::ASTDeclareIndex>(), index, data);
}
for (auto & column : create_defines.columns->children)
visit(*column->as<MySQLParser::ASTDeclareColumn>(), column, data);
}
void CreateQueryMatcher::visit(const MySQLParser::ASTDeclareColumn & declare_column, const ASTPtr &, Data & data)
{
if (!declare_column.data_type)
throw Exception("Missing type in definition of column.", ErrorCodes::UNKNOWN_TYPE);
bool is_nullable = true;
if (declare_column.column_options)
{
if (MySQLParser::ASTDeclareOptions * options = declare_column.column_options->as<MySQLParser::ASTDeclareOptions>())
{
if (options->changes.count("is_null"))
is_nullable = options->changes["is_null"]->as<ASTLiteral>()->value.safeGet<UInt64>();
if (options->changes.count("primary_key"))
data.addPrimaryKey(std::make_shared<ASTIdentifier>(declare_column.name));
/* if (options->changes.count("is_unsigned"))
is_unsigned = options->changes["is_unsigned"]->as<ASTLiteral>()->value.safeGet<UInt64>();
else if (options->changes.count("zero_fill"))
is_unsigned = options->changes["zero_fill"]->as<ASTLiteral>()->value.safeGet<UInt64>();*/
}
}
data.columns_name_and_type.emplace_back(declare_column.name, DataTypeFactory::instance().get(
(is_nullable ? "Nullable(" : "") + queryToString(declare_column.data_type) + (is_nullable ? ")" : "")));
}
void CreateQueryMatcher::visit(const MySQLParser::ASTDeclarePartitionOptions & declare_partition_options, const ASTPtr &, Data & data)
{
data.addPartitionKey(declare_partition_options.partition_expression);
}
void CreateQueryMatcher::Data::addPrimaryKey(const ASTPtr & primary_key)
{
if (const auto & function_index_columns = primary_key->as<ASTFunction>())
{
if (function_index_columns->name != "tuple")
throw Exception("Unable to parse function primary key from MySQL.", ErrorCodes::NOT_IMPLEMENTED);
for (const auto & index_column : function_index_columns->arguments->children)
primary_keys.emplace_back(index_column);
}
else if (const auto & expression_index_columns = primary_key->as<ASTExpressionList>())
{
for (const auto & index_column : expression_index_columns->children)
primary_keys.emplace_back(index_column);
}
else
primary_keys.emplace_back(primary_key);
}
void CreateQueryMatcher::Data::addPartitionKey(const ASTPtr & partition_key)
{
if (const auto & function_partition_columns = partition_key->as<ASTFunction>())
{
if (function_partition_columns->name != "tuple")
throw Exception("Unable to parse function partition by from MySQL.", ErrorCodes::NOT_IMPLEMENTED);
for (const auto & partition_column : function_partition_columns->arguments->children)
partition_keys.emplace_back(partition_column);
}
else if (const auto & expression_partition_columns = partition_key->as<ASTExpressionList>())
{
for (const auto & partition_column : expression_partition_columns->children)
partition_keys.emplace_back(partition_column);
}
else
partition_keys.emplace_back(partition_key);
}
}
bool MySQLTableStruct::operator==(const MySQLTableStruct & other) const
{
const auto & this_expression = std::make_shared<ASTExpressionList>();
this_expression->children.insert(this_expression->children.begin(), primary_keys.begin(), primary_keys.end());
this_expression->children.insert(this_expression->children.begin(), partition_keys.begin(), partition_keys.end());
const auto & other_expression = std::make_shared<ASTExpressionList>();
other_expression->children.insert(other_expression->children.begin(), other.primary_keys.begin(), other.primary_keys.end());
other_expression->children.insert(other_expression->children.begin(), other.partition_keys.begin(), other.partition_keys.end());
return queryToString(this_expression) == queryToString(other_expression) && columns_name_and_type == other.columns_name_and_type;
}
MySQLTableStruct visitCreateQuery(ASTPtr & create_query, const Context & context, const std::string & new_database)
{
create_query->as<MySQLParser::ASTCreateQuery>()->database = new_database;
MySQLVisitor::CreateQueryVisitor::Data table_struct(context);
MySQLVisitor::CreateQueryVisitor visitor(table_struct);
visitor.visit(create_query);
return std::move(table_struct);
}
MySQLTableStruct visitCreateQuery(const String & create_query, const Context & context, const std::string & new_database)
{
MySQLParser::ParserCreateQuery p_create_query;
ASTPtr ast_create_query = parseQuery(p_create_query, create_query.data(), create_query.data() + create_query.size(), "", 0, 0);
if (!ast_create_query || !ast_create_query->as<MySQLParser::ASTCreateQuery>())
throw Exception("LOGICAL ERROR: ast cannot cast to MySQLParser::ASTCreateQuery.", ErrorCodes::LOGICAL_ERROR);
return visitCreateQuery(ast_create_query, context, new_database);
}
}

View File

@ -1,78 +0,0 @@
#pragma once
#include <Core/NamesAndTypes.h>
#include <Interpreters/InDepthNodeVisitor.h>
#include <Parsers/MySQL/ASTCreateDefines.h>
#include <Parsers/MySQL/ASTCreateQuery.h>
#include <Parsers/MySQL/ASTDeclareColumn.h>
#include <Parsers/MySQL/ASTDeclareIndex.h>
#include <Parsers/MySQL/ASTDeclarePartitionOptions.h>
#include <Parsers/parseQuery.h>
namespace DB
{
struct MySQLTableStruct
{
bool if_not_exists;
String table_name;
String database_name;
ASTs primary_keys;
ASTs partition_keys;
NamesAndTypesList columns_name_and_type;
MySQLTableStruct() {}
MySQLTableStruct(const ASTs & primary_keys_, const ASTs & partition_keys_, const NamesAndTypesList & columns_name_and_type_)
: primary_keys(primary_keys_), partition_keys(partition_keys_), columns_name_and_type(columns_name_and_type_)
{}
bool operator==(const MySQLTableStruct & other) const;
};
namespace MySQLVisitor
{
/// Convert MySQL CREATE query to https://clickhouse.tech/docs/en/sql-reference/statements/create/
class CreateQueryMatcher
{
public:
using Visitor = InDepthNodeVisitor<CreateQueryMatcher, false>;
struct Data : public MySQLTableStruct
{
const Context & context;
size_t max_ranges;
size_t min_rows_pre_range;
Data(const Context & context_) : MySQLTableStruct(), context(context_) {}
void addPrimaryKey(const ASTPtr & primary_key);
void addPartitionKey(const ASTPtr & partition_key);
};
static void visit(ASTPtr & ast, Data & data);
static bool needChildVisit(ASTPtr &, const ASTPtr &) { return false; }
private:
static void visit(const MySQLParser::ASTCreateQuery & create, const ASTPtr &, Data & data);
static void visit(const MySQLParser::ASTDeclareIndex & declare_index, const ASTPtr &, Data & data);
static void visit(const MySQLParser::ASTCreateDefines & create_defines, const ASTPtr &, Data & data);
static void visit(const MySQLParser::ASTDeclareColumn & declare_column, const ASTPtr &, Data & data);
static void visit(const MySQLParser::ASTDeclarePartitionOptions & declare_partition_options, const ASTPtr &, Data & data);
};
using CreateQueryVisitor = CreateQueryMatcher::Visitor;
}
MySQLTableStruct visitCreateQuery(ASTPtr & create_query, const Context & context, const std::string & new_database);
MySQLTableStruct visitCreateQuery(const String & create_query, const Context & context, const std::string & new_database);
}

View File

@ -4,13 +4,14 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/queryToString.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/MySQL/ASTCreateQuery.h>
#include <Parsers/MySQL/ASTDeclareColumn.h>
#include <Parsers/MySQL/ASTDeclareOption.h>
#include <Parsers/MySQL/ASTCreateDefines.h>
#include <DataTypes/DataTypeFactory.h>
#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/DataTypeNullable.h>
#include <Interpreters/InterpreterCreateQuery.h>
#include <Interpreters/executeQuery.h>
@ -37,7 +38,7 @@ InterpreterMySQLCreateQuery::InterpreterMySQLCreateQuery(const ASTPtr & query_pt
BlockIO InterpreterMySQLCreateQuery::execute()
{
return executeQuery(getRewrittenQuery(), context, true);
return InterpreterCreateQuery(getRewrittenQuery(), context).execute();
}
static inline NamesAndTypesList getColumnsList(ASTExpressionList * columns_define)
@ -234,49 +235,54 @@ static ASTPtr getOrderByPolicy(
return order_by_expression;
}
String InterpreterMySQLCreateQuery::getRewrittenQuery()
ASTPtr InterpreterMySQLCreateQuery::getRewrittenQuery()
{
std::stringstream rewritten_query;
auto rewritten_query = std::make_shared<ASTCreateQuery>();
const auto & create_query = query_ptr->as<MySQLParser::ASTCreateQuery &>();
/// This is dangerous, because the like table may not exists in ClickHouse
if (create_query.like_table)
throw Exception("Cannot convert create like statement to ClickHouse SQL", ErrorCodes::NOT_IMPLEMENTED);
rewritten_query << "CREATE TABLE " << (create_query.if_not_exists ? "IF NOT EXISTS" : "") << backQuoteIfNeed(create_query.table);
const auto & create_defines = create_query.columns_list->as<MySQLParser::ASTCreateDefines>();
if (!create_defines || !create_defines->columns || create_defines->columns->children.empty())
throw Exception("Missing definition of columns.", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED);
std::cout << "InterpreterMySQLCreateQuery::getRewrittenQuery() -1 \n";
NamesAndTypesList columns_name_and_type = getColumnsList(create_defines->columns);
std::cout << "InterpreterMySQLCreateQuery::getRewrittenQuery() -2 \n";
const auto & [primary_keys, unique_keys, keys, increment_columns] = getKeys(create_defines->columns, create_defines->indices, context, columns_name_and_type);
std::cout << "InterpreterMySQLCreateQuery::getRewrittenQuery() -3 \n";
if (primary_keys.empty())
throw Exception(
"The " + backQuoteIfNeed(create_query.database) + "." + backQuoteIfNeed(create_query.table)
+ " cannot be materialized, because there is no primary keys.",
ErrorCodes::NOT_IMPLEMENTED);
throw Exception("The " + backQuoteIfNeed(create_query.database) + "." + backQuoteIfNeed(create_query.table)
+ " cannot be materialized, because there is no primary keys.", ErrorCodes::NOT_IMPLEMENTED);
auto columns = std::make_shared<ASTColumns>();
/// Add _sign and _version column.
String sign_column_name = getUniqueColumnName(columns_name_and_type, "_sign");
String version_column_name = getUniqueColumnName(columns_name_and_type, "_version");
rewritten_query << "(" << queryToString(InterpreterCreateQuery::formatColumns(columns_name_and_type))
<< ", " << sign_column_name << " Int8, " << version_column_name << " UInt64" << ") "
<< "ENGINE = ReplacingMergeTree(" + version_column_name + ")";
columns_name_and_type.emplace_back(NameAndTypePair{sign_column_name, std::make_shared<DataTypeInt8>()});
columns_name_and_type.emplace_back(NameAndTypePair{version_column_name, std::make_shared<DataTypeUInt64>()});
columns->set(columns->columns, InterpreterCreateQuery::formatColumns(columns_name_and_type));
auto storage = std::make_shared<ASTStorage>();
/// The `partition by` expression must use primary keys, otherwise the primary keys will not be merge.
if (ASTPtr partition_expression = getPartitionPolicy(primary_keys))
rewritten_query << " PARTITION BY " << queryToString(partition_expression);
storage->set(storage->partition_by, partition_expression);
/// The `order by` expression must use primary keys, otherwise the primary keys will not be merge.
if (ASTPtr order_by_expression = getOrderByPolicy(primary_keys, unique_keys, keys, increment_columns))
rewritten_query << " ORDER BY " << queryToString(order_by_expression);
storage->set(storage->order_by, order_by_expression);
return rewritten_query.str();
storage->set(storage->engine, makeASTFunction("ReplacingMergeTree", std::make_shared<ASTIdentifier>(version_column_name)));
rewritten_query->table = create_query.table;
rewritten_query->if_not_exists = create_query.if_not_exists;
rewritten_query->set(rewritten_query->storage, storage);
rewritten_query->set(rewritten_query->columns_list, columns);
return rewritten_query;
}
}

View File

@ -22,7 +22,7 @@ private:
ASTPtr query_ptr;
Context & context;
String getRewrittenQuery();
ASTPtr getRewrittenQuery();
};
}

View File

@ -1,187 +0,0 @@
#include <DataTypes/DataTypeFactory.h>
#include <IO/WriteBufferFromString.h>
#include <Interpreters/Context.h>
#include <Interpreters/MySQL/CreateQueryVisitor.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/MySQL/ASTCreateQuery.h>
#include <Parsers/parseQuery.h>
#include <gtest/gtest.h>
using namespace DB;
using namespace MySQLParser;
using namespace MySQLVisitor;
static DataTypePtr getType(const String & data_type)
{
return DataTypeFactory::instance().get(data_type);
}
static ContextShared * contextShared()
{
static SharedContextHolder shared = Context::createShared();
return shared.get();
}
static MySQLTableStruct visitQuery(const String & query)
{
ParserCreateQuery p_create_query;
ASTPtr ast = parseQuery(p_create_query, query.data(), query.data() + query.size(), "", 0, 0);
CreateQueryVisitor::Data data(Context::createGlobal(contextShared()));
data.max_ranges = 1000;
data.min_rows_pre_range = 1000000;
CreateQueryVisitor visitor(data);
visitor.visit(ast);
return std::move(data);
}
TEST(CreateQueryVisitor, TestWithNumberColumnsType)
{
EXPECT_EQ(
visitQuery("CREATE TABLE test(a tinyint, b SMALLINT, c MEDIUMINT, d INT, e INTEGER, f BIGINT, g DECIMAL, h DEC, i NUMERIC, j "
"FIXED, k FLOAT, l DOUBLE, m DOUBLE PRECISION, n REAL)"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Nullable(Int8)")}, {"b", getType("Nullable(Int16)")}
, {"c", getType("Nullable(Int32)")}, {"d", getType("Nullable(Int32)")}, {"e", getType("Nullable(Int32)")}
, {"f", getType("Nullable(Int64)")}, {"g", getType("Nullable(Decimal(10, 0))")}, {"h", getType("Nullable(Decimal(10, 0))")}
, {"i", getType("Nullable(Decimal(10, 0))")}, {"j", getType("Nullable(Decimal(10, 0))")}
, {"k", getType("Nullable(Float32)")}, {"l", getType("Nullable(Float64)")}, {"m", getType("Nullable(Float64)")}
, {"n", getType("Nullable(Float64)")}}
)
);
EXPECT_EQ(
visitQuery("CREATE TABLE test(a tinyint(1), b SMALLINT(1), c MEDIUMINT(1), d INT(1), e INTEGER(1), f BIGINT(1), g DECIMAL(1), h "
"DEC(2, 1), i NUMERIC(4, 3), j FIXED(6, 5), k FLOAT(1), l DOUBLE(1, 2), m DOUBLE PRECISION(3, 4), n REAL(5, 6))"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Nullable(Int8)")}, {"b", getType("Nullable(Int16)")}
, {"c", getType("Nullable(Int32)")}, {"d", getType("Nullable(Int32)")}, {"e", getType("Nullable(Int32)")}
, {"f", getType("Nullable(Int64)")}, {"g", getType("Nullable(Decimal(1, 0))")}, {"h", getType("Nullable(Decimal(2, 1))")}
, {"i", getType("Nullable(Decimal(4, 3))")}, {"j", getType("Nullable(Decimal(6, 5))")}
, {"k", getType("Nullable(Float32)")}, {"l", getType("Nullable(Float64)")}, {"m", getType("Nullable(Float64)")}
, {"n", getType("Nullable(Float64)")}}
)
);
/// UNSIGNED
EXPECT_EQ(
visitQuery("CREATE TABLE test(a tinyint UNSIGNED, b SMALLINT(1) UNSIGNED, c MEDIUMINT(1) UNSIGNED, d INT(1) UNSIGNED, e INTEGER(1), f "
"BIGINT(1) UNSIGNED, g DECIMAL(1) UNSIGNED, h DEC(2, 1) UNSIGNED, i NUMERIC(4, 3) UNSIGNED, j FIXED(6, 5) UNSIGNED, k FLOAT(1) "
"UNSIGNED, l DOUBLE(1, 2) UNSIGNED, m DOUBLE PRECISION(3, 4) UNSIGNED, n REAL(5, 6) UNSIGNED)"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Nullable(UInt8)")}, {"b", getType("Nullable(UInt16)")}
, {"c", getType("Nullable(UInt32)")}, {"d", getType("Nullable(UInt32)")}, {"e", getType("Nullable(Int32)")}
, {"f", getType("Nullable(UInt64)")}, {"g", getType("Nullable(Decimal(1, 0))")}, {"h", getType("Nullable(Decimal(2, 1))")}
, {"i", getType("Nullable(Decimal(4, 3))")}, {"j", getType("Nullable(Decimal(6, 5))")}
, {"k", getType("Nullable(Float32)")}, {"l", getType("Nullable(Float64)")}, {"m", getType("Nullable(Float64)")}
, {"n", getType("Nullable(Float64)")}}
)
);
/// NOT NULL
EXPECT_EQ(
visitQuery("CREATE TABLE test(a tinyint NOT NULL, b SMALLINT(1) NOT NULL, c MEDIUMINT(1) NOT NULL, d INT(1) NOT NULL, e INTEGER(1), f "
"BIGINT(1) NOT NULL, g DECIMAL(1) NOT NULL, h DEC(2, 1) NOT NULL, i NUMERIC(4, 3) NOT NULL, j FIXED(6, 5) NOT NULL, k FLOAT(1) NOT "
"NULL, l DOUBLE(1, 2) NOT NULL, m DOUBLE PRECISION(3, 4) NOT NULL, n REAL(5, 6) NOT NULL)"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Int8")}, {"b", getType("Int16")}
, {"c", getType("Int32")}, {"d", getType("Int32")}, {"e", getType("Nullable(Int32)")}
, {"f", getType("Int64")}, {"g", getType("Decimal(1, 0)")}, {"h", getType("Decimal(2, 1)")}
, {"i", getType("Decimal(4, 3)")}, {"j", getType("Decimal(6, 5)")}
, {"k", getType("Float32")}, {"l", getType("Float64")}, {"m", getType("Float64")}, {"n", getType("Float64")}}
)
);
/// ZEROFILL
EXPECT_EQ(
visitQuery("CREATE TABLE test(a tinyint ZEROFILL, b SMALLINT(1) ZEROFILL, c MEDIUMINT(1) ZEROFILL, d INT(1) ZEROFILL, e INTEGER(1), f "
"BIGINT(1) ZEROFILL, g DECIMAL(1) ZEROFILL, h DEC(2, 1) ZEROFILL, i NUMERIC(4, 3) ZEROFILL, j FIXED(6, 5) ZEROFILL, k FLOAT(1) "
"ZEROFILL, l DOUBLE(1, 2) ZEROFILL, m DOUBLE PRECISION(3, 4) ZEROFILL, n REAL(5, 6) ZEROFILL)"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Nullable(UInt8)")}, {"b", getType("Nullable(UInt16)")}
, {"c", getType("Nullable(UInt32)")}, {"d", getType("Nullable(UInt32)")}, {"e", getType("Nullable(Int32)")}
, {"f", getType("Nullable(UInt64)")}, {"g", getType("Nullable(Decimal(1, 0))")}, {"h", getType("Nullable(Decimal(2, 1))")}
, {"i", getType("Nullable(Decimal(4, 3))")}, {"j", getType("Nullable(Decimal(6, 5))")}
, {"k", getType("Nullable(Float32)")}, {"l", getType("Nullable(Float64)")}, {"m", getType("Nullable(Float64)")}
, {"n", getType("Nullable(Float64)")}}
)
);
}
TEST(CreateQueryVisitor, TestWithDateTimesColumnsType)
{
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE, b DATETIME, c TIMESTAMP, d TIME, e year)"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Nullable(Date)")}, {"b", getType("Nullable(DateTime)")}
, {"c", getType("Nullable(DateTime)")}, {"d", getType("Nullable(DateTime64(3))")}, {"e", getType("Nullable(Int16)")} }
)
);
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE, b DATETIME(1), c TIMESTAMP(1), d TIME(1), e year(4))"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Nullable(Date)")}, {"b", getType("Nullable(DateTime)")}
, {"c", getType("Nullable(DateTime)")}, {"d", getType("Nullable(DateTime64(3))")}, {"e", getType("Nullable(Int16)")} }
)
);
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL, b DATETIME(1) NOT NULL, c TIMESTAMP(1) NOT NULL, d TIME(1) NOT NULL, e year(4) NOT NULL)"),
MySQLTableStruct(ASTs{}, ASTs{}, {{"a", getType("Date")}, {"b", getType("DateTime")} , {"c", getType("DateTime")}, {"d", getType("DateTime64")}, {"e", getType("Int16")} }
)
);
}
TEST(CreateQueryVisitor, TestWithParitionOptions)
{
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL) PARTITION BY HASH a"),
MySQLTableStruct(ASTs{}, ASTs{std::make_shared<ASTIdentifier>("a")}, {{"a", getType("Date")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL) PARTITION BY LINEAR HASH a"),
MySQLTableStruct(ASTs{}, ASTs{std::make_shared<ASTIdentifier>("a")}, {{"a", getType("Date")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL) PARTITION BY RANGE(a)"),
MySQLTableStruct(ASTs{}, ASTs{std::make_shared<ASTIdentifier>("a")}, {{"a", getType("Date")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL, b INT) PARTITION BY RANGE COLUMNS(a, b)"),
MySQLTableStruct(ASTs{}, ASTs{std::make_shared<ASTIdentifier>("a"), std::make_shared<ASTIdentifier>("b")}, {{"a", getType("Date")}, {"b", getType("Nullable(Int32)")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL) PARTITION BY LIST(a)"),
MySQLTableStruct(ASTs{}, ASTs{std::make_shared<ASTIdentifier>("a")}, {{"a", getType("Date")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL, b INT) PARTITION BY LIST COLUMNS(a, b)"),
MySQLTableStruct(ASTs{}, ASTs{std::make_shared<ASTIdentifier>("a"), std::make_shared<ASTIdentifier>("b")},
{{"a", getType("Date")}, {"b", getType("Nullable(Int32)")}}));
}
TEST(CreateQueryVisitor, TestWithPrimaryToPartitionBy)
{
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATE NOT NULL PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("Date")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a DATETIME NOT NULL PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("DateTime")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a TINYINT NOT NULL PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("Int8")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a SMALLINT NOT NULL PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("Int16")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a INT NOT NULL PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("Int32")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a BIGINT NOT NULL PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("Int64")}}));
EXPECT_EQ(
visitQuery("CREATE TABLE test(a BIGINT PRIMARY KEY)"),
MySQLTableStruct(ASTs{std::make_shared<ASTIdentifier>("a")}, ASTs{}, {{"a", getType("Nullable(Int64)")}}));
}