mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Fixed error [#METR-18149].
This commit is contained in:
parent
b10177ed69
commit
003d63023b
@ -289,6 +289,9 @@ public:
|
||||
/** Преобразование из константы в полноценный столбец */
|
||||
ColumnPtr convertToFullColumn() const override;
|
||||
|
||||
/** Create ColumnTuple of constant columns as elements. */
|
||||
ColumnPtr convertToTupleOfConstants() const;
|
||||
|
||||
void getExtremes(Field & min, Field & max) const override;
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,6 @@ namespace ErrorCodes
|
||||
|
||||
/** Column, that is just group of few another columns.
|
||||
*
|
||||
* Nested columns must not be constant.
|
||||
* For constant Tuples, see ColumnConstTuple.
|
||||
* Mixed constant/non-constant columns is prohibited in tuple
|
||||
* for implementation simplicity.
|
||||
|
@ -672,8 +672,27 @@ private:
|
||||
* x >= y: x1 > y1 || (x1 == y1 && (x2 > y2 || (x2 == y2 ... && xn >= yn))
|
||||
*/
|
||||
|
||||
auto x_const = typeid_cast<const ColumnConstTuple *>(c0);
|
||||
auto y_const = typeid_cast<const ColumnConstTuple *>(c1);
|
||||
|
||||
ColumnPtr x_tuple_of_consts;
|
||||
ColumnPtr y_tuple_of_consts;
|
||||
|
||||
auto x = static_cast<const ColumnTuple *>(c0);
|
||||
auto y = static_cast<const ColumnTuple *>(c1);
|
||||
|
||||
if (x_const)
|
||||
{
|
||||
x_tuple_of_consts = x_const->convertToTupleOfConstants();
|
||||
x = static_cast<const ColumnTuple *>(x_tuple_of_consts.get());
|
||||
}
|
||||
|
||||
if (y_const)
|
||||
{
|
||||
y_tuple_of_consts = y_const->convertToTupleOfConstants();
|
||||
y = static_cast<const ColumnTuple *>(y_tuple_of_consts.get());
|
||||
}
|
||||
|
||||
const size_t tuple_size = x->getData().columns();
|
||||
|
||||
if (0 == tuple_size)
|
||||
@ -866,7 +885,7 @@ public:
|
||||
+ " of first argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
else if (typeid_cast<const ColumnTuple *>(col_left_untyped))
|
||||
else if (typeid_cast<const DataTypeTuple *>(col_with_name_and_type_left.type.get()))
|
||||
executeTuple(block, result, col_left_untyped, col_right_untyped);
|
||||
else if (!left_is_num && !right_is_num)
|
||||
executeString(block, result, col_left_untyped, col_right_untyped);
|
||||
|
@ -1269,12 +1269,26 @@ private:
|
||||
const ColumnWithTypeAndName & arg1 = block.getByPosition(arguments[1]);
|
||||
const ColumnWithTypeAndName & arg2 = block.getByPosition(arguments[2]);
|
||||
|
||||
const ColumnTuple * col1 = static_cast<const ColumnTuple *>(arg1.column.get());
|
||||
const ColumnTuple * col2 = static_cast<const ColumnTuple *>(arg2.column.get());
|
||||
ColumnPtr col1_holder;
|
||||
ColumnPtr col2_holder;
|
||||
|
||||
if (!col1 || !col2)
|
||||
if (typeid_cast<const ColumnTuple *>(arg1.column.get()))
|
||||
col1_holder = arg1.column;
|
||||
else if (const ColumnConstTuple * const_tuple = typeid_cast<const ColumnConstTuple *>(arg1.column.get()))
|
||||
col1_holder = const_tuple->convertToTupleOfConstants();
|
||||
else
|
||||
return false;
|
||||
|
||||
if (typeid_cast<const ColumnTuple *>(arg2.column.get()))
|
||||
col2_holder = arg2.column;
|
||||
else if (const ColumnConstTuple * const_tuple = typeid_cast<const ColumnConstTuple *>(arg2.column.get()))
|
||||
col2_holder = const_tuple->convertToTupleOfConstants();
|
||||
else
|
||||
return false;
|
||||
|
||||
const ColumnTuple * col1 = static_cast<const ColumnTuple *>(col1_holder.get());
|
||||
const ColumnTuple * col2 = static_cast<const ColumnTuple *>(col2_holder.get());
|
||||
|
||||
const DataTypeTuple & type1 = static_cast<const DataTypeTuple &>(*arg1.type);
|
||||
const DataTypeTuple & type2 = static_cast<const DataTypeTuple &>(*arg2.type);
|
||||
|
||||
|
@ -1652,7 +1652,7 @@ private:
|
||||
if (const auto column_tuple = typeid_cast<const ColumnTuple *>(col))
|
||||
element_block = column_tuple->getData();
|
||||
else if (const auto column_const_tuple = typeid_cast<const ColumnConstTuple *>(col))
|
||||
element_block = static_cast<const ColumnTuple &>(*column_const_tuple->convertToFullColumn()).getData();
|
||||
element_block = static_cast<const ColumnTuple &>(*column_const_tuple->convertToTupleOfConstants()).getData();
|
||||
|
||||
/// create columns for converted elements
|
||||
for (const auto & to_element_type : to_element_types)
|
||||
|
@ -885,17 +885,19 @@ private:
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
|
||||
|
||||
const auto key_col_with_type = block.getByPosition(arguments[1]);
|
||||
if (const ColumnTuple * key_col = typeid_cast<const ColumnTuple *>(key_col_with_type.column.get()))
|
||||
if (typeid_cast<const ColumnTuple *>(key_col_with_type.column.get())
|
||||
|| typeid_cast<const ColumnConstTuple *>(key_col_with_type.column.get()))
|
||||
{
|
||||
/// Функции у внешних словарей поддерживают только полноценные (не константные) столбцы с ключами.
|
||||
const ColumnPtr key_col_materialized = key_col->convertToFullColumnIfConst();
|
||||
const ColumnPtr key_col_materialized = key_col_with_type.column->convertToFullColumnIfConst();
|
||||
|
||||
const auto key_columns = ext::map<ConstColumnPlainPtrs>(
|
||||
static_cast<const ColumnTuple &>(*key_col_materialized.get()).getColumns(), [](const ColumnPtr & ptr) { return ptr.get(); });
|
||||
static_cast<const ColumnTuple &>(*key_col_materialized.get()).getColumns(),
|
||||
[](const ColumnPtr & ptr) { return ptr.get(); });
|
||||
|
||||
const auto & key_types = static_cast<const DataTypeTuple &>(*key_col_with_type.type).getElements();
|
||||
|
||||
const auto out = std::make_shared<ColumnUInt8>(key_col->size());
|
||||
const auto out = std::make_shared<ColumnUInt8>(key_col_with_type.column->size());
|
||||
block.getByPosition(result).column = out;
|
||||
|
||||
dict->has(key_columns, key_types, out->getData());
|
||||
@ -1064,12 +1066,14 @@ private:
|
||||
const auto & attr_name = attr_name_col->getData();
|
||||
|
||||
const auto key_col_with_type = block.getByPosition(arguments[2]);
|
||||
if (const auto key_col = typeid_cast<const ColumnTuple *>(key_col_with_type.column.get()))
|
||||
if (typeid_cast<const ColumnTuple *>(key_col_with_type.column.get())
|
||||
|| typeid_cast<const ColumnConstTuple *>(key_col_with_type.column.get()))
|
||||
{
|
||||
const ColumnPtr key_col_materialized = key_col->convertToFullColumnIfConst();
|
||||
const ColumnPtr key_col_materialized = key_col_with_type.column->convertToFullColumnIfConst();
|
||||
|
||||
const auto key_columns = ext::map<ConstColumnPlainPtrs>(
|
||||
static_cast<const ColumnTuple &>(*key_col_materialized.get()).getColumns(), [](const ColumnPtr & ptr) { return ptr.get(); });
|
||||
static_cast<const ColumnTuple &>(*key_col_materialized.get()).getColumns(),
|
||||
[](const ColumnPtr & ptr) { return ptr.get(); });
|
||||
|
||||
const auto & key_types = static_cast<const DataTypeTuple &>(*key_col_with_type.type).getElements();
|
||||
|
||||
@ -1635,12 +1639,14 @@ private:
|
||||
const auto & attr_name = attr_name_col->getData();
|
||||
|
||||
const auto key_col_with_type = block.getByPosition(arguments[2]);
|
||||
if (const auto key_col = typeid_cast<const ColumnTuple *>(key_col_with_type.column.get()))
|
||||
if (typeid_cast<const ColumnTuple *>(key_col_with_type.column.get())
|
||||
|| typeid_cast<const ColumnConstTuple *>(key_col_with_type.column.get()))
|
||||
{
|
||||
const ColumnPtr key_col_materialized = key_col->convertToFullColumnIfConst();
|
||||
const ColumnPtr key_col_materialized = key_col_with_type.column->convertToFullColumnIfConst();
|
||||
|
||||
const auto key_columns = ext::map<ConstColumnPlainPtrs>(
|
||||
static_cast<const ColumnTuple &>(*key_col_materialized.get()).getColumns(), [](const ColumnPtr & ptr) { return ptr.get(); });
|
||||
static_cast<const ColumnTuple &>(*key_col_materialized.get()).getColumns(),
|
||||
[](const ColumnPtr & ptr) { return ptr.get(); });
|
||||
|
||||
const auto & key_types = static_cast<const DataTypeTuple &>(*key_col_with_type.type).getElements();
|
||||
|
||||
|
@ -571,6 +571,11 @@ private:
|
||||
executeForArgument(col.type.get(), col.column.get(), vec_to, is_first);
|
||||
}
|
||||
}
|
||||
else if (const ColumnConstTuple * tuple = typeid_cast<const ColumnConstTuple *>(column))
|
||||
{
|
||||
ColumnPtr tuple_of_constants = tuple->convertToTupleOfConstants();
|
||||
executeForArgument(type, tuple_of_constants.get(), vec_to, is_first);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_first)
|
||||
|
@ -108,6 +108,11 @@ StringRef ColumnConst<Array>::getDataAtWithTerminatingZero(size_t n) const
|
||||
|
||||
|
||||
ColumnPtr ColumnConst<Tuple>::convertToFullColumn() const
|
||||
{
|
||||
return convertToTupleOfConstants()->convertToFullColumnIfConst();
|
||||
}
|
||||
|
||||
ColumnPtr ColumnConst<Tuple>::convertToTupleOfConstants() const
|
||||
{
|
||||
if (!data_type)
|
||||
throw Exception("No data type specified for ColumnConstTuple", ErrorCodes::LOGICAL_ERROR);
|
||||
@ -123,7 +128,7 @@ ColumnPtr ColumnConst<Tuple>::convertToFullColumn() const
|
||||
|
||||
for (size_t i = 0; i < tuple_size; ++i)
|
||||
block.insert(ColumnWithTypeAndName{
|
||||
element_types[i]->createConstColumn(s, static_cast<const TupleBackend &>(*data)[i])->convertToFullColumnIfConst(),
|
||||
element_types[i]->createConstColumn(s, static_cast<const TupleBackend &>(*data)[i]),
|
||||
element_types[i],
|
||||
""});
|
||||
|
||||
|
@ -349,12 +349,13 @@ void FunctionVisibleWidth::execute(Block & block, const ColumnNumbers & argument
|
||||
|
||||
block.getByPosition(result).column = nested_result_column;
|
||||
}
|
||||
else if (const ColumnConstArray * col = typeid_cast<const ColumnConstArray *>(column.get()))
|
||||
else if (typeid_cast<const ColumnConstArray *>(column.get())
|
||||
|| typeid_cast<const ColumnConstTuple *>(column.get()))
|
||||
{
|
||||
String s;
|
||||
{
|
||||
WriteBufferFromString wb(s);
|
||||
type->serializeTextEscaped(*col->convertToFullColumn(), 0, wb);
|
||||
type->serializeTextEscaped(*column->cut(0, 1)->convertToFullColumnIfConst(), 0, wb);
|
||||
}
|
||||
|
||||
block.getByPosition(result).column = std::make_shared<ColumnConstUInt64>(rows, s.size());
|
||||
|
@ -1262,6 +1262,11 @@ void ExpressionAnalyzer::makeExplicitSet(ASTFunction * node, const Block & sampl
|
||||
|
||||
ASTFunction * left_arg_tuple = typeid_cast<ASTFunction *>(left_arg.get());
|
||||
|
||||
/** NOTE If tuple in left hand side specified non-explicitly
|
||||
* Example: identity((a, b)) IN ((1, 2), (3, 4))
|
||||
* instead of (a, b)) IN ((1, 2), (3, 4))
|
||||
* then set creation of set doesn't work correctly.
|
||||
*/
|
||||
if (left_arg_tuple && left_arg_tuple->name == "tuple")
|
||||
{
|
||||
for (const auto & arg : left_arg_tuple->arguments->children)
|
||||
|
Loading…
Reference in New Issue
Block a user