Merge pull request #11901 from BohuTANG/mysql_global_variables

Change MySQL global variables query to globalVariable function
This commit is contained in:
alexey-milovidov 2020-06-25 16:15:41 +03:00 committed by GitHub
commit bc585c7c33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 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,38 @@ 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<DataTypeInt32>();
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 = 0;
if (variable != global_variable_map.end())
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}}, {"version", {std::make_shared<DataTypeString>(), "5.7.30"}}};
};

View File

@ -1270,6 +1270,20 @@ bool ParserMySQLGlobalVariable::parseImpl(Pos & pos, ASTPtr & node, Expected & e
String name(pos->begin, pos->end);
++pos;
/// SELECT @@session|global.variable style
if (pos->type == TokenType::Dot)
{
++pos;
if (pos->type != TokenType::BareWord)
{
expected.add(pos, "variable name");
return false;
}
name = String(pos->begin, pos->end);
++pos;
}
auto name_literal = std::make_shared<ASTLiteral>(name);
auto expr_list_args = std::make_shared<ASTExpressionList>();
@ -1281,6 +1295,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

@ -271,7 +271,6 @@ void MySQLHandler::comPing()
}
static bool isFederatedServerSetupSetCommand(const String & query);
static bool isFederatedServerSetupSelectVarCommand(const String & query);
void MySQLHandler::comQuery(ReadBuffer & payload)
{
@ -289,15 +288,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))
{
@ -305,6 +295,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;
@ -377,16 +372,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,15 @@
0
"@@max_allowed_packet"
67108864
"@@MAX_ALLOWED_PACKET"
67108864
"@@max_allowed_packet","number"
67108864,0
67108864,1
67108864,2
"@@auto_increment_increment"
0
"auto_increment_increment"
0
"@@Version"
"5.7.30"

View File

@ -1 +1,7 @@
SELECT @@test; -- { serverError 36 }
SELECT @@test;
SELECT @@max_allowed_packet FORMAT CSVWithNames;
SELECT @@MAX_ALLOWED_PACKET FORMAT CSVWithNames;
SELECT @@max_allowed_packet, number FROM system.numbers LIMIT 3 FORMAT CSVWithNames;
SELECT @@session.auto_increment_increment FORMAT CSVWithNames;
SELECT @@session.auto_increment_increment AS auto_increment_increment FORMAT CSVWithNames;
SELECT @@Version FORMAT CSVWithNames;