Change MySQL global variables query to globalVariable function

This commit is contained in:
BohuTANG 2020-06-24 10:19:35 +08:00
parent 5decc73b5d
commit 4d96a25655
5 changed files with 46 additions and 27 deletions

View File

@ -1,11 +1,15 @@
#include <Functions/IFunctionImpl.h>
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionHelpers.h>
#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/DataTypeString.h>
#include <Columns/ColumnString.h>
#include <Columns/ColumnConst.h>
#include <Core/Field.h>
#include <unordered_map>
#include <Poco/String.h>
namespace DB
{
@ -43,19 +47,39 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
{
if (!checkColumnConst<ColumnString>(arguments[0].column.get()))
throw Exception("Agrument of function " + getName() + " must be constant string", ErrorCodes::BAD_ARGUMENTS);
throw Exception("Argument of function " + getName() + " must be constant string", ErrorCodes::BAD_ARGUMENTS);
String variable_name = assert_cast<const ColumnConst &>(*arguments[0].column).getValue<String>();
throw Exception("There is no global variable with name " + variable_name, ErrorCodes::BAD_ARGUMENTS);
auto variable = global_variable_map.find(Poco::toLower(variable_name));
if (variable == global_variable_map.end())
return std::make_shared<DataTypeString>();
else
return variable->second.type;
}
void executeImpl(Block & block, const ColumnNumbers &, size_t /*result*/, size_t /*input_rows_count*/) override
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override
{
String variable_name = assert_cast<const ColumnConst &>(*block.getByPosition(0).column).getValue<String>();
const ColumnWithTypeAndName & col = block.getByPosition(arguments[0]);
String variable_name = assert_cast<const ColumnConst &>(*col.column).getValue<String>();
auto variable = global_variable_map.find(Poco::toLower(variable_name));
throw Exception("There is no global variable with name " + variable_name, ErrorCodes::BAD_ARGUMENTS);
Field val;
if (variable == global_variable_map.end())
val = "";
else
val = variable->second.value;
auto & result_col = block.getByPosition(result);
result_col.column = result_col.type->createColumnConst(input_rows_count, val);
}
private:
struct TypeAndValue
{
DataTypePtr type;
Field value;
};
std::unordered_map<String, TypeAndValue> global_variable_map = {{"max_allowed_packet", {std::make_shared<DataTypeInt32>(), 67108864}}};
};

View File

@ -1281,6 +1281,7 @@ bool ParserMySQLGlobalVariable::parseImpl(Pos & pos, ASTPtr & node, Expected & e
function_node->children.push_back(expr_list_args);
node = function_node;
node->setAlias(name);
return true;
}

View File

@ -270,7 +270,6 @@ void MySQLHandler::comPing()
}
static bool isFederatedServerSetupSetCommand(const String & query);
static bool isFederatedServerSetupSelectVarCommand(const String & query);
void MySQLHandler::comQuery(ReadBuffer & payload)
{
@ -288,15 +287,6 @@ void MySQLHandler::comQuery(ReadBuffer & payload)
bool should_replace = false;
bool with_output = false;
// Translate query from MySQL to ClickHouse.
// Required parameters when setup:
// * max_allowed_packet, default 64MB, https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_allowed_packet
if (isFederatedServerSetupSelectVarCommand(query))
{
should_replace = true;
replacement_query = "SELECT 67108864 AS max_allowed_packet";
}
// This is a workaround in order to support adding ClickHouse to MySQL using federated server.
if (0 == strncasecmp("SHOW TABLE STATUS LIKE", query.c_str(), 22))
{
@ -304,6 +294,11 @@ void MySQLHandler::comQuery(ReadBuffer & payload)
replacement_query = boost::replace_all_copy(query, "SHOW TABLE STATUS LIKE ", show_table_status_replacement_query);
}
if (0 == strncasecmp("SHOW VARIABLES", query.c_str(), 13))
{
should_replace = true;
}
ReadBufferFromString replacement(replacement_query);
Context query_context = connection_context;
@ -376,16 +371,6 @@ static bool isFederatedServerSetupSetCommand(const String & query)
return 1 == std::regex_match(query, expr);
}
static bool isFederatedServerSetupSelectVarCommand(const String & query)
{
static const std::regex expr{
"|(^(SELECT @@(.*)))"
"|(^((/\\*(.*)\\*/)([ \t]*)(SELECT([ \t]*)@@(.*))))"
"|(^((/\\*(.*)\\*/)([ \t]*)(SHOW VARIABLES(.*))))"
, std::regex::icase};
return 1 == std::regex_match(query, expr);
}
const String MySQLHandler::show_table_status_replacement_query("SELECT"
" name AS Name,"
" engine AS Engine,"

View File

@ -0,0 +1,5 @@
67108864
67108864
67108864 0
67108864 1
67108864 2

View File

@ -1 +1,5 @@
SELECT @@test; -- { serverError 36 }
SELECT @@test; -- empty string
SELECT @@max_allowed_packet;
SELECT @@MAX_ALLOWED_PACKET;
SELECT @@max_allowed_packet, number FROM system.numbers LIMIT 3;
SHOW VARIABLES LIKE 'lower_case_table_names';