Wrap _shard_num with toUInt32 for simpler JOIN with system.clusters.shard_num

This commit is contained in:
Azat Khuzhin 2019-11-06 20:37:30 +03:00
parent 92bd96fc0d
commit 0677ae048c
4 changed files with 35 additions and 6 deletions

View File

@ -105,7 +105,7 @@ void SelectStreamFactory::createForShard(
{
auto modified_query_ast = query_ast->clone();
if (has_virtual_shard_num_column)
VirtualColumnUtils::rewriteEntityInAst(modified_query_ast, "_shard_num", shard_info.shard_num);
VirtualColumnUtils::rewriteEntityInAst(modified_query_ast, "_shard_num", shard_info.shard_num, "toUInt32");
auto emplace_local_stream = [&]()
{

View File

@ -81,6 +81,32 @@ void rewriteEntityInAst(ASTPtr ast, const String & column_name, const Field & va
select.with()->children.push_back(literal);
}
void rewriteEntityInAst(ASTPtr ast, const String & column_name, const Field & value, const String & func)
{
auto & select = ast->as<ASTSelectQuery &>();
if (!select.with())
select.setExpression(ASTSelectQuery::Expression::WITH, std::make_shared<ASTExpressionList>());
if (func.empty())
{
auto literal = std::make_shared<ASTLiteral>(value);
literal->alias = column_name;
literal->prefer_alias_to_column_name = true;
select.with()->children.push_back(literal);
}
else
{
auto literal = std::make_shared<ASTLiteral>(value);
literal->prefer_alias_to_column_name = true;
auto function = makeASTFunction(func, literal);
function->alias = column_name;
function->prefer_alias_to_column_name = true;
select.with()->children.push_back(function);
}
}
void filterBlockWithQuery(const ASTPtr & query, Block & block, const Context & context)
{
const auto & select = query->as<ASTSelectQuery &>();

View File

@ -16,9 +16,13 @@ class NamesAndTypesList;
namespace VirtualColumnUtils
{
/// Adds to the select query section `select column_name as value`
/// For example select _port as 9000.
void rewriteEntityInAst(ASTPtr ast, const String & column_name, const Field & value);
/// Adds to the select query section `WITH value AS column_name`, and uses func
/// to wrap the value (if any)
///
/// For example:
/// - `WITH 9000 as _port`.
/// - `WITH toUInt16(9000) as _port`.
void rewriteEntityInAst(ASTPtr ast, const String & column_name, const Field & value, const String & func = "");
/// Leave in the block only the rows that fit under the WHERE clause and the PREWHERE clause of the query.
/// Only elements of the outer conjunction are considered, depending only on the columns present in the block.

View File

@ -48,11 +48,10 @@ FROM (SELECT *, _shard_num FROM dist_1) a
JOIN system.clusters b
ON a._shard_num = b.shard_num
WHERE b.cluster = 'test_cluster_two_shards_localhost';
-- Requires toUInt32() otherwise Type mismatch of columns (53)
SELECT _shard_num, key, b.host_name, b.host_address, b.port
FROM dist_1 a
JOIN system.clusters b
ON toUInt32(_shard_num) = b.shard_num
ON _shard_num = b.shard_num
WHERE b.cluster = 'test_cluster_two_shards_localhost';
-- rewrite does not work with aliases, hence Missing columns (47)