This commit is contained in:
Nikolai Kochetov 2020-10-20 00:21:10 +03:00
parent bc58637ec2
commit 9fe51524cc
29 changed files with 481 additions and 606 deletions

View File

@ -57,7 +57,7 @@ public:
/// For argument-lambda expressions, it defines the types of arguments of these expressions.
void getLambdaArgumentTypes(DataTypes & arguments) const override
{
if (arguments.size() < 1)
if (arguments.empty())
throw Exception("Function " + getName() + " needs at least one argument; passed "
+ toString(arguments.size()) + ".",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
@ -96,7 +96,7 @@ public:
if (arguments.size() == 1)
{
const auto array_type = checkAndGetDataType<DataTypeArray>(arguments[0].type.get());
const auto * array_type = checkAndGetDataType<DataTypeArray>(arguments[0].type.get());
if (!array_type)
throw Exception("The only argument for function " + getName() + " must be array. Found "
@ -116,7 +116,7 @@ public:
throw Exception("Function " + getName() + " needs one array argument.",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
const auto data_type_function = checkAndGetDataType<DataTypeFunction>(arguments[0].type.get());
const auto * data_type_function = checkAndGetDataType<DataTypeFunction>(arguments[0].type.get());
if (!data_type_function)
throw Exception("First argument for function " + getName() + " must be a function.",
@ -129,17 +129,17 @@ public:
throw Exception("Expression for function " + getName() + " must return UInt8, found "
+ return_type->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
const auto first_array_type = checkAndGetDataType<DataTypeArray>(arguments[1].type.get());
const auto * first_array_type = checkAndGetDataType<DataTypeArray>(arguments[1].type.get());
return Impl::getReturnType(return_type, first_array_type->getNestedType());
}
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{
if (arguments.size() == 1)
{
ColumnPtr column_array_ptr = columns[arguments[0]].column;
ColumnPtr column_array_ptr = arguments[0].column;
const auto * column_array = checkAndGetColumn<ColumnArray>(column_array_ptr.get());
if (!column_array)
@ -151,11 +151,11 @@ public:
column_array = assert_cast<const ColumnArray *>(column_array_ptr.get());
}
columns[result].column = Impl::execute(*column_array, column_array->getDataPtr());
return Impl::execute(*column_array, column_array->getDataPtr());
}
else
{
const auto & column_with_type_and_name = columns[arguments[0]];
const auto & column_with_type_and_name = arguments[0];
if (!column_with_type_and_name.column)
throw Exception("First argument for function " + getName() + " must be a function.",
@ -177,7 +177,7 @@ public:
for (size_t i = 1; i < arguments.size(); ++i)
{
const auto & array_with_type_and_name = columns[arguments[i]];
const auto & array_with_type_and_name = arguments[i];
ColumnPtr column_array_ptr = array_with_type_and_name.column;
const auto * column_array = checkAndGetColumn<ColumnArray>(column_array_ptr.get());
@ -229,7 +229,7 @@ public:
if (lambda_result->lowCardinality())
lambda_result = lambda_result->convertToFullColumnIfLowCardinality();
columns[result].column = Impl::execute(*column_first_array, lambda_result);
return Impl::execute(*column_first_array, lambda_result);
}
}
};

View File

@ -30,19 +30,15 @@ public:
return std::make_shared<DataTypeArray>(getLeastSupertype(arguments));
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{
size_t num_elements = arguments.size();
if (num_elements == 0)
{
/// We should return constant empty array.
columns[result].column = columns[result].type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
return result_type->createColumnConstWithDefaultValue(input_rows_count);
const DataTypePtr & return_type = columns[result].type;
const DataTypePtr & elem_type = static_cast<const DataTypeArray &>(*return_type).getNestedType();
const DataTypePtr & elem_type = static_cast<const DataTypeArray &>(*result_type).getNestedType();
/** If part of columns have not same type as common type of all elements of array,
* then convert them to common type.
@ -55,7 +51,7 @@ public:
for (size_t i = 0; i < num_elements; ++i)
{
const auto & arg = columns[arguments[i]];
const auto & arg = arguments[i];
ColumnPtr preprocessed_column = arg.column;
@ -87,7 +83,7 @@ public:
out_offsets[i] = current_offset;
}
columns[result].column = std::move(out);
return out;
}
private:

View File

@ -49,15 +49,10 @@ public:
return getLeastSupertype(arguments);
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{
const DataTypePtr & return_type = columns[result].type;
if (return_type->onlyNull())
{
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
if (result_type->onlyNull())
return result_type->createColumnConstWithDefaultValue(input_rows_count);
size_t rows = input_rows_count;
size_t num_args = arguments.size();
@ -66,11 +61,11 @@ public:
for (size_t i = 0; i < num_args; ++i)
{
const ColumnWithTypeAndName & arg = columns[arguments[i]];
const ColumnWithTypeAndName & arg = arguments[i];
ColumnPtr preprocessed_column = arg.column;
if (!arg.type->equals(*return_type))
preprocessed_column = castColumn(arg, return_type);
if (!arg.type->equals(*result_type))
preprocessed_column = castColumn(arg, result_type);
preprocessed_columns[i] = std::move(preprocessed_column);
}
@ -95,7 +90,7 @@ public:
auto sink = GatherUtils::concat(sources);
columns[result].column = std::move(sink);
return sink;
}
bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -55,7 +55,7 @@ public:
return std::make_shared<DataTypeArray>(nested_type);
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
private:
/// Initially allocate a piece of memory for 512 elements. NOTE: This is just a guess.
@ -85,12 +85,12 @@ private:
};
void FunctionArrayDistinct::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const
ColumnPtr FunctionArrayDistinct::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const
{
ColumnPtr array_ptr = columns[arguments[0]].column;
ColumnPtr array_ptr = arguments[0].column;
const ColumnArray * array = checkAndGetColumn<ColumnArray>(array_ptr.get());
const auto & return_type = columns[result].type;
const auto & return_type = result_type;
auto res_ptr = return_type->createColumn();
ColumnArray & res = assert_cast<ColumnArray &>(*res_ptr);
@ -127,7 +127,7 @@ void FunctionArrayDistinct::executeImpl(ColumnsWithTypeAndName & columns, const
|| executeString(*inner_col, offsets, res_data, res_offsets, nullable_col)))
executeHashed(*inner_col, offsets, res_data, res_offsets, nullable_col);
columns[result].column = std::move(res_ptr);
return res_ptr;
}
template <typename T>

View File

@ -46,46 +46,40 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
private:
void perform(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result,
ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const;
ColumnPtr perform(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const;
template <typename DataType>
static bool executeNumberConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const Field & index,
ArrayImpl::NullMapBuilder & builder);
static ColumnPtr executeNumberConst(ColumnsWithTypeAndName & arguments, const Field & index, ArrayImpl::NullMapBuilder & builder);
template <typename IndexType, typename DataType>
static bool executeNumber(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const PaddedPODArray<IndexType> & indices,
ArrayImpl::NullMapBuilder & builder);
static ColumnPtr executeNumber(ColumnsWithTypeAndName & arguments, const PaddedPODArray<IndexType> & indices, ArrayImpl::NullMapBuilder & builder);
static bool executeStringConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const Field & index,
ArrayImpl::NullMapBuilder & builder);
static ColumnPtr executeStringConst(ColumnsWithTypeAndName & arguments, const Field & index, ArrayImpl::NullMapBuilder & builder);
template <typename IndexType>
static bool executeString(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const PaddedPODArray<IndexType> & indices,
ArrayImpl::NullMapBuilder & builder);
static ColumnPtr executeString(ColumnsWithTypeAndName & arguments, const PaddedPODArray<IndexType> & indices, ArrayImpl::NullMapBuilder & builder);
static bool executeGenericConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const Field & index,
ArrayImpl::NullMapBuilder & builder);
static ColumnPtr executeGenericConst(ColumnsWithTypeAndName & arguments, const Field & index, ArrayImpl::NullMapBuilder & builder);
template <typename IndexType>
static bool executeGeneric(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const PaddedPODArray<IndexType> & indices,
ArrayImpl::NullMapBuilder & builder);
static ColumnPtr executeGeneric(ColumnsWithTypeAndName & arguments, const PaddedPODArray<IndexType> & indices, ArrayImpl::NullMapBuilder & builder);
template <typename IndexType>
static bool executeConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result,
const PaddedPODArray <IndexType> & indices, ArrayImpl::NullMapBuilder & builder,
size_t input_rows_count);
static ColumnPtr executeConst(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
const PaddedPODArray <IndexType> & indices, ArrayImpl::NullMapBuilder & builder,
size_t input_rows_count);
template <typename IndexType>
bool executeArgument(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result,
ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const;
ColumnPtr executeArgument(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const;
/** For a tuple array, the function is evaluated component-wise for each element of the tuple.
*/
bool executeTuple(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const;
ColumnPtr executeTuple(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const;
};
@ -426,18 +420,18 @@ FunctionPtr FunctionArrayElement::create(const Context &)
template <typename DataType>
bool FunctionArrayElement::executeNumberConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const Field & index,
ArrayImpl::NullMapBuilder & builder)
ColumnPtr FunctionArrayElement::executeNumberConst(
ColumnsWithTypeAndName & arguments, const Field & index, ArrayImpl::NullMapBuilder & builder)
{
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const ColumnVector<DataType> * col_nested = checkAndGetColumn<ColumnVector<DataType>>(&col_array->getData());
if (!col_nested)
return false;
return nullptr;
auto col_res = ColumnVector<DataType>::create();
@ -450,45 +444,42 @@ bool FunctionArrayElement::executeNumberConst(ColumnsWithTypeAndName & columns,
else
throw Exception("Illegal type of array index", ErrorCodes::LOGICAL_ERROR);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
template <typename IndexType, typename DataType>
bool FunctionArrayElement::executeNumber(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const PaddedPODArray<IndexType> & indices,
ArrayImpl::NullMapBuilder & builder)
ColumnPtr FunctionArrayElement::executeNumber(
ColumnsWithTypeAndName & arguments, const PaddedPODArray<IndexType> & indices, ArrayImpl::NullMapBuilder & builder)
{
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const ColumnVector<DataType> * col_nested = checkAndGetColumn<ColumnVector<DataType>>(&col_array->getData());
if (!col_nested)
return false;
return nullptr;
auto col_res = ColumnVector<DataType>::create();
ArrayElementNumImpl<DataType>::template vector<IndexType>(
col_nested->getData(), col_array->getOffsets(), indices, col_res->getData(), builder);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
bool FunctionArrayElement::executeStringConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const Field & index,
ArrayImpl::NullMapBuilder & builder)
ColumnPtr FunctionArrayElement::executeStringConst(ColumnsWithTypeAndName & arguments, const Field & index, ArrayImpl::NullMapBuilder & builder)
{
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const ColumnString * col_nested = checkAndGetColumn<ColumnString>(&col_array->getData());
if (!col_nested)
return false;
return nullptr;
auto col_res = ColumnString::create();
@ -513,23 +504,21 @@ bool FunctionArrayElement::executeStringConst(ColumnsWithTypeAndName & columns,
else
throw Exception("Illegal type of array index", ErrorCodes::LOGICAL_ERROR);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
template <typename IndexType>
bool FunctionArrayElement::executeString(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const PaddedPODArray<IndexType> & indices,
ArrayImpl::NullMapBuilder & builder)
ColumnPtr FunctionArrayElement::executeString(ColumnsWithTypeAndName & arguments, const PaddedPODArray<IndexType> & indices, ArrayImpl::NullMapBuilder & builder)
{
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const ColumnString * col_nested = checkAndGetColumn<ColumnString>(&col_array->getData());
if (!col_nested)
return false;
return nullptr;
auto col_res = ColumnString::create();
@ -542,17 +531,15 @@ bool FunctionArrayElement::executeString(ColumnsWithTypeAndName & columns, const
col_res->getOffsets(),
builder);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
bool FunctionArrayElement::executeGenericConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const Field & index,
ArrayImpl::NullMapBuilder & builder)
ColumnPtr FunctionArrayElement::executeGenericConst(ColumnsWithTypeAndName & arguments, const Field & index, ArrayImpl::NullMapBuilder & builder)
{
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const auto & col_nested = col_array->getData();
auto col_res = col_nested.cloneEmpty();
@ -566,18 +553,16 @@ bool FunctionArrayElement::executeGenericConst(ColumnsWithTypeAndName & columns,
else
throw Exception("Illegal type of array index", ErrorCodes::LOGICAL_ERROR);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
template <typename IndexType>
bool FunctionArrayElement::executeGeneric(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, const PaddedPODArray<IndexType> & indices,
ArrayImpl::NullMapBuilder & builder)
ColumnPtr FunctionArrayElement::executeGeneric(ColumnsWithTypeAndName & arguments, const PaddedPODArray<IndexType> & indices, ArrayImpl::NullMapBuilder & builder)
{
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const auto & col_nested = col_array->getData();
auto col_res = col_nested.cloneEmpty();
@ -585,21 +570,20 @@ bool FunctionArrayElement::executeGeneric(ColumnsWithTypeAndName & columns, cons
ArrayElementGenericImpl::vector<IndexType>(
col_nested, col_array->getOffsets(), indices, *col_res, builder);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
template <typename IndexType>
bool FunctionArrayElement::executeConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result,
ColumnPtr FunctionArrayElement::executeConst(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
const PaddedPODArray <IndexType> & indices, ArrayImpl::NullMapBuilder & builder,
size_t input_rows_count)
{
const ColumnArray * col_array = checkAndGetColumnConstData<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col_array = checkAndGetColumnConstData<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
auto res = columns[result].type->createColumn();
auto res = result_type->createColumn();
size_t rows = input_rows_count;
const IColumn & array_elements = col_array->getData();
@ -630,60 +614,60 @@ bool FunctionArrayElement::executeConst(ColumnsWithTypeAndName & columns, const
}
}
columns[result].column = std::move(res);
return true;
return res;
}
template <typename IndexType>
bool FunctionArrayElement::executeArgument(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result,
ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const
ColumnPtr FunctionArrayElement::executeArgument(
ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const
{
auto index = checkAndGetColumn<ColumnVector<IndexType>>(columns[arguments[1]].column.get());
auto index = checkAndGetColumn<ColumnVector<IndexType>>(arguments[1].column.get());
if (!index)
return false;
return nullptr;
const auto & index_data = index->getData();
if (builder)
builder.initSink(index_data.size());
if (!(executeNumber<IndexType, UInt8>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, UInt16>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, UInt32>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, UInt64>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, Int8>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, Int16>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, Int32>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, Int64>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, Float32>(columns, arguments, result, index_data, builder)
|| executeNumber<IndexType, Float64>(columns, arguments, result, index_data, builder)
|| executeConst<IndexType>(columns, arguments, result, index_data, builder, input_rows_count)
|| executeString<IndexType>(columns, arguments, result, index_data, builder)
|| executeGeneric<IndexType>(columns, arguments, result, index_data, builder)))
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
ColumnPtr res;
if ( !((res = executeNumber<IndexType, UInt8>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, UInt16>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, UInt32>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, UInt64>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, Int8>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, Int16>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, Int32>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, Int64>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, Float32>(arguments, index_data, builder))
|| (res = executeNumber<IndexType, Float64>(arguments, index_data, builder))
|| (res = executeConst<IndexType>(arguments, result_type, index_data, builder, input_rows_count))
|| (res = executeString<IndexType>(arguments, index_data, builder))
|| (res = executeGeneric<IndexType>(arguments, index_data, builder))))
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
return true;
return res;
}
bool FunctionArrayElement::executeTuple(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr FunctionArrayElement::executeTuple(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{
const ColumnArray * col_array = typeid_cast<const ColumnArray *>(columns[arguments[0]].column.get());
const ColumnArray * col_array = typeid_cast<const ColumnArray *>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const ColumnTuple * col_nested = typeid_cast<const ColumnTuple *>(&col_array->getData());
if (!col_nested)
return false;
return nullptr;
const auto & tuple_columns = col_nested->getColumns();
size_t tuple_size = tuple_columns.size();
const DataTypes & tuple_types = typeid_cast<const DataTypeTuple &>(
*typeid_cast<const DataTypeArray &>(*columns[arguments[0]].type).getNestedType()).getElements();
*typeid_cast<const DataTypeArray &>(*arguments[0].type).getNestedType()).getElements();
/** We will calculate the function for the tuple of the internals of the array.
* To do this, create a temporary columns.
@ -695,32 +679,25 @@ bool FunctionArrayElement::executeTuple(ColumnsWithTypeAndName & columns, const
* - result of taking elements by index for an array of second elements of tuples;
* ...
*/
ColumnsWithTypeAndName temporary_results;
temporary_results.emplace_back(columns[arguments[1]]);
ColumnsWithTypeAndName temporary_results(2);
temporary_results[1] = arguments[1];
/// results of taking elements by index for arrays from each element of the tuples;
Columns result_tuple_columns;
Columns result_tuple_columns(tuple_size);
for (size_t i = 0; i < tuple_size; ++i)
{
ColumnWithTypeAndName array_of_tuple_section;
array_of_tuple_section.column = ColumnArray::create(tuple_columns[i], col_array->getOffsetsPtr());
array_of_tuple_section.type = std::make_shared<DataTypeArray>(tuple_types[i]);
temporary_results.emplace_back(array_of_tuple_section);
temporary_results[0] = array_of_tuple_section;
ColumnWithTypeAndName array_elements_of_tuple_section;
array_elements_of_tuple_section.type = getReturnTypeImpl(
{temporary_results[i * 2 + 1].type, temporary_results[0].type});
temporary_results.emplace_back(array_elements_of_tuple_section);
executeImpl(temporary_results, ColumnNumbers{i * 2 + 1, 0}, i * 2 + 2, input_rows_count);
result_tuple_columns.emplace_back(std::move(temporary_results[i * 2 + 2].column));
auto type = getReturnTypeImpl({temporary_results[0].type, temporary_results[1].type});
auto col = executeImpl(temporary_results, type, input_rows_count);
result_tuple_columns[i] = std::move(col);
}
columns[result].column = ColumnTuple::create(result_tuple_columns);
return true;
return ColumnTuple::create(result_tuple_columns);
}
String FunctionArrayElement::getName() const
@ -748,7 +725,7 @@ DataTypePtr FunctionArrayElement::getReturnTypeImpl(const DataTypes & arguments)
return array_type->getNestedType();
}
void FunctionArrayElement::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr FunctionArrayElement::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
/// Check nullability.
bool is_array_of_nullable = false;
@ -756,23 +733,23 @@ void FunctionArrayElement::executeImpl(ColumnsWithTypeAndName & columns, const C
const ColumnArray * col_array = nullptr;
const ColumnArray * col_const_array = nullptr;
col_array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (col_array)
is_array_of_nullable = isColumnNullable(col_array->getData());
else
{
col_const_array = checkAndGetColumnConstData<ColumnArray>(columns[arguments[0]].column.get());
col_const_array = checkAndGetColumnConstData<ColumnArray>(arguments[0].column.get());
if (col_const_array)
is_array_of_nullable = isColumnNullable(col_const_array->getData());
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
}
if (!is_array_of_nullable)
{
ArrayImpl::NullMapBuilder builder;
perform(columns, arguments, result, builder, input_rows_count);
perform(arguments, result_type, builder, input_rows_count);
}
else
{
@ -781,9 +758,9 @@ void FunctionArrayElement::executeImpl(ColumnsWithTypeAndName & columns, const C
ColumnsWithTypeAndName source_columns;
const DataTypePtr & input_type = typeid_cast<const DataTypeNullable &>(
*typeid_cast<const DataTypeArray &>(*columns[arguments[0]].type).getNestedType()).getNestedType();
*typeid_cast<const DataTypeArray &>(*arguments[0].type).getNestedType()).getNestedType();
DataTypePtr tmp_ret_type = removeNullable(columns[result].type);
DataTypePtr tmp_ret_type = removeNullable(result_type);
if (col_array)
{
@ -798,12 +775,7 @@ void FunctionArrayElement::executeImpl(ColumnsWithTypeAndName & columns, const C
std::make_shared<DataTypeArray>(input_type),
""
},
columns[arguments[1]],
{
nullptr,
tmp_ret_type,
""
}
arguments[1],
};
builder.initSource(nullable_col.getNullMapData().data());
@ -821,48 +793,42 @@ void FunctionArrayElement::executeImpl(ColumnsWithTypeAndName & columns, const C
std::make_shared<DataTypeArray>(input_type),
""
},
columns[arguments[1]],
{
nullptr,
tmp_ret_type,
""
}
arguments[1],
};
builder.initSource(nullable_col.getNullMapData().data());
}
perform(source_columns, {0, 1}, 2, builder, input_rows_count);
perform(source_columns, tmp_ret_type, builder, input_rows_count);
/// Store the result.
const ColumnWithTypeAndName & source_col = source_columns[2];
ColumnWithTypeAndName & dest_col = columns[result];
dest_col.column = ColumnNullable::create(source_col.column, builder ? std::move(builder).getNullMapColumnPtr() : ColumnUInt8::create());
return ColumnNullable::create(source_col.column, builder ? std::move(builder).getNullMapColumnPtr() : ColumnUInt8::create());
}
}
void FunctionArrayElement::perform(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result,
ColumnPtr FunctionArrayElement::perform(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
ArrayImpl::NullMapBuilder & builder, size_t input_rows_count) const
{
if (executeTuple(columns, arguments, result, input_rows_count))
ColumnPtr res;
if ((res = executeTuple(arguments, input_rows_count)))
return res;
else if (!isColumnConst(*arguments[1].column))
{
}
else if (!isColumnConst(*columns[arguments[1]].column))
{
if (!(executeArgument<UInt8>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<UInt16>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<UInt32>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<UInt64>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<Int8>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<Int16>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<Int32>(columns, arguments, result, builder, input_rows_count)
|| executeArgument<Int64>(columns, arguments, result, builder, input_rows_count)))
if ( !((res = executeArgument<UInt8>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<UInt16>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<UInt32>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<UInt64>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<Int8>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<Int16>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<Int32>(arguments, result_type, builder, input_rows_count))
|| (res = executeArgument<Int64>(arguments, result_type, builder, input_rows_count))))
throw Exception("Second argument for function " + getName() + " must must have UInt or Int type.",
ErrorCodes::ILLEGAL_COLUMN);
}
else
{
Field index = (*columns[arguments[1]].column)[0];
Field index = (*arguments[1].column)[0];
if (builder)
builder.initSink(input_rows_count);
@ -870,22 +836,24 @@ void FunctionArrayElement::perform(ColumnsWithTypeAndName & columns, const Colum
if (index == 0u)
throw Exception("Array indices are 1-based", ErrorCodes::ZERO_ARRAY_OR_TUPLE_INDEX);
if (!(executeNumberConst<UInt8>(columns, arguments, result, index, builder)
|| executeNumberConst<UInt16>(columns, arguments, result, index, builder)
|| executeNumberConst<UInt32>(columns, arguments, result, index, builder)
|| executeNumberConst<UInt64>(columns, arguments, result, index, builder)
|| executeNumberConst<Int8>(columns, arguments, result, index, builder)
|| executeNumberConst<Int16>(columns, arguments, result, index, builder)
|| executeNumberConst<Int32>(columns, arguments, result, index, builder)
|| executeNumberConst<Int64>(columns, arguments, result, index, builder)
|| executeNumberConst<Float32>(columns, arguments, result, index, builder)
|| executeNumberConst<Float64>(columns, arguments, result, index, builder)
|| executeStringConst (columns, arguments, result, index, builder)
|| executeGenericConst (columns, arguments, result, index, builder)))
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
if ( !((res = executeNumberConst<UInt8>(arguments, index, builder))
|| (res = executeNumberConst<UInt16>(arguments, index, builder))
|| (res = executeNumberConst<UInt32>(arguments, index, builder))
|| (res = executeNumberConst<UInt64>(arguments, index, builder))
|| (res = executeNumberConst<Int8>(arguments, index, builder))
|| (res = executeNumberConst<Int16>(arguments, index, builder))
|| (res = executeNumberConst<Int32>(arguments, index, builder))
|| (res = executeNumberConst<Int64>(arguments, index, builder))
|| (res = executeNumberConst<Float32>(arguments, index, builder))
|| (res = executeNumberConst<Float64>(arguments, index, builder))
|| (res = executeStringConst (arguments, index, builder))
|| (res = executeGenericConst (arguments, index, builder))))
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
return res;
}

View File

@ -45,9 +45,9 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeUInt32>());
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override
{
if (const ColumnArray * array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get()))
if (const ColumnArray * array = checkAndGetColumn<ColumnArray>(arguments[0].column.get()))
{
const ColumnArray::Offsets & offsets = array->getOffsets();
@ -63,11 +63,11 @@ public:
prev_off = off;
}
columns[result].column = ColumnArray::create(std::move(res_nested), array->getOffsetsPtr());
return ColumnArray::create(std::move(res_nested), array->getOffsetsPtr());
}
else
{
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}

View File

@ -56,7 +56,7 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeUInt32>());
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override;
private:
/// Initially allocate a piece of memory for 64 elements. NOTE: This is just a guess.
@ -121,7 +121,7 @@ private:
template <typename Derived>
void FunctionArrayEnumerateExtended<Derived>::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const
ColumnPtr FunctionArrayEnumerateExtended<Derived>::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{
const ColumnArray::Offsets * offsets = nullptr;
size_t num_arguments = arguments.size();
@ -131,14 +131,14 @@ void FunctionArrayEnumerateExtended<Derived>::executeImpl(ColumnsWithTypeAndName
ColumnPtr offsets_column;
for (size_t i = 0; i < num_arguments; ++i)
{
const ColumnPtr & array_ptr = columns[arguments[i]].column;
const ColumnPtr & array_ptr = arguments[i].column;
const ColumnArray * array = checkAndGetColumn<ColumnArray>(array_ptr.get());
if (!array)
{
const ColumnConst * const_array = checkAndGetColumnConst<ColumnArray>(
columns[arguments[i]].column.get());
arguments[i].column.get());
if (!const_array)
throw Exception("Illegal column " + columns[arguments[i]].column->getName()
throw Exception("Illegal column " + arguments[i].column->getName()
+ " of " + toString(i + 1) + "-th argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
array_holders.emplace_back(const_array->convertToFullColumn());
@ -155,7 +155,7 @@ void FunctionArrayEnumerateExtended<Derived>::executeImpl(ColumnsWithTypeAndName
throw Exception("Lengths of all arrays passed to " + getName() + " must be equal.",
ErrorCodes::SIZES_OF_ARRAYS_DOESNT_MATCH);
auto * array_data = &array->getData();
const auto * array_data = &array->getData();
data_columns[i] = array_data;
}
@ -163,7 +163,7 @@ void FunctionArrayEnumerateExtended<Derived>::executeImpl(ColumnsWithTypeAndName
for (size_t i = 0; i < num_arguments; ++i)
{
if (auto * nullable_col = checkAndGetColumn<ColumnNullable>(*data_columns[i]))
if (const auto * nullable_col = checkAndGetColumn<ColumnNullable>(*data_columns[i]))
{
if (num_arguments == 1)
data_columns[i] = &nullable_col->getNestedColumn();
@ -201,7 +201,7 @@ void FunctionArrayEnumerateExtended<Derived>::executeImpl(ColumnsWithTypeAndName
executeHashed(*offsets, data_columns, res_values);
}
columns[result].column = ColumnArray::create(std::move(res_nested), offsets_column);
return ColumnArray::create(std::move(res_nested), offsets_column);
}
template <typename Derived>

View File

@ -116,7 +116,7 @@ public:
return type;
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
private:
/// Initially allocate a piece of memory for 64 elements. NOTE: This is just a guess.
@ -149,8 +149,8 @@ static inline UInt128 ALWAYS_INLINE hash128depths(const std::vector<size_t> & in
template <typename Derived>
void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const
ColumnPtr FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{
size_t num_arguments = arguments.size();
ColumnRawPtrs data_columns;
@ -158,12 +158,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
Columns array_holders;
ColumnPtr offsets_column;
ColumnsWithTypeAndName args;
for (size_t i = 0; i < arguments.size(); ++i)
args.emplace_back(columns[arguments[i]]);
const ArraysDepths arrays_depths = getArraysDepths(args);
const ArraysDepths arrays_depths = getArraysDepths(arguments);
/// If the column is Array - return it. If the const Array - materialize it, keep ownership and return.
auto get_array_column = [&](const auto & column) -> const DB::ColumnArray *
@ -186,7 +181,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
size_t array_num = 0;
for (size_t i = 0; i < num_arguments; ++i)
{
const auto * array = get_array_column(columns[arguments[i]].column.get());
const auto * array = get_array_column(arguments[i].column.get());
if (!array)
continue;
@ -258,7 +253,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
for (ssize_t depth = arrays_depths.max_array_depth - 1; depth >= 0; --depth)
result_nested_array = ColumnArray::create(std::move(result_nested_array), offsetsptr_by_depth[depth]);
columns[result].column = result_nested_array;
return result_nested_array;
}
/*

View File

@ -39,7 +39,7 @@ public:
return std::make_shared<DataTypeArray>(nested_type);
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{
/** We create an array column with array elements as the most deep elements of nested arrays,
* and construct offsets by selecting elements of most deep offsets by values of ancestor offsets.
@ -79,10 +79,10 @@ result offsets: 3, 4
result: Row 1: [1, 2, 3], Row2: [4]
*/
const ColumnArray * src_col = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * src_col = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!src_col)
throw Exception("Illegal column " + columns[arguments[0]].column->getName() + " in argument of function 'arrayFlatten'",
throw Exception("Illegal column " + arguments[0].column->getName() + " in argument of function 'arrayFlatten'",
ErrorCodes::ILLEGAL_COLUMN);
const IColumn::Offsets & src_offsets = src_col->getOffsets();
@ -107,7 +107,7 @@ result: Row 1: [1, 2, 3], Row2: [4]
prev_data = &next_col->getData();
}
columns[result].column = ColumnArray::create(
return ColumnArray::create(
prev_data->getPtr(),
result_offsets_column ? std::move(result_offsets_column) : src_col->getOffsetsPtr());
}

View File

@ -396,9 +396,9 @@ public:
* (they are vectors of Fields, which may represent the NULL value),
* they do not require any preprocessing.
*/
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override
{
ColumnPtr& ptr = columns[arguments[0]].column;
ColumnPtr& ptr = arguments[0].column;
/**
* The columns here have two general cases, either being Array(T) or Const(Array(T)).
@ -411,11 +411,11 @@ public:
if (col_array)
nullable = checkAndGetColumn<ColumnNullable>(col_array->getData());
auto & arg_column = columns[arguments[1]].column;
auto & arg_column = arguments[1].column;
const ColumnNullable * arg_nullable = checkAndGetColumn<ColumnNullable>(*arg_column);
if (!nullable && !arg_nullable)
executeOnNonNullable(columns, arguments, result);
return executeOnNonNullable(arguments, result_type);
else
{
/**
@ -424,7 +424,7 @@ public:
* {0, 1, 2, 3, 4}
* {data (array) argument, "value" argument, data null map, "value" null map, function result}.
*/
ColumnsWithTypeAndName source_columns = { {}, {}, {}, {}, {nullptr, columns[result].type, ""} };
ColumnsWithTypeAndName source_columns(4);
if (nullable)
{
@ -436,7 +436,7 @@ public:
data.type = std::make_shared<DataTypeArray>(
static_cast<const DataTypeNullable &>(
*static_cast<const DataTypeArray &>(
*columns[arguments[0]].type
*arguments[0].type
).getNestedType()
).getNestedType());
@ -448,7 +448,7 @@ public:
else
{
auto & data = source_columns[0];
data = columns[arguments[0]];
data = arguments[0];
}
if (arg_nullable)
@ -457,7 +457,7 @@ public:
arg.column = arg_nullable->getNestedColumnPtr();
arg.type =
static_cast<const DataTypeNullable &>(
*columns[arguments[1]].type
*arguments[1].type
).getNestedType();
auto & null_map = source_columns[3];
@ -467,16 +467,11 @@ public:
else
{
auto & arg = source_columns[1];
arg = columns[arguments[1]];
arg = arguments[1];
}
/// Now perform the function.
executeOnNonNullable(source_columns, {0, 1, 2, 3}, 4);
/// Move the result to its final position.
const ColumnWithTypeAndName & source_col = source_columns[4];
ColumnWithTypeAndName & dest_col = columns[result];
dest_col.column = std::move(source_col.column);
return executeOnNonNullable(source_columns, result_type);
}
}
@ -492,12 +487,11 @@ private:
const IColumn& left;
const IColumn& right;
const ColumnArray::Offsets& offsets;
ColumnsWithTypeAndName & columns;
size_t result_pos;
ColumnPtr result_column;
NullMaps maps;
ResultColumnPtr result { ResultColumnType::create() };
inline void move_result() { columns[result_pos].column = std::move(result); }
inline void move_result() { result_column = std::move(result); }
};
static inline bool allowNested(const DataTypePtr & left, const DataTypePtr & right)
@ -579,14 +573,14 @@ private:
#define INTEGRAL_TPL_PACK UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64
void executeOnNonNullable(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeOnNonNullable(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) const
{
if (const auto* const left_arr = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get()))
if (const auto* const left_arr = checkAndGetColumn<ColumnArray>(arguments[0].column.get()))
{
if (checkAndGetColumn<ColumnLowCardinality>(&left_arr->getData()))
{
if (executeLowCardinality(columns, arguments, result))
return;
if (auto res = executeLowCardinality(arguments))
return res;
throw Exception(
"Illegal internal type of first argument of function " + getName(),
@ -594,13 +588,16 @@ private:
}
}
if (!(executeIntegral<INTEGRAL_TPL_PACK>(columns, arguments, result)
|| executeConst(columns, arguments, result)
|| executeString(columns, arguments, result)
|| executeGeneric(columns, arguments, result)))
ColumnPtr res;
if (!((res = executeIntegral<INTEGRAL_TPL_PACK>(arguments))
|| (res = executeConst(arguments, result_type))
|| (res = executeString(arguments))
|| (res = executeGeneric(arguments))))
throw Exception(
"Illegal internal type of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
return res;
}
/**
@ -614,7 +611,7 @@ private:
* @return {nullptr, null_map_item} if there are four arguments but the third is missing.
* @return {null_map_data, null_map_item} if there are four arguments.
*/
static NullMaps getNullMaps(const ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments) noexcept
static NullMaps getNullMaps(const ColumnsWithTypeAndName & arguments) noexcept
{
if (arguments.size() < 3)
return {nullptr, nullptr};
@ -622,10 +619,10 @@ private:
const NullMap * null_map_data = nullptr;
const NullMap * null_map_item = nullptr;
if (const auto & data_map = columns[arguments[2]].column; data_map)
if (const auto & data_map = arguments[2].column; data_map)
null_map_data = &assert_cast<const ColumnUInt8 &>(*data_map).getData();
if (const auto & item_map = columns[arguments[3]].column; item_map)
if (const auto & item_map = arguments[3].column; item_map)
null_map_item = &assert_cast<const ColumnUInt8 &>(*item_map).getData();
return {null_map_data, null_map_item};
@ -637,25 +634,25 @@ private:
* (s1, s1, s2, ...), (s2, s1, s2, ...), (s3, s1, s2, ...)
*/
template <class ...Integral>
static inline bool executeIntegral(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_pos)
static inline ColumnPtr executeIntegral(ColumnsWithTypeAndName & arguments)
{
const ColumnArray * const left = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * const left = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!left)
return false;
return nullptr;
const IColumn& right = *columns[arguments[1]].column.get();
const IColumn& right = *arguments[1].column.get();
ExecutionData data = {
left->getData(),
right,
left->getOffsets(),
columns,
result_pos,
getNullMaps(columns, arguments)
nullptr,
getNullMaps(arguments)
};
return executeIntegral<Integral...>(data);
if (executeIntegral<Integral...>(data))
return data.result_column;
}
template <class ...Integral>
@ -727,22 +724,21 @@ private:
*
* Tips and tricks tried can be found at https://github.com/ClickHouse/ClickHouse/pull/12550 .
*/
static bool executeLowCardinality(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result)
static ColumnPtr executeLowCardinality(ColumnsWithTypeAndName & arguments)
{
const ColumnArray * const col_array = checkAndGetColumn<ColumnArray>(
columns[arguments[0]].column.get());
const ColumnArray * const col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
const ColumnLowCardinality * const col_lc = checkAndGetColumn<ColumnLowCardinality>(&col_array->getData());
if (!col_lc)
return false;
return nullptr;
const auto [null_map_data, null_map_item] = getNullMaps(columns, arguments);
const auto [null_map_data, null_map_item] = getNullMaps(arguments);
const IColumn& col_arg = *columns[arguments[1]].column.get();
const IColumn& col_arg = *arguments[1].column.get();
if (const ColumnConst * const col_arg_const = checkAndGetColumn<ColumnConst>(col_arg))
{
@ -758,12 +754,11 @@ private:
// inner types do not match (like A and Nullable(B) or A and Const(B));
&& different_inner_types;
const DataTypeArray * const array_type = checkAndGetDataType<DataTypeArray>(
columns[arguments[0]].type.get());
const DataTypeArray * const array_type = checkAndGetDataType<DataTypeArray>(arguments[0].type.get());
const DataTypePtr target_type_ptr = recursiveRemoveLowCardinality(array_type->getNestedType());
const ColumnPtr col_arg_cloned = use_cloned_arg
? castColumn(columns[arguments[1]], target_type_ptr)
? castColumn(arguments[1], target_type_ptr)
: col_arg_const->getPtr();
const StringRef elem = col_arg_cloned->getDataAt(0);
@ -782,8 +777,7 @@ private:
data.resize_fill(offsets_size);
columns[result].column = std::move(col_result);
return true;
return col_result;
}
}
@ -795,8 +789,7 @@ private:
null_map_data,
null_map_item);
columns[result].column = std::move(col_result);
return true;
return col_result;
}
else if (col_lc->nestedIsNullable()) // LC(Nullable(T)) and U
{
@ -821,19 +814,20 @@ private:
ExecutionData data = {
left_ptr, right_ptr,
col_array->getOffsets(),
columns, result,
nullptr,
{null_map_left_casted, null_map_right_casted}};
return dispatchConvertedLCColumns(data);
if (dispatchConvertedLCColumns(data))
return data.result_column;
}
else // LC(T) and U, T not Nullable
{
if (col_arg.isNullable())
return false;
return nullptr;
if (const auto* const arg_lc = checkAndGetColumn<ColumnLowCardinality>(&col_arg);
arg_lc && arg_lc->isNullable())
return false;
return nullptr;
// LC(T) and U (possibly LC(V))
@ -842,10 +836,11 @@ private:
ExecutionData data = {
*left_casted.get(), *right_casted.get(), col_array->getOffsets(),
columns, result, {null_map_data, null_map_item}
nullptr, {null_map_data, null_map_item}
};
return dispatchConvertedLCColumns(data);
if (dispatchConvertedLCColumns(data))
return data.result_column;
}
}
@ -869,27 +864,30 @@ private:
#undef INTEGRAL_TPL_PACK
static bool executeString(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_pos)
static ColumnPtr executeString(ColumnsWithTypeAndName & arguments)
{
const ColumnArray * array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!array)
return false;
return nullptr;
const ColumnString * left = checkAndGetColumn<ColumnString>(&array->getData());
if (!left)
return false;
return nullptr;
const IColumn & right = *columns[arguments[1]].column.get();
const IColumn & right = *arguments[1].column.get();
ExecutionData data = {
*left, right, array->getOffsets(),
columns, result_pos, getNullMaps(columns, arguments),
nullptr, getNullMaps(arguments),
std::move(ResultColumnType::create())
};
return executeStringImpl(data);
if (executeStringImpl(data))
return data.result_column;
return nullptr;
}
static bool executeStringImpl(ExecutionData& data)
@ -954,17 +952,16 @@ private:
return true;
}
static bool executeConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result)
static ColumnPtr executeConst(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type)
{
const ColumnConst * col_array = checkAndGetColumnConst<ColumnArray>(
columns[arguments[0]].column.get());
const ColumnConst * col_array = checkAndGetColumnConst<ColumnArray>(arguments[0].column.get());
if (!col_array)
return false;
return nullptr;
Array arr = col_array->getValue<Array>();
const IColumn * item_arg = columns[arguments[1]].column.get();
const IColumn * item_arg = arguments[1].column.get();
if (isColumnConst(*item_arg))
{
@ -982,8 +979,7 @@ private:
break;
}
columns[result].column = columns[result].type->createColumnConst(
item_arg->size(), static_cast<ResultType>(current));
return result_type->createColumnConst(item_arg->size(), static_cast<ResultType>(current));
}
else
{
@ -991,7 +987,7 @@ private:
const NullMap * null_map = nullptr;
if (arguments.size() > 2)
if (const auto & col = columns[arguments[3]].column; col)
if (const auto & col = arguments[3].column; col)
null_map = &assert_cast<const ColumnUInt8 &>(*col).getData();
const size_t size = item_arg->size();
@ -1025,25 +1021,23 @@ private:
}
}
columns[result].column = std::move(col_res);
return col_res;
}
return true;
}
static bool executeGeneric(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result)
static ColumnPtr executeGeneric(ColumnsWithTypeAndName & arguments)
{
const ColumnArray * col = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * col = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!col)
return false;
return nullptr;
const IColumn & col_nested = col->getData();
const IColumn & item_arg = *columns[arguments[1]].column;
const IColumn & item_arg = *arguments[1].column;
auto col_res = ResultColumnType::create();
auto [null_map_data, null_map_item] = getNullMaps(columns, arguments);
auto [null_map_data, null_map_item] = getNullMaps(arguments);
if (item_arg.onlyNull())
Impl::Null<ConcreteAction>::process(
@ -1067,8 +1061,7 @@ private:
null_map_data,
null_map_item);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
};
}

View File

@ -48,7 +48,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
bool useDefaultImplementationForConstants() const override { return true; }
@ -88,7 +88,7 @@ private:
ColumnsWithTypeAndName casted;
};
static CastArgumentsResult castColumns(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments,
static CastArgumentsResult castColumns(ColumnsWithTypeAndName & arguments,
const DataTypePtr & return_type, const DataTypePtr & return_type_with_nulls);
UnpackedArrays prepareArrays(const ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & initial_columns) const;
@ -206,8 +206,7 @@ ColumnPtr FunctionArrayIntersect::castRemoveNullable(const ColumnPtr & column, c
}
FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, const DataTypePtr & return_type,
const DataTypePtr & return_type_with_nulls)
ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, const DataTypePtr & return_type_with_nulls)
{
size_t num_args = arguments.size();
ColumnsWithTypeAndName initial_columns(num_args);
@ -233,7 +232,7 @@ FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
for (size_t i = 0; i < num_args; ++i)
{
const ColumnWithTypeAndName & arg = columns[arguments[i]];
const ColumnWithTypeAndName & arg = arguments[i];
initial_columns[i] = arg;
casted_columns[i] = arg;
auto & column = casted_columns[i];
@ -284,18 +283,9 @@ FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
static ColumnPtr callFunctionNotEquals(ColumnWithTypeAndName first, ColumnWithTypeAndName second, const Context & context)
{
ColumnsWithTypeAndName args;
args.reserve(2);
args.emplace_back(std::move(first));
args.emplace_back(std::move(second));
ColumnsWithTypeAndName args{first, second};
auto eq_func = FunctionFactory::instance().get("notEquals", context)->build(args);
args.emplace_back(ColumnWithTypeAndName{nullptr, eq_func->getReturnType(), ""});
eq_func->execute(args, {0, 1}, 2, args.front().column->size());
return args[2].column;
return eq_func->execute(args, eq_func->getResultType(), args.front().column->size());
}
FunctionArrayIntersect::UnpackedArrays FunctionArrayIntersect::prepareArrays(
@ -383,9 +373,8 @@ FunctionArrayIntersect::UnpackedArrays FunctionArrayIntersect::prepareArrays(
return arrays;
}
void FunctionArrayIntersect::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr FunctionArrayIntersect::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, size_t input_rows_count) const
{
const auto & return_type = columns[result].type;
const auto * return_type_array = checkAndGetDataType<DataTypeArray>(return_type.get());
if (!return_type_array)
@ -394,20 +383,17 @@ void FunctionArrayIntersect::executeImpl(ColumnsWithTypeAndName & columns, const
const auto & nested_return_type = return_type_array->getNestedType();
if (typeid_cast<const DataTypeNothing *>(nested_return_type.get()))
{
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
return return_type->createColumnConstWithDefaultValue(input_rows_count);
auto num_args = arguments.size();
DataTypes data_types;
data_types.reserve(num_args);
for (size_t i = 0; i < num_args; ++i)
data_types.push_back(columns[arguments[i]].type);
data_types.push_back(arguments[i].type);
auto return_type_with_nulls = getMostSubtype(data_types, true, true);
auto casted_columns = castColumns(columns, arguments, return_type, return_type_with_nulls);
auto casted_columns = castColumns(arguments, return_type, return_type_with_nulls);
UnpackedArrays arrays = prepareArrays(casted_columns.casted, casted_columns.initial);
@ -446,7 +432,7 @@ void FunctionArrayIntersect::executeImpl(ColumnsWithTypeAndName & columns, const
}
}
columns[result].column = std::move(result_column);
return result_column;
}
template <typename T, size_t>

View File

@ -54,7 +54,7 @@ public:
return arr->getNestedType();
}
void executeImpl(ColumnsWithTypeAndName &, const ColumnNumbers &, size_t, size_t /*input_rows_count*/) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName &, const DataTypePtr &, size_t /*input_rows_count*/) const override
{
throw Exception("Function " + getName() + " must not be executed directly.", ErrorCodes::FUNCTION_IS_SPECIAL);
}

View File

@ -31,7 +31,7 @@ public:
if (arguments[0]->onlyNull())
return arguments[0];
auto array_type = typeid_cast<const DataTypeArray *>(arguments[0].get());
const auto * array_type = typeid_cast<const DataTypeArray *>(arguments[0].get());
if (!array_type)
throw Exception("First argument for function " + getName() + " must be an array but it has type "
+ arguments[0]->getName() + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -39,23 +39,20 @@ public:
return arguments[0];
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{
const auto & return_type = columns[result].type;
const auto & return_type = result_type;
if (return_type->onlyNull())
{
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
return return_type->createColumnConstWithDefaultValue(input_rows_count);
const auto & array_column = columns[arguments[0]].column;
const auto & array_column = arguments[0].column;
std::unique_ptr<GatherUtils::IArraySource> source;
size_t size = array_column->size();
if (auto argument_column_array = typeid_cast<const ColumnArray *>(array_column.get()))
if (const auto * argument_column_array = typeid_cast<const ColumnArray *>(array_column.get()))
source = GatherUtils::createArraySource(*argument_column_array, false, size);
else
throw Exception{"First arguments for function " + getName() + " must be array.", ErrorCodes::LOGICAL_ERROR};
@ -67,7 +64,7 @@ public:
else
sink = GatherUtils::sliceFromLeftConstantOffsetBounded(*source, 0, -1);
columns[result].column = std::move(sink);
return sink;
}
bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -35,7 +35,7 @@ public:
if (arguments[0]->onlyNull())
return arguments[0];
auto array_type = typeid_cast<const DataTypeArray *>(arguments[0].get());
const auto * array_type = typeid_cast<const DataTypeArray *>(arguments[0].get());
if (!array_type)
throw Exception("First argument for function " + getName() + " must be an array but it has type "
+ arguments[0]->getName() + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -47,27 +47,22 @@ public:
return std::make_shared<DataTypeArray>(getLeastSupertype(types));
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, size_t input_rows_count) const override
{
const auto & return_type = columns[result].type;
if (return_type->onlyNull())
{
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
return return_type->createColumnConstWithDefaultValue(input_rows_count);
auto result_column = return_type->createColumn();
auto array_column = columns[arguments[0]].column;
auto appended_column = columns[arguments[1]].column;
auto array_column = arguments[0].column;
auto appended_column = arguments[1].column;
if (!columns[arguments[0]].type->equals(*return_type))
array_column = castColumn(columns[arguments[0]], return_type);
if (!arguments[0].type->equals(*return_type))
array_column = castColumn(arguments[0], return_type);
const DataTypePtr & return_nested_type = typeid_cast<const DataTypeArray &>(*return_type).getNestedType();
if (!columns[arguments[1]].type->equals(*return_nested_type))
appended_column = castColumn(columns[arguments[1]], return_nested_type);
if (!arguments[1].type->equals(*return_nested_type))
appended_column = castColumn(arguments[1], return_nested_type);
std::unique_ptr<GatherUtils::IArraySource> array_source;
std::unique_ptr<GatherUtils::IValueSource> value_source;
@ -75,20 +70,20 @@ public:
size_t size = array_column->size();
bool is_const = false;
if (auto const_array_column = typeid_cast<const ColumnConst *>(array_column.get()))
if (const auto * const_array_column = typeid_cast<const ColumnConst *>(array_column.get()))
{
is_const = true;
array_column = const_array_column->getDataColumnPtr();
}
if (auto argument_column_array = typeid_cast<const ColumnArray *>(array_column.get()))
if (const auto * argument_column_array = typeid_cast<const ColumnArray *>(array_column.get()))
array_source = GatherUtils::createArraySource(*argument_column_array, is_const, size);
else
throw Exception{"First arguments for function " + getName() + " must be array.", ErrorCodes::LOGICAL_ERROR};
bool is_appended_const = false;
if (auto const_appended_column = typeid_cast<const ColumnConst *>(appended_column.get()))
if (const auto * const_appended_column = typeid_cast<const ColumnConst *>(appended_column.get()))
{
is_appended_const = true;
appended_column = const_appended_column->getDataColumnPtr();
@ -100,7 +95,7 @@ public:
GatherUtils::push(*array_source, *value_source, *sink, push_front);
columns[result].column = std::move(result_column);
return result_column;
}
bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -49,7 +49,7 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override;
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
private:
/// lazy initialization in getReturnTypeImpl
@ -105,7 +105,7 @@ DataTypePtr FunctionArrayReduce::getReturnTypeImpl(const ColumnsWithTypeAndName
}
void FunctionArrayReduce::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr FunctionArrayReduce::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
IAggregateFunction & agg_func = *aggregate_function;
std::unique_ptr<Arena> arena = std::make_unique<Arena>();
@ -120,7 +120,7 @@ void FunctionArrayReduce::executeImpl(ColumnsWithTypeAndName & columns, const Co
for (size_t i = 0; i < num_arguments_columns; ++i)
{
const IColumn * col = columns[arguments[i + 1]].column.get();
const IColumn * col = arguments[i + 1].column.get();
const ColumnArray::Offsets * offsets_i = nullptr;
if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(col))
@ -146,7 +146,7 @@ void FunctionArrayReduce::executeImpl(ColumnsWithTypeAndName & columns, const Co
}
const IColumn ** aggregate_arguments = aggregate_arguments_vec.data();
MutableColumnPtr result_holder = columns[result].type->createColumn();
MutableColumnPtr result_holder = result_type->createColumn();
IColumn & res_col = *result_holder;
/// AggregateFunction's states should be inserted into column using specific way
@ -154,7 +154,7 @@ void FunctionArrayReduce::executeImpl(ColumnsWithTypeAndName & columns, const Co
if (!res_col_aggregate_function && agg_func.isState())
throw Exception("State function " + agg_func.getName() + " inserts results into non-state column "
+ columns[result].type->getName(), ErrorCodes::ILLEGAL_COLUMN);
+ result_type->getName(), ErrorCodes::ILLEGAL_COLUMN);
PODArray<AggregateDataPtr> places(input_rows_count);
for (size_t i = 0; i < input_rows_count; ++i)
@ -191,7 +191,7 @@ void FunctionArrayReduce::executeImpl(ColumnsWithTypeAndName & columns, const Co
agg_func.insertResultInto(places[i], res_col, arena.get());
else
res_col_aggregate_function->insertFrom(places[i]);
columns[result].column = std::move(result_holder);
return result_holder;
}

View File

@ -52,7 +52,7 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override;
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
private:
/// lazy initialization in getReturnTypeImpl
@ -123,7 +123,7 @@ DataTypePtr FunctionArrayReduceInRanges::getReturnTypeImpl(const ColumnsWithType
}
void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
IAggregateFunction & agg_func = *aggregate_function;
std::unique_ptr<Arena> arena = std::make_unique<Arena>();
@ -133,7 +133,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
/// Handling ranges
const IColumn * ranges_col_array = columns[arguments[1]].column.get();
const IColumn * ranges_col_array = arguments[1].column.get();
const IColumn * ranges_col_tuple = nullptr;
const ColumnArray::Offsets * ranges_offsets = nullptr;
if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(ranges_col_array))
@ -164,7 +164,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
for (size_t i = 0; i < num_arguments_columns; ++i)
{
const IColumn * col = columns[arguments[i + 2]].column.get();
const IColumn * col = arguments[i + 2].column.get();
const ColumnArray::Offsets * offsets_i = nullptr;
if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(col))
@ -192,7 +192,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
/// Handling results
MutableColumnPtr result_holder = columns[result].type->createColumn();
MutableColumnPtr result_holder = result_type->createColumn();
ColumnArray * result_arr = static_cast<ColumnArray *>(result_holder.get());
IColumn & result_data = result_arr->getData();
@ -203,7 +203,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
if (!res_col_aggregate_function && agg_func.isState())
throw Exception("State function " + agg_func.getName() + " inserts results into non-state column "
+ columns[result].type->getName(), ErrorCodes::ILLEGAL_COLUMN);
+ result_type->getName(), ErrorCodes::ILLEGAL_COLUMN);
/// Perform the aggregation
@ -383,7 +383,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
}
}
columns[result].column = std::move(result_holder);
return result_holder;
}

View File

@ -63,23 +63,18 @@ public:
return std::make_shared<DataTypeArray>(getLeastSupertype({array_type->getNestedType(), arguments[2]}));
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, size_t input_rows_count) const override
{
const auto & return_type = columns[result].type;
if (return_type->onlyNull())
{
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
return return_type->createColumnConstWithDefaultValue(input_rows_count);
auto result_column = return_type->createColumn();
auto array_column = columns[arguments[0]].column;
auto size_column = columns[arguments[1]].column;
auto array_column = arguments[0].column;
auto size_column = arguments[1].column;
if (!columns[arguments[0]].type->equals(*return_type))
array_column = castColumn(columns[arguments[0]], return_type);
if (!arguments[0].type->equals(*return_type))
array_column = castColumn(arguments[0], return_type);
const DataTypePtr & return_nested_type = typeid_cast<const DataTypeArray &>(*return_type).getNestedType();
size_t size = array_column->size();
@ -87,9 +82,9 @@ public:
ColumnPtr appended_column;
if (arguments.size() == 3)
{
appended_column = columns[arguments[2]].column;
if (!columns[arguments[2]].type->equals(*return_nested_type))
appended_column = castColumn(columns[arguments[2]], return_nested_type);
appended_column = arguments[2].column;
if (!arguments[2].type->equals(*return_nested_type))
appended_column = castColumn(arguments[2], return_nested_type);
}
else
appended_column = return_nested_type->createColumnConstWithDefaultValue(size);
@ -127,7 +122,7 @@ public:
else
GatherUtils::resizeDynamicSize(*array_source, *value_source, *sink, *size_column);
columns[result].column = std::move(result_column);
return result_column;
}
bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -41,7 +41,7 @@ public:
return arguments[0];
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t) const override;
private:
template <typename T>
@ -53,11 +53,11 @@ private:
};
void FunctionArrayReverse::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t) const
ColumnPtr FunctionArrayReverse::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const
{
const ColumnArray * array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!array)
throw Exception("Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function " + getName(),
throw Exception("Illegal column " + arguments[0].column->getName() + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
auto res_ptr = array->cloneEmpty();
@ -96,7 +96,7 @@ void FunctionArrayReverse::executeImpl(ColumnsWithTypeAndName & columns, const C
+ " of null map of the first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
columns[result].column = std::move(res_ptr);
return res_ptr;
}

View File

@ -31,33 +31,37 @@ private:
using ResultColumnType = ColumnVector<typename Method::ResultType>;
template <typename T>
bool executeNumber(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeNumber(ColumnsWithTypeAndName & arguments) const
{
return executeNumberNumber<T, UInt8>(columns, arguments, result)
|| executeNumberNumber<T, UInt16>(columns, arguments, result)
|| executeNumberNumber<T, UInt32>(columns, arguments, result)
|| executeNumberNumber<T, UInt64>(columns, arguments, result)
|| executeNumberNumber<T, Int8>(columns, arguments, result)
|| executeNumberNumber<T, Int16>(columns, arguments, result)
|| executeNumberNumber<T, Int32>(columns, arguments, result)
|| executeNumberNumber<T, Int64>(columns, arguments, result)
|| executeNumberNumber<T, Float32>(columns, arguments, result)
|| executeNumberNumber<T, Float64>(columns, arguments, result);
ColumnPtr res;
if ( (res = executeNumberNumber<T, UInt8>(arguments))
|| (res = executeNumberNumber<T, UInt16>(arguments))
|| (res = executeNumberNumber<T, UInt32>(arguments))
|| (res = executeNumberNumber<T, UInt64>(arguments))
|| (res = executeNumberNumber<T, Int8>(arguments))
|| (res = executeNumberNumber<T, Int16>(arguments))
|| (res = executeNumberNumber<T, Int32>(arguments))
|| (res = executeNumberNumber<T, Int64>(arguments))
|| (res = executeNumberNumber<T, Float32>(arguments))
|| (res = executeNumberNumber<T, Float64>(arguments)))
return res;
return nullptr;
}
template <typename T, typename U>
bool executeNumberNumber(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeNumberNumber(ColumnsWithTypeAndName & arguments) const
{
ColumnPtr col1 = columns[arguments[0]].column->convertToFullColumnIfConst();
ColumnPtr col2 = columns[arguments[1]].column->convertToFullColumnIfConst();
ColumnPtr col1 = arguments[0].column->convertToFullColumnIfConst();
ColumnPtr col2 = arguments[1].column->convertToFullColumnIfConst();
if (!col1 || !col2)
return false;
return nullptr;
const ColumnArray * col_array1 = checkAndGetColumn<ColumnArray>(col1.get());
const ColumnArray * col_array2 = checkAndGetColumn<ColumnArray>(col2.get());
if (!col_array1 || !col_array2)
return false;
return nullptr;
if (!col_array1->hasEqualOffsets(*col_array2))
throw Exception("Array arguments for function " + getName() + " must have equal sizes", ErrorCodes::BAD_ARGUMENTS);
@ -65,7 +69,7 @@ private:
const ColumnVector<T> * col_nested1 = checkAndGetColumn<ColumnVector<T>>(col_array1->getData());
const ColumnVector<U> * col_nested2 = checkAndGetColumn<ColumnVector<U>>(col_array2->getData());
if (!col_nested1 || !col_nested2)
return false;
return nullptr;
auto col_res = ResultColumnType::create();
@ -75,8 +79,7 @@ private:
col_array1->getOffsets(),
col_res->getData());
columns[result].column = std::move(col_res);
return true;
return col_res;
}
template <typename T, typename U>
@ -112,7 +115,7 @@ public:
if (!array_type)
throw Exception("All arguments for function " + getName() + " must be an array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto & nested_type = array_type->getNestedType();
const auto & nested_type = array_type->getNestedType();
if (!isNativeNumber(nested_type) && !isEnum(nested_type))
throw Exception(
getName() + " cannot process values of type " + nested_type->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -123,21 +126,24 @@ public:
return Method::getReturnType(nested_types[0], nested_types[1]);
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /* input_rows_count */) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /* input_rows_count */) const override
{
if (!(executeNumber<UInt8>(columns, arguments, result)
|| executeNumber<UInt16>(columns, arguments, result)
|| executeNumber<UInt32>(columns, arguments, result)
|| executeNumber<UInt64>(columns, arguments, result)
|| executeNumber<Int8>(columns, arguments, result)
|| executeNumber<Int16>(columns, arguments, result)
|| executeNumber<Int32>(columns, arguments, result)
|| executeNumber<Int64>(columns, arguments, result)
|| executeNumber<Float32>(columns, arguments, result)
|| executeNumber<Float64>(columns, arguments, result)))
throw Exception{"Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function "
ColumnPtr res;
if ( !((res = executeNumber<UInt8>(arguments))
|| (res = executeNumber<UInt16>(arguments))
|| (res = executeNumber<UInt32>(arguments))
|| (res = executeNumber<UInt64>(arguments))
|| (res = executeNumber<Int8>(arguments))
|| (res = executeNumber<Int16>(arguments))
|| (res = executeNumber<Int32>(arguments))
|| (res = executeNumber<Int64>(arguments))
|| (res = executeNumber<Float32>(arguments))
|| (res = executeNumber<Float64>(arguments))))
throw Exception{"Illegal column " + arguments[0].column->getName() + " of first argument of function "
+ getName(),
ErrorCodes::ILLEGAL_COLUMN};
return res;
}
};

View File

@ -69,19 +69,14 @@ public:
return arguments[0];
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, size_t input_rows_count) const override
{
const auto & return_type = columns[result].type;
if (return_type->onlyNull())
{
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
return return_type->createColumnConstWithDefaultValue(input_rows_count);
auto & array_column = columns[arguments[0]].column;
const auto & offset_column = columns[arguments[1]].column;
const auto & length_column = arguments.size() > 2 ? columns[arguments[2]].column : nullptr;
auto & array_column = arguments[0].column;
const auto & offset_column = arguments[1].column;
const auto & length_column = arguments.size() > 2 ? arguments[2].column : nullptr;
std::unique_ptr<GatherUtils::IArraySource> source;
@ -105,8 +100,7 @@ public:
{
if (!length_column || length_column->onlyNull())
{
columns[result].column = array_column;
return;
return array_column;
}
else if (isColumnConst(*length_column))
sink = GatherUtils::sliceFromLeftConstantOffsetBounded(*source, 0, length_column->getInt(0));
@ -146,7 +140,7 @@ public:
sink = GatherUtils::sliceDynamicOffsetBounded(*source, *offset_column, *length_column);
}
columns[result].column = std::move(sink);
return sink;
}
bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -57,7 +57,7 @@ public:
return std::make_shared<DataTypeUInt32>();
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override;
private:
/// Initially allocate a piece of memory for 512 elements. NOTE: This is just a guess.
@ -121,7 +121,7 @@ private:
};
void FunctionArrayUniq::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const
ColumnPtr FunctionArrayUniq::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{
const ColumnArray::Offsets * offsets = nullptr;
const size_t num_arguments = arguments.size();
@ -131,14 +131,14 @@ void FunctionArrayUniq::executeImpl(ColumnsWithTypeAndName & columns, const Colu
Columns array_holders;
for (size_t i = 0; i < num_arguments; ++i)
{
const ColumnPtr & array_ptr = columns[arguments[i]].column;
const ColumnPtr & array_ptr = arguments[i].column;
const ColumnArray * array = checkAndGetColumn<ColumnArray>(array_ptr.get());
if (!array)
{
const ColumnConst * const_array = checkAndGetColumnConst<ColumnArray>(
columns[arguments[i]].column.get());
arguments[i].column.get());
if (!const_array)
throw Exception("Illegal column " + columns[arguments[i]].column->getName()
throw Exception("Illegal column " + arguments[i].column->getName()
+ " of " + toString(i + 1) + "-th argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
array_holders.emplace_back(const_array->convertToFullColumn());
@ -196,7 +196,7 @@ void FunctionArrayUniq::executeImpl(ColumnsWithTypeAndName & columns, const Colu
executeHashed(*offsets, data_columns, res_values);
}
columns[result].column = std::move(res);
return res;
}
template <typename Method, bool has_null_map>

View File

@ -47,10 +47,10 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
bool useDefaultImplementationForNulls() const override { return false; }
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t num_rows) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t num_rows) const override
{
const auto * col_num = columns[arguments[0]].column.get();
const auto * col_value = columns[arguments[1]].column.get();
const auto * col_num = arguments[0].column.get();
const auto * col_value = arguments[1].column.get();
auto offsets_col = ColumnArray::ColumnOffsets::create();
ColumnArray::Offsets & offsets = offsets_col->getData();
@ -72,7 +72,7 @@ public:
offsets.push_back(offset);
}
columns[result].column = ColumnArray::create(col_value->replicate(offsets)->convertToFullColumnIfConst(), std::move(offsets_col));
return ColumnArray::create(col_value->replicate(offsets)->convertToFullColumnIfConst(), std::move(offsets_col));
}
};

View File

@ -55,7 +55,7 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeTuple>(arguments_types));
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{
size_t num_arguments = arguments.size();
@ -65,7 +65,7 @@ public:
for (size_t i = 0; i < num_arguments; ++i)
{
/// Constant columns cannot be inside tuple. It's only possible to have constant tuple as a whole.
ColumnPtr holder = columns[arguments[i]].column->convertToFullColumnIfConst();
ColumnPtr holder = arguments[i].column->convertToFullColumnIfConst();
const ColumnArray * column_array = checkAndGetColumn<ColumnArray>(holder.get());
@ -86,7 +86,7 @@ public:
tuple_columns[i] = column_array->getDataPtr();
}
columns[result].column = ColumnArray::create(
return ColumnArray::create(
ColumnTuple::create(tuple_columns), static_cast<const ColumnArray &>(*first_array_column).getOffsetsPtr());
}
};

View File

@ -44,11 +44,11 @@ private:
return std::make_shared<DataTypeArray>(std::make_shared<DataType>());
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers &, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName &, const DataTypePtr &, size_t input_rows_count) const override
{
using UnderlyingColumnType = typename TypeToColumnType<typename DataType::FieldType>::ColumnType;
columns[result].column = ColumnArray::create(
return ColumnArray::create(
UnderlyingColumnType::create(),
ColumnArray::ColumnOffsets::create(input_rows_count, 0));
}

View File

@ -45,7 +45,7 @@ public:
return arguments[0];
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
};
@ -53,25 +53,23 @@ namespace
{
namespace FunctionEmptyArrayToSingleImpl
{
bool executeConst(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count)
ColumnPtr executeConst(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count)
{
if (const ColumnConst * const_array = checkAndGetColumnConst<ColumnArray>(columns[arguments[0]].column.get()))
if (const ColumnConst * const_array = checkAndGetColumnConst<ColumnArray>(arguments[0].column.get()))
{
if (const_array->getValue<Array>().empty())
{
auto nested_type = typeid_cast<const DataTypeArray &>(*columns[arguments[0]].type).getNestedType();
auto nested_type = typeid_cast<const DataTypeArray &>(*arguments[0].type).getNestedType();
columns[result].column = columns[result].type->createColumnConst(
return result_type->createColumnConst(
input_rows_count,
Array{nested_type->getDefault()});
}
else
columns[result].column = columns[arguments[0]].column;
return true;
return arguments[0].column;
}
else
return false;
return nullptr;
}
template <typename T, bool nullable>
@ -369,14 +367,14 @@ namespace
}
void FunctionEmptyArrayToSingle::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr FunctionEmptyArrayToSingle::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
if (FunctionEmptyArrayToSingleImpl::executeConst(columns, arguments, result, input_rows_count))
return;
if (auto res = FunctionEmptyArrayToSingleImpl::executeConst(arguments, result_type, input_rows_count))
return res;
const ColumnArray * array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get());
const ColumnArray * array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!array)
throw Exception("Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function " + getName(),
throw Exception("Illegal column " + arguments[0].column->getName() + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
MutableColumnPtr res_ptr = array->cloneEmpty();
@ -414,7 +412,7 @@ void FunctionEmptyArrayToSingle::executeImpl(ColumnsWithTypeAndName & columns, c
else
FunctionEmptyArrayToSingleImpl::executeDispatch<false>(*inner_col, src_offsets, *inner_res_col, res_offsets, src_null_map, res_null_map);
columns[result].column = std::move(res_ptr);
return res_ptr;
}

View File

@ -49,20 +49,20 @@ public:
return std::make_shared<DataTypeUInt8>();
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{
size_t rows = input_rows_count;
size_t num_args = arguments.size();
DataTypePtr common_type = nullptr;
auto commonType = [&common_type, &columns, &arguments]()
auto commonType = [&common_type, &arguments]()
{
if (common_type == nullptr)
{
DataTypes data_types;
data_types.reserve(arguments.size());
for (const auto & argument : arguments)
data_types.push_back(columns[argument].type);
data_types.push_back(argument.type);
common_type = getLeastSupertype(data_types);
}
@ -74,10 +74,10 @@ public:
for (size_t i = 0; i < num_args; ++i)
{
const auto & argument = columns[arguments[i]];
const auto & argument = arguments[i];
ColumnPtr preprocessed_column = argument.column;
const auto argument_type = typeid_cast<const DataTypeArray *>(argument.type.get());
const auto * argument_type = typeid_cast<const DataTypeArray *>(argument.type.get());
const auto & nested_type = argument_type->getNestedType();
/// Converts Array(Nothing) or Array(Nullable(Nothing) to common type. Example: hasAll([Null, 1], [Null]) -> 1
@ -93,23 +93,23 @@ public:
{
bool is_const = false;
if (auto argument_column_const = typeid_cast<const ColumnConst *>(argument_column.get()))
if (const auto * argument_column_const = typeid_cast<const ColumnConst *>(argument_column.get()))
{
is_const = true;
argument_column = argument_column_const->getDataColumnPtr();
}
if (auto argument_column_array = typeid_cast<const ColumnArray *>(argument_column.get()))
if (const auto * argument_column_array = typeid_cast<const ColumnArray *>(argument_column.get()))
sources.emplace_back(GatherUtils::createArraySource(*argument_column_array, is_const, rows));
else
throw Exception{"Arguments for function " + getName() + " must be arrays.", ErrorCodes::LOGICAL_ERROR};
}
auto result_column = ColumnUInt8::create(rows);
auto result_column_ptr = typeid_cast<ColumnUInt8 *>(result_column.get());
auto * result_column_ptr = typeid_cast<ColumnUInt8 *>(result_column.get());
GatherUtils::sliceHas(*sources[0], *sources[1], search_type, *result_column_ptr);
columns[result].column = std::move(result_column);
return result_column;
}
bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -121,7 +121,7 @@ private:
}
template <typename KeyType, bool is_str_key, typename ValType>
void execute2(ColumnsWithTypeAndName & columns, const size_t result, size_t row_count, TupleMaps & args, const DataTypeTuple & res_type) const
ColumnPtr execute2(size_t row_count, TupleMaps & args, const DataTypeTuple & res_type) const
{
MutableColumnPtr res_tuple = res_type.createColumn();
@ -199,18 +199,18 @@ private:
// same offsets as in keys
to_vals_arr.getOffsets().insert(to_keys_offset.begin(), to_keys_offset.end());
columns[result].column = std::move(res_tuple);
return res_tuple;
}
template <typename KeyType, bool is_str_key>
void execute1(ColumnsWithTypeAndName & columns, const size_t result, size_t row_count, const DataTypeTuple & res_type, TupleMaps & args) const
ColumnPtr execute1(size_t row_count, const DataTypeTuple & res_type, TupleMaps & args) const
{
const auto & promoted_type = (assert_cast<const DataTypeArray *>(res_type.getElements()[1].get()))->getNestedType();
#define MATCH_EXECUTE(is_str) \
switch (promoted_type->getTypeId()) { \
case TypeIndex::Int64: execute2<KeyType, is_str, Int64>(columns, result, row_count, args, res_type); break; \
case TypeIndex::UInt64: execute2<KeyType, is_str, UInt64>(columns, result, row_count, args, res_type); break; \
case TypeIndex::Float64: execute2<KeyType, is_str, Float64>(columns, result, row_count, args, res_type); break; \
case TypeIndex::Int64: return execute2<KeyType, is_str, Int64>(row_count, args, res_type); \
case TypeIndex::UInt64: return execute2<KeyType, is_str, UInt64>(row_count, args, res_type); \
case TypeIndex::Float64: return execute2<KeyType, is_str, Float64>(row_count, args, res_type); \
default: \
throw Exception{"Illegal columns in arguments of function " + getName(), ErrorCodes::ILLEGAL_COLUMN}; \
}
@ -226,9 +226,9 @@ private:
#undef MATCH_EXECUTE
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override
{
const DataTypeTuple * tup_type = checkAndGetDataType<DataTypeTuple>((columns[arguments[0]]).type.get());
const DataTypeTuple * tup_type = checkAndGetDataType<DataTypeTuple>((arguments[0]).type.get());
const DataTypeArray * key_array_type = checkAndGetDataType<DataTypeArray>(tup_type->getElements()[0].get());
const DataTypeArray * val_array_type = checkAndGetDataType<DataTypeArray>(tup_type->getElements()[1].get());
@ -241,9 +241,8 @@ private:
args.reserve(arguments.size());
//prepare columns, extract data columns for direct access and put them to the vector
for (auto arg : arguments)
for (const auto & col : arguments)
{
auto & col = columns[arg];
const ColumnTuple * tup;
bool is_const = isColumnConst(*col.column);
if (is_const)
@ -274,46 +273,36 @@ private:
args.push_back({key_column, val_column, key_offsets, val_offsets, is_const});
}
size_t row_count = columns[arguments[0]].column->size();
size_t row_count = arguments[0].column->size();
auto key_type_id = key_array_type->getNestedType()->getTypeId();
switch (key_type_id)
{
case TypeIndex::Enum8:
case TypeIndex::Int8:
execute1<Int8, false>(columns, result, row_count, res_type, args);
break;
return execute1<Int8, false>(row_count, res_type, args);
case TypeIndex::Enum16:
case TypeIndex::Int16:
execute1<Int16, false>(columns, result, row_count, res_type, args);
break;
return execute1<Int16, false>(row_count, res_type, args);
case TypeIndex::Int32:
execute1<Int32, false>(columns, result, row_count, res_type, args);
break;
return execute1<Int32, false>(row_count, res_type, args);
case TypeIndex::Int64:
execute1<Int64, false>(columns, result, row_count, res_type, args);
break;
return execute1<Int64, false>(row_count, res_type, args);
case TypeIndex::UInt8:
execute1<UInt8, false>(columns, result, row_count, res_type, args);
break;
return execute1<UInt8, false>(row_count, res_type, args);
case TypeIndex::Date:
case TypeIndex::UInt16:
execute1<UInt16, false>(columns, result, row_count, res_type, args);
break;
return execute1<UInt16, false>(row_count, res_type, args);
case TypeIndex::DateTime:
case TypeIndex::UInt32:
execute1<UInt32, false>(columns, result, row_count, res_type, args);
break;
return execute1<UInt32, false>(row_count, res_type, args);
case TypeIndex::UInt64:
execute1<UInt64, false>(columns, result, row_count, res_type, args);
break;
return execute1<UInt64, false>(row_count, res_type, args);
case TypeIndex::UUID:
execute1<UInt128, false>(columns, result, row_count, res_type, args);
break;
return execute1<UInt128, false>(row_count, res_type, args);
case TypeIndex::FixedString:
case TypeIndex::String:
execute1<String, true>(columns, result, row_count, res_type, args);
break;
return execute1<String, true>(row_count, res_type, args);
default:
throw Exception{"Illegal columns in arguments of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}

View File

@ -71,9 +71,7 @@ private:
}
template <typename KeyType, typename ValType>
void execute2(
ColumnsWithTypeAndName & columns, size_t result, ColumnPtr key_column, ColumnPtr val_column, ColumnPtr max_key_column, const DataTypeTuple & res_type)
const
ColumnPtr execute2(ColumnPtr key_column, ColumnPtr val_column, ColumnPtr max_key_column, const DataTypeTuple & res_type) const
{
MutableColumnPtr res_tuple = res_type.createColumn();
@ -213,50 +211,40 @@ private:
}
to_vals_arr.getOffsets().insert(to_keys_offsets.begin(), to_keys_offsets.end());
columns[result].column = std::move(res_tuple);
return res_tuple;
}
template <typename KeyType>
void execute1(
ColumnsWithTypeAndName & columns, size_t result, ColumnPtr key_column, ColumnPtr val_column, ColumnPtr max_key_column, const DataTypeTuple & res_type)
const
ColumnPtr execute1(ColumnPtr key_column, ColumnPtr val_column, ColumnPtr max_key_column, const DataTypeTuple & res_type) const
{
const auto & val_type = (assert_cast<const DataTypeArray *>(res_type.getElements()[1].get()))->getNestedType();
switch (val_type->getTypeId())
{
case TypeIndex::Int8:
execute2<KeyType, Int8>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, Int8>(key_column, val_column, max_key_column, res_type);
case TypeIndex::Int16:
execute2<KeyType, Int16>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, Int16>(key_column, val_column, max_key_column, res_type);
case TypeIndex::Int32:
execute2<KeyType, Int32>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, Int32>(key_column, val_column, max_key_column, res_type);
case TypeIndex::Int64:
execute2<KeyType, Int64>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, Int64>(key_column, val_column, max_key_column, res_type);
case TypeIndex::UInt8:
execute2<KeyType, UInt8>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, UInt8>(key_column, val_column, max_key_column, res_type);
case TypeIndex::UInt16:
execute2<KeyType, UInt16>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, UInt16>(key_column, val_column, max_key_column, res_type);
case TypeIndex::UInt32:
execute2<KeyType, UInt32>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, UInt32>(key_column, val_column, max_key_column, res_type);
case TypeIndex::UInt64:
execute2<KeyType, UInt64>(columns, result, key_column, val_column, max_key_column, res_type);
break;
return execute2<KeyType, UInt64>(key_column, val_column, max_key_column, res_type);
default:
throw Exception{"Illegal columns in arguments of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override
{
auto col1 = columns[arguments[0]];
auto col2 = columns[arguments[1]];
auto col1 = arguments[0];
auto col2 = arguments[1];
const auto * k = assert_cast<const DataTypeArray *>(col1.type.get());
const auto * v = assert_cast<const DataTypeArray *>(col2.type.get());
@ -270,35 +258,27 @@ private:
if (arguments.size() == 3)
{
/* max key provided */
max_key_column = columns[arguments[2]].column;
max_key_column = arguments[2].column;
}
switch (k->getNestedType()->getTypeId())
{
case TypeIndex::Int8:
execute1<Int8>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<Int8>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::Int16:
execute1<Int16>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<Int16>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::Int32:
execute1<Int32>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<Int32>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::Int64:
execute1<Int64>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<Int64>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::UInt8:
execute1<UInt8>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<UInt8>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::UInt16:
execute1<UInt16>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<UInt16>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::UInt32:
execute1<UInt32>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<UInt32>(col1.column, col2.column, max_key_column, res_type);
case TypeIndex::UInt64:
execute1<UInt64>(columns, result, col1.column, col2.column, max_key_column, res_type);
break;
return execute1<UInt64>(col1.column, col2.column, max_key_column, res_type);
default:
throw Exception{"Illegal columns in arguments of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}

View File

@ -57,7 +57,7 @@ private:
}
template <typename T>
bool executeInternal(ColumnsWithTypeAndName & columns, const IColumn * arg, const size_t result) const
ColumnPtr executeInternal(const IColumn * arg) const
{
if (const auto in = checkAndGetColumn<ColumnVector<T>>(arg))
{
@ -94,22 +94,19 @@ private:
out_offsets[row_idx] = offset;
}
columns[result].column = ColumnArray::create(std::move(data_col), std::move(offsets_col));
return true;
return ColumnArray::create(std::move(data_col), std::move(offsets_col));
}
else
return false;
return nullptr;
}
template <typename T>
bool executeConstStartStep(
ColumnsWithTypeAndName & columns, const IColumn * end_arg, const T start, const T step, const size_t input_rows_count, const size_t result) const
ColumnPtr executeConstStartStep(
const IColumn * end_arg, const T start, const T step, const size_t input_rows_count) const
{
auto end_column = checkAndGetColumn<ColumnVector<T>>(end_arg);
if (!end_column)
{
return false;
}
return nullptr;
const auto & end_data = end_column->getData();
@ -157,20 +154,17 @@ private:
out_offsets[row_idx] = offset;
}
columns[result].column = ColumnArray::create(std::move(data_col), std::move(offsets_col));
return true;
return ColumnArray::create(std::move(data_col), std::move(offsets_col));
}
template <typename T>
bool executeConstStep(
ColumnsWithTypeAndName & columns, const IColumn * start_arg, const IColumn * end_arg, const T step, const size_t input_rows_count, const size_t result) const
ColumnPtr executeConstStep(
const IColumn * start_arg, const IColumn * end_arg, const T step, const size_t input_rows_count) const
{
auto start_column = checkAndGetColumn<ColumnVector<T>>(start_arg);
auto end_column = checkAndGetColumn<ColumnVector<T>>(end_arg);
if (!end_column || !start_column)
{
return false;
}
return nullptr;
const auto & start_data = start_column->getData();
const auto & end_data = end_column->getData();
@ -219,20 +213,17 @@ private:
out_offsets[row_idx] = offset;
}
columns[result].column = ColumnArray::create(std::move(data_col), std::move(offsets_col));
return true;
return ColumnArray::create(std::move(data_col), std::move(offsets_col));
}
template <typename T>
bool executeConstStart(
ColumnsWithTypeAndName & columns, const IColumn * end_arg, const IColumn * step_arg, const T start, const size_t input_rows_count, const size_t result) const
ColumnPtr executeConstStart(
const IColumn * end_arg, const IColumn * step_arg, const T start, const size_t input_rows_count) const
{
auto end_column = checkAndGetColumn<ColumnVector<T>>(end_arg);
auto step_column = checkAndGetColumn<ColumnVector<T>>(step_arg);
if (!end_column || !step_column)
{
return false;
}
return nullptr;
const auto & end_data = end_column->getData();
const auto & step_data = step_column->getData();
@ -281,23 +272,19 @@ private:
out_offsets[row_idx] = offset;
}
columns[result].column = ColumnArray::create(std::move(data_col), std::move(offsets_col));
return true;
return ColumnArray::create(std::move(data_col), std::move(offsets_col));
}
template <typename T>
bool executeGeneric(
ColumnsWithTypeAndName & block, const IColumn * start_col, const IColumn * end_col, const IColumn * step_col,
const size_t input_rows_count, const size_t result) const
ColumnPtr executeGeneric(
const IColumn * start_col, const IColumn * end_col, const IColumn * step_col, const size_t input_rows_count) const
{
auto start_column = checkAndGetColumn<ColumnVector<T>>(start_col);
auto end_column = checkAndGetColumn<ColumnVector<T>>(end_col);
auto step_column = checkAndGetColumn<ColumnVector<T>>(step_col);
if (!start_column || !end_column || !step_column)
{
return false;
}
return nullptr;
const auto & start_data = start_column->getData();
const auto & end_start = end_column->getData();
@ -347,36 +334,36 @@ private:
out_offsets[row_idx] = offset;
}
block[result].column = ColumnArray::create(std::move(data_col), std::move(offsets_col));
return true;
return ColumnArray::create(std::move(data_col), std::move(offsets_col));
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{
ColumnPtr res;
if (arguments.size() == 1)
{
const auto * col = columns[arguments[0]].column.get();
if (!executeInternal<UInt8>(columns, col, result) &&
!executeInternal<UInt16>(columns, col, result) &&
!executeInternal<UInt32>(columns, col, result) &&
!executeInternal<UInt64>(columns, col, result))
const auto * col = arguments[0].column.get();
if ( !((res = executeInternal<UInt8>(col))
|| (res = executeInternal<UInt16>(col))
|| (res = executeInternal<UInt32>(col))
|| (res = executeInternal<UInt64>(col))))
{
throw Exception{"Illegal column " + col->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
return;
return res;
}
Columns columns_holder(3);
ColumnRawPtrs column_ptrs(3);
const auto return_type = checkAndGetDataType<DataTypeArray>(columns[result].type.get())->getNestedType();
const auto return_type = checkAndGetDataType<DataTypeArray>(result_type.get())->getNestedType();
for (size_t i = 0; i < arguments.size(); ++i)
{
if (i == 1)
columns_holder[i] = castColumn(columns[arguments[i]], return_type)->convertToFullColumnIfConst();
columns_holder[i] = castColumn(arguments[i], return_type)->convertToFullColumnIfConst();
else
columns_holder[i] = castColumn(columns[arguments[i]], return_type);
columns_holder[i] = castColumn(arguments[i], return_type);
column_ptrs[i] = columns_holder[i].get();
}
@ -390,47 +377,48 @@ private:
bool is_start_const = isColumnConst(*column_ptrs[0]);
bool is_step_const = isColumnConst(*column_ptrs[2]);
bool ok;
if (is_start_const && is_step_const)
{
UInt64 start = assert_cast<const ColumnConst &>(*column_ptrs[0]).getUInt(0);
UInt64 step = assert_cast<const ColumnConst &>(*column_ptrs[2]).getUInt(0);
ok = executeConstStartStep<UInt8>(columns, column_ptrs[1], start, step, input_rows_count, result) ||
executeConstStartStep<UInt16>(columns, column_ptrs[1], start, step, input_rows_count, result) ||
executeConstStartStep<UInt32>(columns, column_ptrs[1], start, step, input_rows_count, result) ||
executeConstStartStep<UInt64>(columns, column_ptrs[1], start, step, input_rows_count, result);
if ((res = executeConstStartStep<UInt8>(column_ptrs[1], start, step, input_rows_count)) ||
(res = executeConstStartStep<UInt16>(column_ptrs[1], start, step, input_rows_count)) ||
(res = executeConstStartStep<UInt32>(column_ptrs[1], start, step, input_rows_count)) ||
(res = executeConstStartStep<UInt64>(column_ptrs[1], start, step, input_rows_count))) {}
}
else if (is_start_const && !is_step_const)
{
UInt64 start = assert_cast<const ColumnConst &>(*column_ptrs[0]).getUInt(0);
ok = executeConstStart<UInt8>(columns, column_ptrs[1], column_ptrs[2], start, input_rows_count, result) ||
executeConstStart<UInt16>(columns, column_ptrs[1], column_ptrs[2], start, input_rows_count, result) ||
executeConstStart<UInt32>(columns, column_ptrs[1], column_ptrs[2], start, input_rows_count, result) ||
executeConstStart<UInt64>(columns, column_ptrs[1], column_ptrs[2], start, input_rows_count, result);
if ((res = executeConstStart<UInt8>(column_ptrs[1], column_ptrs[2], start, input_rows_count)) ||
(res = executeConstStart<UInt16>(column_ptrs[1], column_ptrs[2], start, input_rows_count)) ||
(res = executeConstStart<UInt32>(column_ptrs[1], column_ptrs[2], start, input_rows_count)) ||
(res = executeConstStart<UInt64>(column_ptrs[1], column_ptrs[2], start, input_rows_count))) {}
}
else if (!is_start_const && is_step_const)
{
UInt64 step = assert_cast<const ColumnConst &>(*column_ptrs[2]).getUInt(0);
ok = executeConstStep<UInt8>(columns, column_ptrs[0], column_ptrs[1], step, input_rows_count, result) ||
executeConstStep<UInt16>(columns, column_ptrs[0], column_ptrs[1], step, input_rows_count, result) ||
executeConstStep<UInt32>(columns, column_ptrs[0], column_ptrs[1], step, input_rows_count, result) ||
executeConstStep<UInt64>(columns, column_ptrs[0], column_ptrs[1], step, input_rows_count, result);
if ((res = executeConstStep<UInt8>(column_ptrs[0], column_ptrs[1], step, input_rows_count)) ||
(res = executeConstStep<UInt16>(column_ptrs[0], column_ptrs[1], step, input_rows_count)) ||
(res = executeConstStep<UInt32>(column_ptrs[0], column_ptrs[1], step, input_rows_count)) ||
(res = executeConstStep<UInt64>(column_ptrs[0], column_ptrs[1], step, input_rows_count))) {}
}
else
{
ok = executeGeneric<UInt8>(columns, column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count, result) ||
executeGeneric<UInt16>(columns, column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count, result) ||
executeGeneric<UInt32>(columns, column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count, result) ||
executeGeneric<UInt64>(columns, column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count, result);
if ((res = executeGeneric<UInt8>(column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count)) ||
(res = executeGeneric<UInt16>(column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count)) ||
(res = executeGeneric<UInt32>(column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count)) ||
(res = executeGeneric<UInt64>(column_ptrs[0], column_ptrs[1], column_ptrs[2], input_rows_count))) {}
}
if (!ok)
if (!res)
{
throw Exception{"Illegal columns " + column_ptrs[0]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
return res;
}
};