mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 17:12:03 +00:00
Part 9.
This commit is contained in:
parent
bc58637ec2
commit
9fe51524cc
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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; }
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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>
|
||||
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
};
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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};
|
||||
}
|
||||
|
@ -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};
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user