mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2026-10-28 16:18:23 +08:00
Merge pull request #126273 from ClickHouse/simplify_key_description
Simplify sorting description parsing
This commit is contained in:
1 file changed
+60
-60
@@ -1797,6 +1797,21 @@ KeyDescription getSortingKeyDescriptionFromMetadata(Poco::JSON::Object::Ptr meta
|
||||
{
|
||||
auto sort_order_id = metadata_object->getValue<Int64>(f_default_sort_order_id);
|
||||
Poco::JSON::Array::Ptr sort_orders = metadata_object->getArray(f_sort_orders);
|
||||
|
||||
Poco::JSON::Array::Ptr fields;
|
||||
for (UInt32 i = 0; i < sort_orders->size(); ++i)
|
||||
{
|
||||
auto sort_order = sort_orders->getObject(i);
|
||||
if (sort_order->getValue<Int64>(f_order_id) == sort_order_id)
|
||||
{
|
||||
fields = sort_order->getArray(f_fields);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fields || fields->size() == 0)
|
||||
return KeyDescription{};
|
||||
|
||||
std::unordered_map<Int64, String> source_id_to_column_name;
|
||||
auto [schema, current_schema_id] = parseTableSchemaV2Method(metadata_object);
|
||||
|
||||
@@ -1806,70 +1821,55 @@ KeyDescription getSortingKeyDescriptionFromMetadata(Poco::JSON::Object::Ptr meta
|
||||
source_id_to_column_name[source_id] = col_name;
|
||||
}
|
||||
|
||||
KeyDescription key_description;
|
||||
ColumnsDescription column_description;
|
||||
for (size_t i = 0; i < ch_schema.size(); ++i)
|
||||
column_description.add(ColumnDescription(ch_schema.getNames()[i], ch_schema.getTypes()[i]));
|
||||
|
||||
String order_by_str;
|
||||
|
||||
for (UInt32 i = 0; i < sort_orders->size(); ++i)
|
||||
for (UInt32 field_index = 0; field_index < fields->size(); ++field_index)
|
||||
{
|
||||
auto sort_order = sort_orders->getObject(i);
|
||||
if (sort_order->getValue<Int64>(f_order_id) != sort_order_id)
|
||||
continue;
|
||||
auto fields = sort_order->getArray(f_fields);
|
||||
for (UInt32 field_index = 0; field_index < fields->size(); ++field_index)
|
||||
auto field = fields->getObject(field_index);
|
||||
auto source_id = field->getValue<Int64>(f_source_id);
|
||||
auto column_name = source_id_to_column_name[source_id];
|
||||
int direction = field->getValue<String>(f_direction) == "asc" ? 1 : -1;
|
||||
auto iceberg_transform_name = field->getValue<String>(f_transform);
|
||||
std::optional<TransformAndArgument> clickhouse_transform_name;
|
||||
try
|
||||
{
|
||||
auto field = fields->getObject(field_index);
|
||||
auto source_id = field->getValue<Int64>(f_source_id);
|
||||
auto column_name = source_id_to_column_name[source_id];
|
||||
int direction = field->getValue<String>(f_direction) == "asc" ? 1 : -1;
|
||||
auto iceberg_transform_name = field->getValue<String>(f_transform);
|
||||
std::optional<TransformAndArgument> clickhouse_transform_name;
|
||||
try
|
||||
{
|
||||
clickhouse_transform_name = parseTransformAndArgument(iceberg_transform_name);
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
if (e.code() != ErrorCodes::BAD_ARGUMENTS)
|
||||
throw;
|
||||
}
|
||||
if (!clickhouse_transform_name.has_value())
|
||||
{
|
||||
/// An unknown or malformed transform is not a reason to reject the table: an Iceberg
|
||||
/// sort order is only an optimization hint, so drop it and read/write the table as unsorted.
|
||||
return KeyDescription{};
|
||||
}
|
||||
/// Quote the column name so identifiers with special characters (e.g. `@timestamp`)
|
||||
/// produce a parseable ORDER BY clause.
|
||||
auto quoted_column_name = backQuoteIfNeed(column_name);
|
||||
String full_argument;
|
||||
if (clickhouse_transform_name->transform_name != "identity")
|
||||
{
|
||||
full_argument = clickhouse_transform_name->transform_name + "(";
|
||||
if (clickhouse_transform_name->argument)
|
||||
{
|
||||
full_argument += std::to_string(*clickhouse_transform_name->argument) + ", ";
|
||||
}
|
||||
full_argument += quoted_column_name + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
full_argument = quoted_column_name;
|
||||
}
|
||||
if (direction == 1)
|
||||
order_by_str += fmt::format("{} ASC,", full_argument);
|
||||
else
|
||||
order_by_str += fmt::format("{} DESC,", full_argument);
|
||||
clickhouse_transform_name = parseTransformAndArgument(iceberg_transform_name);
|
||||
}
|
||||
break;
|
||||
catch (const Exception & e)
|
||||
{
|
||||
if (e.code() != ErrorCodes::BAD_ARGUMENTS)
|
||||
throw;
|
||||
}
|
||||
if (!clickhouse_transform_name.has_value())
|
||||
{
|
||||
/// An unknown or malformed transform is not a reason to reject the table: an Iceberg
|
||||
/// sort order is only an optimization hint, so drop it and read/write the table as unsorted.
|
||||
return KeyDescription{};
|
||||
}
|
||||
/// Quote the column name so identifiers with special characters (e.g. `@timestamp`)
|
||||
/// produce a parseable ORDER BY clause.
|
||||
auto quoted_column_name = backQuoteIfNeed(column_name);
|
||||
String full_argument;
|
||||
if (clickhouse_transform_name->transform_name != "identity")
|
||||
{
|
||||
full_argument = clickhouse_transform_name->transform_name + "(";
|
||||
if (clickhouse_transform_name->argument)
|
||||
{
|
||||
full_argument += std::to_string(*clickhouse_transform_name->argument) + ", ";
|
||||
}
|
||||
full_argument += quoted_column_name + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
full_argument = quoted_column_name;
|
||||
}
|
||||
if (direction == 1)
|
||||
order_by_str += fmt::format("{} ASC,", full_argument);
|
||||
else
|
||||
order_by_str += fmt::format("{} DESC,", full_argument);
|
||||
}
|
||||
if (order_by_str.empty())
|
||||
return KeyDescription{};
|
||||
order_by_str.pop_back();
|
||||
return KeyDescription::parse(order_by_str, column_description, {}, local_context, true);
|
||||
return KeyDescription::parse(order_by_str, ColumnsDescription(ch_schema), {}, local_context, true);
|
||||
}
|
||||
|
||||
DataTypePtr getFunctionResultType(const String & iceberg_transform_name, DataTypePtr source_type)
|
||||
@@ -1897,9 +1897,9 @@ void sortBlockByKeyDescription(Block & block, const KeyDescription & sort_descri
|
||||
ColumnsWithTypeAndName reordered_columns;
|
||||
for (const auto & column_name : initial_column_names)
|
||||
reordered_columns.push_back(block.getByName(column_name));
|
||||
for (size_t i = 0; i < block.columns(); ++i)
|
||||
if (!initial_column_names_set.contains(block.getNames()[i]))
|
||||
reordered_columns.push_back(block.getColumnsWithTypeAndName()[i]);
|
||||
for (const auto & column : block.getColumnsWithTypeAndName())
|
||||
if (!initial_column_names_set.contains(column.name))
|
||||
reordered_columns.push_back(column);
|
||||
|
||||
block = Block(reordered_columns);
|
||||
SortDescription result_sort_description;
|
||||
|
||||
Reference in new issue
Block a user