Merge branch 'master' into run_func_tests_in_parallel

This commit is contained in:
alesapin 2020-10-21 22:52:30 +03:00
commit 620c8e3d38
252 changed files with 3136 additions and 3628 deletions

View File

@ -143,13 +143,12 @@ void LinearModelData::updateState()
void LinearModelData::predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const Context & context) const
{
gradient_computer->predict(container, columns, offset, limit, arguments, weights, bias, context);
gradient_computer->predict(container, arguments, offset, limit, weights, bias, context);
}
void LinearModelData::returnWeights(IColumn & to) const
@ -449,15 +448,14 @@ void IWeightsUpdater::addToBatch(
void LogisticRegression::predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights,
Float64 bias,
const Context & /*context*/) const
{
size_t rows_num = columns[arguments.front()].column->size();
size_t rows_num = arguments.front().column->size();
if (offset > rows_num || offset + limit > rows_num)
throw Exception("Invalid offset and limit for LogisticRegression::predict. "
@ -468,7 +466,7 @@ void LogisticRegression::predict(
for (size_t i = 1; i < arguments.size(); ++i)
{
const ColumnWithTypeAndName & cur_col = columns[arguments[i]];
const ColumnWithTypeAndName & cur_col = arguments[i];
if (!isNativeNumber(cur_col.type))
throw Exception("Prediction arguments must have numeric type", ErrorCodes::BAD_ARGUMENTS);
@ -518,10 +516,9 @@ void LogisticRegression::compute(
void LinearRegression::predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights,
Float64 bias,
const Context & /*context*/) const
@ -531,7 +528,7 @@ void LinearRegression::predict(
throw Exception("In predict function number of arguments differs from the size of weights vector", ErrorCodes::LOGICAL_ERROR);
}
size_t rows_num = columns[arguments.front()].column->size();
size_t rows_num = arguments.front().column->size();
if (offset > rows_num || offset + limit > rows_num)
throw Exception("Invalid offset and limit for LogisticRegression::predict. "
@ -542,7 +539,7 @@ void LinearRegression::predict(
for (size_t i = 1; i < arguments.size(); ++i)
{
const ColumnWithTypeAndName & cur_col = columns[arguments[i]];
const ColumnWithTypeAndName & cur_col = arguments[i];
if (!isNativeNumber(cur_col.type))
throw Exception("Prediction arguments must have numeric type", ErrorCodes::BAD_ARGUMENTS);

View File

@ -39,10 +39,9 @@ public:
virtual void predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights,
Float64 bias,
const Context & context) const = 0;
@ -65,10 +64,9 @@ public:
void predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights,
Float64 bias,
const Context & context) const override;
@ -91,10 +89,9 @@ public:
void predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights,
Float64 bias,
const Context & context) const override;
@ -264,10 +261,9 @@ public:
void predict(
ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const Context & context) const;
void returnWeights(IColumn & to) const;
@ -364,10 +360,9 @@ public:
void predictValues(
ConstAggregateDataPtr place,
IColumn & to,
ColumnsWithTypeAndName & columns,
ColumnsWithTypeAndName & arguments,
size_t offset,
size_t limit,
const ColumnNumbers & arguments,
const Context & context) const override
{
if (arguments.size() != param_num + 1)
@ -382,7 +377,7 @@ public:
throw Exception("Cast of column of predictions is incorrect. getReturnTypeToPredict must return same value as it is casted to",
ErrorCodes::LOGICAL_ERROR);
this->data(place).predict(column->getData(), columns, offset, limit, arguments, context);
this->data(place).predict(column->getData(), arguments, offset, limit, context);
}
/** This function is called if aggregate function without State modifier is selected in a query.

View File

@ -114,10 +114,9 @@ public:
virtual void predictValues(
ConstAggregateDataPtr /* place */,
IColumn & /*to*/,
ColumnsWithTypeAndName & /*block*/,
ColumnsWithTypeAndName & /*arguments*/,
size_t /*offset*/,
size_t /*limit*/,
const ColumnNumbers & /*arguments*/,
const Context & /*context*/) const
{
throw Exception("Method predictValues is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);

View File

@ -161,7 +161,7 @@ MutableColumnPtr ColumnAggregateFunction::convertToValues(MutableColumnPtr colum
return res;
}
MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName & block, const ColumnNumbers & arguments, const Context & context) const
MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName & arguments, const Context & context) const
{
MutableColumnPtr res = func->getReturnTypeToPredict()->createColumn();
res->reserve(data.size());
@ -172,7 +172,7 @@ MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName &
if (data.size() == 1)
{
/// Case for const column. Predict using single model.
machine_learning_function->predictValues(data[0], *res, block, 0, block[arguments.front()].column->size(), arguments, context);
machine_learning_function->predictValues(data[0], *res, arguments, 0, arguments.front().column->size(), context);
}
else
{
@ -180,7 +180,7 @@ MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName &
size_t row_num = 0;
for (auto * val : data)
{
machine_learning_function->predictValues(val, *res, block, row_num, 1, arguments, context);
machine_learning_function->predictValues(val, *res, arguments, row_num, 1, context);
++row_num;
}
}

View File

@ -119,7 +119,7 @@ public:
const char * getFamilyName() const override { return "AggregateFunction"; }
TypeIndex getDataType() const override { return TypeIndex::AggregateFunction; }
MutableColumnPtr predictValues(ColumnsWithTypeAndName & block, const ColumnNumbers & arguments, const Context & context) const;
MutableColumnPtr predictValues(ColumnsWithTypeAndName & arguments, const Context & context) const;
size_t size() const override
{

View File

@ -188,15 +188,10 @@ ColumnWithTypeAndName ColumnFunction::reduce() const
"arguments but " + toString(captured) + " columns were captured.", ErrorCodes::LOGICAL_ERROR);
auto columns = captured_columns;
columns.emplace_back(ColumnWithTypeAndName {nullptr, function->getReturnType(), ""});
ColumnWithTypeAndName res{nullptr, function->getResultType(), ""};
ColumnNumbers arguments(captured_columns.size());
for (size_t i = 0; i < captured_columns.size(); ++i)
arguments[i] = i;
function->execute(columns, arguments, captured_columns.size(), size_);
return columns[captured_columns.size()];
res.column = function->execute(columns, res.type, size_);
return res;
}
}

View File

@ -30,6 +30,8 @@ namespace ProfileEvents
static constexpr size_t log_peak_memory_usage_every = 1ULL << 30;
thread_local bool MemoryTracker::BlockerInThread::is_blocked = false;
MemoryTracker total_memory_tracker(nullptr, VariableContext::Global);
@ -56,13 +58,15 @@ MemoryTracker::~MemoryTracker()
void MemoryTracker::logPeakMemoryUsage() const
{
const auto * description = description_ptr.load(std::memory_order_relaxed);
LOG_DEBUG(&Poco::Logger::get("MemoryTracker"), "Peak memory usage{}: {}.", (description ? " " + std::string(description) : ""), ReadableSize(peak));
LOG_DEBUG(&Poco::Logger::get("MemoryTracker"),
"Peak memory usage{}: {}.", (description ? " " + std::string(description) : ""), ReadableSize(peak));
}
void MemoryTracker::logMemoryUsage(Int64 current) const
{
const auto * description = description_ptr.load(std::memory_order_relaxed);
LOG_DEBUG(&Poco::Logger::get("MemoryTracker"), "Current memory usage{}: {}.", (description ? " " + std::string(description) : ""), ReadableSize(current));
LOG_DEBUG(&Poco::Logger::get("MemoryTracker"),
"Current memory usage{}: {}.", (description ? " " + std::string(description) : ""), ReadableSize(current));
}
@ -71,7 +75,7 @@ void MemoryTracker::alloc(Int64 size)
if (size < 0)
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Negative size ({}) is passed to MemoryTracker. It is a bug.", size);
if (blocker.isCancelled())
if (BlockerInThread::isBlocked())
return;
/** Using memory_order_relaxed means that if allocations are done simultaneously,
@ -86,12 +90,15 @@ void MemoryTracker::alloc(Int64 size)
Int64 current_hard_limit = hard_limit.load(std::memory_order_relaxed);
Int64 current_profiler_limit = profiler_limit.load(std::memory_order_relaxed);
/// Cap the limit to the total_memory_tracker, since it may include some drift.
/// Cap the limit to the total_memory_tracker, since it may include some drift
/// for user-level memory tracker.
///
/// And since total_memory_tracker is reset to the process resident
/// memory peridically (in AsynchronousMetrics::update()), any limit can be
/// capped to it, to avoid possible drift.
if (unlikely(current_hard_limit && will_be > current_hard_limit))
if (unlikely(current_hard_limit
&& will_be > current_hard_limit
&& level == VariableContext::User))
{
Int64 total_amount = total_memory_tracker.get();
if (amount > total_amount)
@ -104,10 +111,8 @@ void MemoryTracker::alloc(Int64 size)
std::bernoulli_distribution fault(fault_probability);
if (unlikely(fault_probability && fault(thread_local_rng)))
{
free(size);
/// Prevent recursion. Exception::ctor -> std::string -> new[] -> MemoryTracker::alloc
auto untrack_lock = blocker.cancel(); // NOLINT
BlockerInThread untrack_lock;
ProfileEvents::increment(ProfileEvents::QueryMemoryLimitExceeded);
std::stringstream message;
@ -118,12 +123,13 @@ void MemoryTracker::alloc(Int64 size)
<< " (attempt to allocate chunk of " << size << " bytes)"
<< ", maximum: " << formatReadableSizeWithBinarySuffix(current_hard_limit);
amount.fetch_sub(size, std::memory_order_relaxed);
throw DB::Exception(message.str(), DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED);
}
if (unlikely(current_profiler_limit && will_be > current_profiler_limit))
{
auto no_track = blocker.cancel();
BlockerInThread untrack_lock;
DB::TraceCollector::collect(DB::TraceType::Memory, StackTrace(), size);
setOrRaiseProfilerLimit((will_be + profiler_step - 1) / profiler_step * profiler_step);
}
@ -131,16 +137,14 @@ void MemoryTracker::alloc(Int64 size)
std::bernoulli_distribution sample(sample_probability);
if (unlikely(sample_probability && sample(thread_local_rng)))
{
auto no_track = blocker.cancel();
BlockerInThread untrack_lock;
DB::TraceCollector::collect(DB::TraceType::MemorySample, StackTrace(), size);
}
if (unlikely(current_hard_limit && will_be > current_hard_limit))
{
free(size);
/// Prevent recursion. Exception::ctor -> std::string -> new[] -> MemoryTracker::alloc
auto no_track = blocker.cancel(); // NOLINT
BlockerInThread untrack_lock;
ProfileEvents::increment(ProfileEvents::QueryMemoryLimitExceeded);
std::stringstream message;
@ -151,6 +155,7 @@ void MemoryTracker::alloc(Int64 size)
<< " (attempt to allocate chunk of " << size << " bytes)"
<< ", maximum: " << formatReadableSizeWithBinarySuffix(current_hard_limit);
amount.fetch_sub(size, std::memory_order_relaxed);
throw DB::Exception(message.str(), DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED);
}
@ -177,13 +182,13 @@ void MemoryTracker::updatePeak(Int64 will_be)
void MemoryTracker::free(Int64 size)
{
if (blocker.isCancelled())
if (BlockerInThread::isBlocked())
return;
std::bernoulli_distribution sample(sample_probability);
if (unlikely(sample_probability && sample(thread_local_rng)))
{
auto no_track = blocker.cancel();
BlockerInThread untrack_lock;
DB::TraceCollector::collect(DB::TraceType::MemorySample, StackTrace(), -size);
}
@ -298,11 +303,3 @@ namespace CurrentMemoryTracker
}
}
}
DB::SimpleActionLock getCurrentMemoryTrackerActionLock()
{
auto * memory_tracker = DB::CurrentThread::getMemoryTracker();
if (!memory_tracker)
return {};
return memory_tracker->blocker.cancel();
}

View File

@ -3,7 +3,6 @@
#include <atomic>
#include <common/types.h>
#include <Common/CurrentMetrics.h>
#include <Common/SimpleActionBlocker.h>
#include <Common/VariableContext.h>
@ -131,8 +130,18 @@ public:
/// Prints info about peak memory consumption into log.
void logPeakMemoryUsage() const;
/// To be able to temporarily stop memory tracker
DB::SimpleActionBlocker blocker;
/// To be able to temporarily stop memory tracking from current thread.
struct BlockerInThread
{
private:
BlockerInThread(const BlockerInThread &) = delete;
BlockerInThread & operator=(const BlockerInThread &) = delete;
static thread_local bool is_blocked;
public:
BlockerInThread() { is_blocked = true; }
~BlockerInThread() { is_blocked = false; }
static bool isBlocked() { return is_blocked; }
};
};
extern MemoryTracker total_memory_tracker;
@ -145,7 +154,3 @@ namespace CurrentMemoryTracker
void realloc(Int64 old_size, Int64 new_size);
void free(Int64 size);
}
/// Holding this object will temporarily disable memory tracking.
DB::SimpleActionLock getCurrentMemoryTrackerActionLock();

View File

@ -60,27 +60,17 @@ public:
using ArrayA = typename ColVecA::Container;
using ArrayB = typename ColVecB::Container;
DecimalComparison(ColumnsWithTypeAndName & data, size_t result, const ColumnWithTypeAndName & col_left, const ColumnWithTypeAndName & col_right)
{
if (!apply(data, result, col_left, col_right))
throw Exception("Wrong decimal comparison with " + col_left.type->getName() + " and " + col_right.type->getName(),
ErrorCodes::LOGICAL_ERROR);
}
static bool apply(ColumnsWithTypeAndName & data, size_t result [[maybe_unused]],
const ColumnWithTypeAndName & col_left, const ColumnWithTypeAndName & col_right)
static ColumnPtr apply(const ColumnWithTypeAndName & col_left, const ColumnWithTypeAndName & col_right)
{
if constexpr (_actual)
{
ColumnPtr c_res;
Shift shift = getScales<A, B>(col_left.type, col_right.type);
c_res = applyWithScale(col_left.column, col_right.column, shift);
if (c_res)
data[result].column = std::move(c_res);
return true;
return applyWithScale(col_left.column, col_right.column, shift);
}
return false;
else
return nullptr;
}
static bool compare(A a, B b, UInt32 scale_a, UInt32 scale_b)

View File

@ -92,7 +92,7 @@ struct ToStartOfWeekImpl
template <typename FromType, typename ToType, typename Transform>
struct Transformer
{
Transformer(Transform transform_)
explicit Transformer(Transform transform_)
: transform(std::move(transform_))
{}
@ -116,29 +116,29 @@ template <typename FromDataType, typename ToDataType>
struct CustomWeekTransformImpl
{
template <typename Transform>
static void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/, Transform transform = {})
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/, Transform transform = {})
{
const auto op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>{std::move(transform)};
UInt8 week_mode = DEFAULT_WEEK_MODE;
if (arguments.size() > 1)
{
if (const auto week_mode_column = checkAndGetColumnConst<ColumnUInt8>(columns[arguments[1]].column.get()))
if (const auto * week_mode_column = checkAndGetColumnConst<ColumnUInt8>(arguments[1].column.get()))
week_mode = week_mode_column->getValue<UInt8>();
}
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(columns, arguments, 2, 0);
const ColumnPtr source_col = columns[arguments[0]].column;
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(arguments, 2, 0);
const ColumnPtr source_col = arguments[0].column;
if (const auto * sources = checkAndGetColumn<typename FromDataType::ColumnType>(source_col.get()))
{
auto col_to = ToDataType::ColumnType::create();
op.vector(sources->getData(), col_to->getData(), week_mode, time_zone);
columns[result].column = std::move(col_to);
return col_to;
}
else
{
throw Exception(
"Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function "
"Illegal column " + arguments[0].column->getName() + " of first argument of function "
+ Transform::name,
ErrorCodes::ILLEGAL_COLUMN);
}

View File

@ -683,25 +683,25 @@ struct Transformer
template <typename FromDataType, typename ToDataType, typename Transform>
struct DateTimeTransformImpl
{
static void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/, const Transform & transform = {})
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/, const Transform & transform = {})
{
using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>;
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(columns, arguments, 1, 0);
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(arguments, 1, 0);
const ColumnPtr source_col = columns[arguments[0]].column;
const ColumnPtr source_col = arguments[0].column;
if (const auto * sources = checkAndGetColumn<typename FromDataType::ColumnType>(source_col.get()))
{
auto mutable_result_col = columns[result].type->createColumn();
auto mutable_result_col = result_type->createColumn();
auto * col_to = assert_cast<typename ToDataType::ColumnType *>(mutable_result_col.get());
Op::vector(sources->getData(), col_to->getData(), time_zone, transform);
columns[result].column = std::move(mutable_result_col);
return mutable_result_col;
}
else
{
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + Transform::name,
ErrorCodes::ILLEGAL_COLUMN);
}

View File

@ -91,14 +91,14 @@ public:
return std::make_shared<DataTypeString>();
}
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
{
const ColumnPtr column_string = columns[arguments[0]].column;
const ColumnPtr column_string = arguments[0].column;
const ColumnString * input = checkAndGetColumn<ColumnString>(column_string.get());
if (!input)
throw Exception(
"Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function " + getName(),
"Illegal column " + arguments[0].column->getName() + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
auto dst_column = ColumnString::create();
@ -111,9 +111,9 @@ public:
const ColumnString::Offsets & src_offsets = input->getOffsets();
auto source = input->getChars().data();
auto dst = dst_data.data();
auto dst_pos = dst;
const auto * source = input->getChars().data();
auto * dst = dst_data.data();
auto * dst_pos = dst;
size_t src_offset_prev = 0;
@ -141,7 +141,7 @@ public:
{
// during decoding character array can be partially polluted
// if fail, revert back and clean
auto savepoint = dst_pos;
auto * savepoint = dst_pos;
outlen = _tb64d(reinterpret_cast<const uint8_t *>(source), srclen, reinterpret_cast<uint8_t *>(dst_pos));
if (!outlen)
{
@ -166,7 +166,7 @@ public:
dst_data.resize(dst_pos - dst);
columns[result].column = std::move(dst_column);
return dst_column;
}
};
}

View File

@ -613,17 +613,17 @@ class FunctionBinaryArithmetic : public IFunction
}
/// Multiply aggregation state by integer constant: by merging it with itself specified number of times.
void executeAggregateMultiply(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr executeAggregateMultiply(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const
{
ColumnNumbers new_arguments = arguments;
if (WhichDataType(columns[new_arguments[1]].type).isAggregateFunction())
ColumnsWithTypeAndName new_arguments = arguments;
if (WhichDataType(new_arguments[1].type).isAggregateFunction())
std::swap(new_arguments[0], new_arguments[1]);
if (!isColumnConst(*columns[new_arguments[1]].column))
throw Exception{"Illegal column " + columns[new_arguments[1]].column->getName()
if (!isColumnConst(*new_arguments[1].column))
throw Exception{"Illegal column " + new_arguments[1].column->getName()
+ " of argument of aggregation state multiply. Should be integer constant", ErrorCodes::ILLEGAL_COLUMN};
const IColumn & agg_state_column = *columns[new_arguments[0]].column;
const IColumn & agg_state_column = *new_arguments[0].column;
bool agg_state_is_const = isColumnConst(agg_state_column);
const ColumnAggregateFunction & column = typeid_cast<const ColumnAggregateFunction &>(
agg_state_is_const ? assert_cast<const ColumnConst &>(agg_state_column).getDataColumn() : agg_state_column);
@ -647,7 +647,7 @@ class FunctionBinaryArithmetic : public IFunction
auto & vec_to = column_to->getData();
auto & vec_from = column_from->getData();
UInt64 m = typeid_cast<const ColumnConst *>(columns[new_arguments[1]].column.get())->getValue<UInt64>();
UInt64 m = typeid_cast<const ColumnConst *>(new_arguments[1].column.get())->getValue<UInt64>();
// Since we merge the function states by ourselves, we have to have an
// Arena for this. Pass it to the resulting column so that the arena
@ -674,16 +674,16 @@ class FunctionBinaryArithmetic : public IFunction
}
if (agg_state_is_const)
columns[result].column = ColumnConst::create(std::move(column_to), input_rows_count);
return ColumnConst::create(std::move(column_to), input_rows_count);
else
columns[result].column = std::move(column_to);
return column_to;
}
/// Merge two aggregation states together.
void executeAggregateAddition(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr executeAggregateAddition(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const
{
const IColumn & lhs_column = *columns[arguments[0]].column;
const IColumn & rhs_column = *columns[arguments[1]].column;
const IColumn & lhs_column = *arguments[0].column;
const IColumn & rhs_column = *arguments[1].column;
bool lhs_is_const = isColumnConst(lhs_column);
bool rhs_is_const = isColumnConst(rhs_column);
@ -707,37 +707,33 @@ class FunctionBinaryArithmetic : public IFunction
}
if (lhs_is_const && rhs_is_const)
columns[result].column = ColumnConst::create(std::move(column_to), input_rows_count);
return ColumnConst::create(std::move(column_to), input_rows_count);
else
columns[result].column = std::move(column_to);
return column_to;
}
void executeDateTimeIntervalPlusMinus(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments,
size_t result, size_t input_rows_count, const FunctionOverloadResolverPtr & function_builder) const
ColumnPtr executeDateTimeIntervalPlusMinus(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
size_t input_rows_count, const FunctionOverloadResolverPtr & function_builder) const
{
ColumnNumbers new_arguments = arguments;
ColumnsWithTypeAndName new_arguments = arguments;
/// Interval argument must be second.
if (WhichDataType(columns[arguments[1]].type).isDateOrDateTime())
if (WhichDataType(arguments[1].type).isDateOrDateTime())
std::swap(new_arguments[0], new_arguments[1]);
/// Change interval argument type to its representation
ColumnsWithTypeAndName new_columns = columns;
new_columns[new_arguments[1]].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>();
new_arguments[1].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>();
ColumnsWithTypeAndName new_arguments_with_type_and_name =
{new_columns[new_arguments[0]], new_columns[new_arguments[1]]};
auto function = function_builder->build(new_arguments_with_type_and_name);
auto function = function_builder->build(new_arguments);
function->execute(new_columns, new_arguments, result, input_rows_count);
columns[result].column = new_columns[result].column;
return function->execute(new_arguments, result_type, input_rows_count);
}
public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBinaryArithmetic>(context); }
FunctionBinaryArithmetic(const Context & context_)
explicit FunctionBinaryArithmetic(const Context & context_)
: context(context_),
check_decimal_overflow(decimalCheckArithmeticOverflow(context))
{}
@ -790,7 +786,7 @@ public:
new_arguments[1].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>();
auto function = function_builder->build(new_arguments);
return function->getReturnType();
return function->getResultType();
}
DataTypePtr type_res;
@ -851,20 +847,20 @@ public:
return type_res;
}
bool executeFixedString(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeFixedString(ColumnsWithTypeAndName & arguments) const
{
using OpImpl = FixedStringOperationImpl<Op<UInt8, UInt8>>;
auto col_left_raw = columns[arguments[0]].column.get();
auto col_right_raw = columns[arguments[1]].column.get();
if (auto col_left_const = checkAndGetColumnConst<ColumnFixedString>(col_left_raw))
const auto * col_left_raw = arguments[0].column.get();
const auto * col_right_raw = arguments[1].column.get();
if (const auto * col_left_const = checkAndGetColumnConst<ColumnFixedString>(col_left_raw))
{
if (auto col_right_const = checkAndGetColumnConst<ColumnFixedString>(col_right_raw))
if (const auto * col_right_const = checkAndGetColumnConst<ColumnFixedString>(col_right_raw))
{
auto col_left = checkAndGetColumn<ColumnFixedString>(col_left_const->getDataColumn());
auto col_right = checkAndGetColumn<ColumnFixedString>(col_right_const->getDataColumn());
const auto * col_left = checkAndGetColumn<ColumnFixedString>(col_left_const->getDataColumn());
const auto * col_right = checkAndGetColumn<ColumnFixedString>(col_right_const->getDataColumn());
if (col_left->getN() != col_right->getN())
return false;
return nullptr;
auto col_res = ColumnFixedString::create(col_left->getN());
auto & out_chars = col_res->getChars();
out_chars.resize(col_left->getN());
@ -872,25 +868,24 @@ public:
col_right->getChars().data(),
out_chars.data(),
out_chars.size());
columns[result].column = ColumnConst::create(std::move(col_res), col_left_raw->size());
return true;
return ColumnConst::create(std::move(col_res), col_left_raw->size());
}
}
bool is_left_column_const = checkAndGetColumnConst<ColumnFixedString>(col_left_raw) != nullptr;
bool is_right_column_const = checkAndGetColumnConst<ColumnFixedString>(col_right_raw) != nullptr;
auto col_left = is_left_column_const
const auto * col_left = is_left_column_const
? checkAndGetColumn<ColumnFixedString>(checkAndGetColumnConst<ColumnFixedString>(col_left_raw)->getDataColumn())
: checkAndGetColumn<ColumnFixedString>(col_left_raw);
auto col_right = is_right_column_const
const auto * col_right = is_right_column_const
? checkAndGetColumn<ColumnFixedString>(checkAndGetColumnConst<ColumnFixedString>(col_right_raw)->getDataColumn())
: checkAndGetColumn<ColumnFixedString>(col_right_raw);
if (col_left && col_right)
{
if (col_left->getN() != col_right->getN())
return false;
return nullptr;
auto col_res = ColumnFixedString::create(col_left->getN());
auto & out_chars = col_res->getChars();
@ -922,14 +917,13 @@ public:
out_chars.size(),
col_left->getN());
}
columns[result].column = std::move(col_res);
return true;
return col_res;
}
return false;
return nullptr;
}
template <typename A, typename B>
bool executeNumeric(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result [[maybe_unused]], const A & left, const B & right) const
ColumnPtr executeNumeric(ColumnsWithTypeAndName & arguments, const A & left, const B & right) const
{
using LeftDataType = std::decay_t<decltype(left)>;
using RightDataType = std::decay_t<decltype(right)>;
@ -944,8 +938,8 @@ public:
using ColVecT1 = std::conditional_t<IsDecimalNumber<T1>, ColumnDecimal<T1>, ColumnVector<T1>>;
using ColVecResult = std::conditional_t<IsDecimalNumber<ResultType>, ColumnDecimal<ResultType>, ColumnVector<ResultType>>;
auto col_left_raw = columns[arguments[0]].column.get();
auto col_right_raw = columns[arguments[1]].column.get();
const auto * col_left_raw = arguments[0].column.get();
const auto * col_right_raw = arguments[1].column.get();
auto col_left_const = checkAndGetColumnConst<ColVecT0>(col_left_raw);
auto col_right_const = checkAndGetColumnConst<ColVecT1>(col_right_raw);
@ -981,9 +975,8 @@ public:
OpImplCheck::template constantConstant<dec_a, dec_b>(const_a, const_b, scale_a, scale_b) :
OpImpl::template constantConstant<dec_a, dec_b>(const_a, const_b, scale_a, scale_b);
columns[result].column = ResultDataType(type.getPrecision(), type.getScale()).createColumnConst(
return ResultDataType(type.getPrecision(), type.getScale()).createColumnConst(
col_left_const->size(), toField(res, type.getScale()));
return true;
}
col_res = ColVecResult::create(0, type.getScale());
@ -1016,7 +1009,7 @@ public:
OpImpl::template vectorConstant<dec_a, dec_b>(col_left->getData(), const_b, vec_res, scale_a, scale_b);
}
else
return false;
return nullptr;
}
else
{
@ -1026,8 +1019,7 @@ public:
if (col_left_const && col_right_const)
{
auto res = OpImpl::constantConstant(col_left_const->template getValue<T0>(), col_right_const->template getValue<T1>());
columns[result].column = ResultDataType().createColumnConst(col_left_const->size(), toField(res));
return true;
return ResultDataType().createColumnConst(col_left_const->size(), toField(res));
}
col_res = ColVecResult::create();
@ -1047,43 +1039,40 @@ public:
OpImpl::vectorConstant(col_left->getData().data(), col_right_const->template getValue<T1>(), vec_res.data(), vec_res.size());
}
else
return false;
return nullptr;
}
columns[result].column = std::move(col_res);
return true;
return col_res;
}
return false;
return nullptr;
}
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
{
/// Special case when multiply aggregate function state
if (isAggregateMultiply(columns[arguments[0]].type, columns[arguments[1]].type))
if (isAggregateMultiply(arguments[0].type, arguments[1].type))
{
executeAggregateMultiply(columns, arguments, result, input_rows_count);
return;
return executeAggregateMultiply(arguments, result_type, input_rows_count);
}
/// Special case - addition of two aggregate functions states
if (isAggregateAddition(columns[arguments[0]].type, columns[arguments[1]].type))
if (isAggregateAddition(arguments[0].type, arguments[1].type))
{
executeAggregateAddition(columns, arguments, result, input_rows_count);
return;
return executeAggregateAddition(arguments, result_type, input_rows_count);
}
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
if (auto function_builder
= getFunctionForIntervalArithmetic(columns[arguments[0]].type, columns[arguments[1]].type, context))
= getFunctionForIntervalArithmetic(arguments[0].type, arguments[1].type, context))
{
executeDateTimeIntervalPlusMinus(columns, arguments, result, input_rows_count, function_builder);
return;
return executeDateTimeIntervalPlusMinus(arguments, result_type, input_rows_count, function_builder);
}
const auto & left_argument = columns[arguments[0]];
const auto & right_argument = columns[arguments[1]];
auto * left_generic = left_argument.type.get();
auto * right_generic = right_argument.type.get();
const auto & left_argument = arguments[0];
const auto & right_argument = arguments[1];
const auto * left_generic = left_argument.type.get();
const auto * right_generic = right_argument.type.get();
ColumnPtr res;
bool valid = castBothTypes(left_generic, right_generic, [&](const auto & left, const auto & right)
{
using LeftDataType = std::decay_t<decltype(left)>;
@ -1093,10 +1082,10 @@ public:
if constexpr (!Op<DataTypeFixedString, DataTypeFixedString>::allow_fixed_string)
return false;
else
return executeFixedString(columns, arguments, result);
return (res = executeFixedString(arguments)) != nullptr;
}
else
return executeNumeric(columns, arguments, result, left, right);
return (res = executeNumeric(arguments, left, right)) != nullptr;
});
if (!valid)
@ -1109,6 +1098,8 @@ public:
left_argument.name, left_argument.type->getName(),
right_argument.name, right_argument.type->getName());
}
return res;
}
#if USE_EMBEDDED_COMPILER
@ -1190,30 +1181,26 @@ public:
{
}
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
{
if (left.column && isColumnConst(*left.column) && arguments.size() == 1)
{
ColumnsWithTypeAndName columns_with_constant
= {{left.column->cloneResized(input_rows_count), left.type, left.name},
columns[arguments[0]],
columns[result]};
arguments[0]};
Base::executeImpl(columns_with_constant, {0, 1}, 2, input_rows_count);
columns[result] = columns_with_constant[2];
return Base::executeImpl(columns_with_constant, result_type, input_rows_count);
}
else if (right.column && isColumnConst(*right.column) && arguments.size() == 1)
{
ColumnsWithTypeAndName columns_with_constant
= {columns[arguments[0]],
{right.column->cloneResized(input_rows_count), right.type, right.name},
columns[result]};
= {arguments[0],
{right.column->cloneResized(input_rows_count), right.type, right.name}};
Base::executeImpl(columns_with_constant, {0, 1}, 2, input_rows_count);
columns[result] = columns_with_constant[2];
return Base::executeImpl(columns_with_constant, result_type, input_rows_count);
}
else
Base::executeImpl(columns, arguments, result, input_rows_count);
return Base::executeImpl(arguments, result_type, input_rows_count);
}
bool hasInformationAboutMonotonicity() const override
@ -1246,12 +1233,11 @@ public:
{
ColumnsWithTypeAndName columns_with_constant
= {{left.column->cloneResized(1), left.type, left.name},
{right.type->createColumnConst(1, point), right.type, right.name},
{nullptr, return_type, ""}};
{right.type->createColumnConst(1, point), right.type, right.name}};
Base::executeImpl(columns_with_constant, {0, 1}, 2, 1);
auto col = Base::executeImpl(columns_with_constant, return_type, 1);
Field point_transformed;
columns_with_constant[2].column->get(0, point_transformed);
col->get(0, point_transformed);
return point_transformed;
};
transform(left_point);
@ -1282,12 +1268,11 @@ public:
{
ColumnsWithTypeAndName columns_with_constant
= {{left.type->createColumnConst(1, point), left.type, left.name},
{right.column->cloneResized(1), right.type, right.name},
{nullptr, return_type, ""}};
{right.column->cloneResized(1), right.type, right.name}};
Base::executeImpl(columns_with_constant, {0, 1}, 2, 1);
auto col = Base::executeImpl(columns_with_constant, return_type, 1);
Field point_transformed;
columns_with_constant[2].column->get(0, point_transformed);
col->get(0, point_transformed);
return point_transformed;
};

View File

@ -54,32 +54,35 @@ 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 & result_type, size_t /*input_rows_count*/) const override
{
const auto value_col = columns[arguments.front()].column.get();
const auto * value_col = arguments.front().column.get();
if (!execute<UInt8>(columns, arguments, result, value_col)
&& !execute<UInt16>(columns, arguments, result, value_col)
&& !execute<UInt32>(columns, arguments, result, value_col)
&& !execute<UInt64>(columns, arguments, result, value_col)
&& !execute<Int8>(columns, arguments, result, value_col)
&& !execute<Int16>(columns, arguments, result, value_col)
&& !execute<Int32>(columns, arguments, result, value_col)
&& !execute<Int64>(columns, arguments, result, value_col))
ColumnPtr res;
if (!((res = execute<UInt8>(arguments, result_type, value_col))
|| (res = execute<UInt16>(arguments, result_type, value_col))
|| (res = execute<UInt32>(arguments, result_type, value_col))
|| (res = execute<UInt64>(arguments, result_type, value_col))
|| (res = execute<Int8>(arguments, result_type, value_col))
|| (res = execute<Int16>(arguments, result_type, value_col))
|| (res = execute<Int32>(arguments, result_type, value_col))
|| (res = execute<Int64>(arguments, result_type, value_col))))
throw Exception{"Illegal column " + value_col->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
return res;
}
private:
template <typename T>
bool execute(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, const size_t result,
ColumnPtr execute(
ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
const IColumn * const value_col_untyped) const
{
if (const auto value_col = checkAndGetColumn<ColumnVector<T>>(value_col_untyped))
{
const auto size = value_col->size();
bool is_const;
const auto const_mask = createConstMaskIfConst<T>(columns, arguments, is_const);
const auto const_mask = createConstMaskIfConst<T>(arguments, is_const);
const auto & val = value_col->getData();
auto out_col = ColumnVector<UInt8>::create(size);
@ -92,29 +95,28 @@ private:
}
else
{
const auto mask = createMask<T>(size, columns, arguments);
const auto mask = createMask<T>(size, arguments);
for (const auto i : ext::range(0, size))
out[i] = Impl::apply(val[i], mask[i]);
}
columns[result].column = std::move(out_col);
return true;
return out_col;
}
else if (const auto value_col_const = checkAndGetColumnConst<ColumnVector<T>>(value_col_untyped))
{
const auto size = value_col_const->size();
bool is_const;
const auto const_mask = createConstMaskIfConst<T>(columns, arguments, is_const);
const auto const_mask = createConstMaskIfConst<T>(arguments, is_const);
const auto val = value_col_const->template getValue<T>();
if (is_const)
{
columns[result].column = columns[result].type->createColumnConst(size, toField(Impl::apply(val, const_mask)));
return result_type->createColumnConst(size, toField(Impl::apply(val, const_mask)));
}
else
{
const auto mask = createMask<T>(size, columns, arguments);
const auto mask = createMask<T>(size, arguments);
auto out_col = ColumnVector<UInt8>::create(size);
auto & out = out_col->getData();
@ -122,24 +124,22 @@ private:
for (const auto i : ext::range(0, size))
out[i] = Impl::apply(val, mask[i]);
columns[result].column = std::move(out_col);
return out_col;
}
return true;
}
return false;
return nullptr;
}
template <typename ValueType>
ValueType createConstMaskIfConst(const ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, bool & out_is_const) const
ValueType createConstMaskIfConst(const ColumnsWithTypeAndName & arguments, bool & out_is_const) const
{
out_is_const = true;
ValueType mask = 0;
for (const auto i : ext::range(1, arguments.size()))
{
if (auto pos_col_const = checkAndGetColumnConst<ColumnVector<ValueType>>(columns[arguments[i]].column.get()))
if (auto pos_col_const = checkAndGetColumnConst<ColumnVector<ValueType>>(arguments[i].column.get()))
{
const auto pos = pos_col_const->getUInt(0);
if (pos < 8 * sizeof(ValueType))
@ -156,13 +156,13 @@ private:
}
template <typename ValueType>
PaddedPODArray<ValueType> createMask(const size_t size, const ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments) const
PaddedPODArray<ValueType> createMask(const size_t size, const ColumnsWithTypeAndName & arguments) const
{
PaddedPODArray<ValueType> mask(size, ValueType{});
for (const auto i : ext::range(1, arguments.size()))
{
const auto pos_col = columns[arguments[i]].column.get();
const auto * pos_col = arguments[i].column.get();
if (!addToMaskImpl<UInt8>(mask, pos_col)
&& !addToMaskImpl<UInt16>(mask, pos_col)

View File

@ -96,26 +96,26 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; }
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 IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type);
if (which.isDate())
CustomWeekTransformImpl<DataTypeDate, ToDataType>::execute(
columns, arguments, result, input_rows_count, Transform{});
return CustomWeekTransformImpl<DataTypeDate, ToDataType>::execute(
arguments, result_type, input_rows_count, Transform{});
else if (which.isDateTime())
CustomWeekTransformImpl<DataTypeDateTime, ToDataType>::execute(
columns, arguments, result, input_rows_count, Transform{});
return CustomWeekTransformImpl<DataTypeDateTime, ToDataType>::execute(
arguments, result_type, input_rows_count, Transform{});
else if (which.isDateTime64())
{
CustomWeekTransformImpl<DataTypeDateTime64, ToDataType>::execute(
columns, arguments, result, input_rows_count,
return CustomWeekTransformImpl<DataTypeDateTime64, ToDataType>::execute(
arguments, result_type, input_rows_count,
TransformDateTime64<Transform>{assert_cast<const DataTypeDateTime64 *>(from_type)->getScale()});
}
else
throw Exception(
"Illegal type " + columns[arguments[0]].type->getName() + " of argument of function " + getName(),
"Illegal type " + arguments[0].type->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}

View File

@ -305,7 +305,7 @@ private:
template <typename FromDataType, typename ToDataType, typename Transform>
struct DateTimeAddIntervalImpl
{
static void execute(Transform transform, ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result)
static ColumnPtr execute(Transform transform, ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type)
{
using FromValueType = typename FromDataType::FieldType;
using FromColumnType = typename FromDataType::ColumnType;
@ -313,16 +313,16 @@ struct DateTimeAddIntervalImpl
auto op = Adder<Transform>{std::move(transform)};
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(columns, arguments, 2, 0);
const DateLUTImpl & time_zone = extractTimeZoneFromFunctionArguments(arguments, 2, 0);
const ColumnPtr source_col = columns[arguments[0]].column;
const ColumnPtr source_col = arguments[0].column;
auto result_col = columns[result].type->createColumn();
auto result_col = result_type->createColumn();
auto col_to = assert_cast<ToColumnType *>(result_col.get());
if (const auto * sources = checkAndGetColumn<FromColumnType>(source_col.get()))
{
const IColumn & delta_column = *columns[arguments[1]].column;
const IColumn & delta_column = *arguments[1].column;
if (const auto * delta_const_column = typeid_cast<const ColumnConst *>(&delta_column))
op.vectorConstant(sources->getData(), col_to->getData(), delta_const_column->getInt(0), time_zone);
@ -334,16 +334,16 @@ struct DateTimeAddIntervalImpl
op.constantVector(
sources_const->template getValue<FromValueType>(),
col_to->getData(),
*columns[arguments[1]].column, time_zone);
*arguments[1].column, time_zone);
}
else
{
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + Transform::name,
ErrorCodes::ILLEGAL_COLUMN);
}
columns[result].column = std::move(result_col);
return result_col;
}
};
@ -463,28 +463,28 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {2}; }
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 IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type);
if (which.isDate())
{
DateTimeAddIntervalImpl<DataTypeDate, TransformResultDataType<DataTypeDate>, Transform>::execute(
Transform{}, columns, arguments, result);
return DateTimeAddIntervalImpl<DataTypeDate, TransformResultDataType<DataTypeDate>, Transform>::execute(
Transform{}, arguments, result_type);
}
else if (which.isDateTime())
{
DateTimeAddIntervalImpl<DataTypeDateTime, TransformResultDataType<DataTypeDateTime>, Transform>::execute(
Transform{}, columns, arguments, result);
return DateTimeAddIntervalImpl<DataTypeDateTime, TransformResultDataType<DataTypeDateTime>, Transform>::execute(
Transform{}, arguments, result_type);
}
else if (const auto * datetime64_type = assert_cast<const DataTypeDateTime64 *>(from_type))
{
DateTimeAddIntervalImpl<DataTypeDateTime64, TransformResultDataType<DataTypeDateTime64>, Transform>::execute(
Transform{datetime64_type->getScale()}, columns, arguments, result);
return DateTimeAddIntervalImpl<DataTypeDateTime64, TransformResultDataType<DataTypeDateTime64>, Transform>::execute(
Transform{datetime64_type->getScale()}, arguments, result_type);
}
else
throw Exception("Illegal type " + columns[arguments[0]].type->getName() + " of first argument of function " + getName(),
throw Exception("Illegal type " + arguments[0].type->getName() + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
};

View File

@ -95,23 +95,23 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
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 IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type);
if (which.isDate())
DateTimeTransformImpl<DataTypeDate, ToDataType, Transform>::execute(columns, arguments, result, input_rows_count);
return DateTimeTransformImpl<DataTypeDate, ToDataType, Transform>::execute(arguments, result_type, input_rows_count);
else if (which.isDateTime())
DateTimeTransformImpl<DataTypeDateTime, ToDataType, Transform>::execute(columns, arguments, result, input_rows_count);
return DateTimeTransformImpl<DataTypeDateTime, ToDataType, Transform>::execute(arguments, result_type, input_rows_count);
else if (which.isDateTime64())
{
const auto scale = static_cast<const DataTypeDateTime64 *>(from_type)->getScale();
const TransformDateTime64<Transform> transformer(scale);
DateTimeTransformImpl<DataTypeDateTime64, ToDataType, decltype(transformer)>::execute(columns, arguments, result, input_rows_count, transformer);
return DateTimeTransformImpl<DataTypeDateTime64, ToDataType, decltype(transformer)>::execute(arguments, result_type, input_rows_count, transformer);
}
else
throw Exception("Illegal type " + columns[arguments[0]].type->getName() + " of argument of function " + getName(),
throw Exception("Illegal type " + arguments[0].type->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}

View File

@ -34,9 +34,9 @@ public:
return std::make_shared<DataTypeString>();
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers &, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName &, const DataTypePtr & result_type, size_t input_rows_count) const override
{
columns[result].column = columns[result].type->createColumnConst(
return result_type->createColumnConst(
input_rows_count, getFQDNOrHostName())->convertToFullColumnIfConst();
}
};

View File

@ -7,7 +7,6 @@
#include <Columns/ColumnLowCardinality.h>
#include <Common/assert_cast.h>
#include <DataTypes/DataTypeNullable.h>
#include <DataTypes/DataTypeLowCardinality.h>
namespace DB
@ -51,16 +50,12 @@ Columns convertConstTupleToConstantElements(const ColumnConst & column)
}
static ColumnsWithTypeAndName createBlockWithNestedColumnsImpl(const ColumnsWithTypeAndName & columns, const std::unordered_set<size_t> & args)
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns)
{
ColumnsWithTypeAndName res;
size_t num_columns = columns.size();
for (size_t i = 0; i < num_columns; ++i)
for (const auto & col : columns)
{
const auto & col = columns[i];
if (args.count(i) && col.type->isNullable())
if (col.type->isNullable())
{
const DataTypePtr & nested_type = static_cast<const DataTypeNullable &>(*col.type).getNestedType();
@ -88,20 +83,6 @@ static ColumnsWithTypeAndName createBlockWithNestedColumnsImpl(const ColumnsWith
return res;
}
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args)
{
std::unordered_set<size_t> args_set(args.begin(), args.end());
return createBlockWithNestedColumnsImpl(columns, args_set);
}
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result)
{
std::unordered_set<size_t> args_set(args.begin(), args.end());
args_set.insert(result);
return createBlockWithNestedColumnsImpl(columns, args_set);
}
void validateArgumentType(const IFunction & func, const DataTypes & arguments,
size_t argument_index, bool (* validator_func)(const IDataType &),
const char * expected_type_description)

View File

@ -82,13 +82,9 @@ inline std::enable_if_t<IsDecimalNumber<T>, Field> toField(const T & x, UInt32 s
Columns convertConstTupleToConstantElements(const ColumnConst & column);
/// Returns the copy of a given columns in which each column specified in
/// the "arguments" parameter is replaced with its respective nested
/// Returns the copy of a given columns in which each column is replaced with its respective nested
/// column if it is nullable.
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args);
/// Similar function as above. Additionally transform the result type if needed.
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result);
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns);
/// Checks argument type at specified index with predicate.
/// throws if there is no argument at specified index or if predicate returns false.

View File

@ -17,19 +17,19 @@ namespace ErrorCodes
}
template <bool or_null>
void ExecutableFunctionJoinGet<or_null>::execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t)
ColumnPtr ExecutableFunctionJoinGet<or_null>::execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t)
{
ColumnsWithTypeAndName keys;
for (size_t i = 2; i < arguments.size(); ++i)
{
auto key = columns[arguments[i]];
auto key = arguments[i];
keys.emplace_back(std::move(key));
}
columns[result] = join->joinGet(keys, result_columns);
return join->joinGet(keys, result_columns).column;
}
template <bool or_null>
ExecutableFunctionImplPtr FunctionJoinGet<or_null>::prepare(const ColumnsWithTypeAndName &, const ColumnNumbers &, size_t) const
ExecutableFunctionImplPtr FunctionJoinGet<or_null>::prepare(const ColumnsWithTypeAndName &) const
{
return std::make_unique<ExecutableFunctionJoinGet<or_null>>(join, DB::Block{{return_type->createColumn(), return_type, attr_name}});
}

View File

@ -24,7 +24,7 @@ public:
bool useDefaultImplementationForLowCardinalityColumns() const override { return true; }
bool useDefaultImplementationForConstants() const override { return true; }
void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override;
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) override;
String getName() const override { return name; }
@ -54,9 +54,9 @@ public:
String getName() const override { return name; }
const DataTypes & getArgumentTypes() const override { return argument_types; }
const DataTypePtr & getReturnType() const override { return return_type; }
const DataTypePtr & getResultType() const override { return return_type; }
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & sample_columns, const ColumnNumbers & arguments, size_t result) const override;
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName &) const override;
private:
TableLockHolder table_lock;

View File

@ -54,7 +54,7 @@ private:
}
template <typename LeftType, typename RightType>
bool executeTyped(ColumnsWithTypeAndName & columns, const size_t result, const ColumnConst * left_arg, const IColumn * right_arg) const
ColumnPtr executeTyped(const ColumnConst * left_arg, const IColumn * right_arg) const
{
if (const auto right_arg_typed = checkAndGetColumn<ColumnVector<RightType>>(right_arg))
{
@ -95,15 +95,14 @@ private:
memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64));
}
columns[result].column = std::move(dst);
return true;
return dst;
}
return false;
return nullptr;
}
template <typename LeftType, typename RightType>
bool executeTyped(ColumnsWithTypeAndName & columns, const size_t result, const ColumnVector<LeftType> * left_arg, const IColumn * right_arg) const
ColumnPtr executeTyped(const ColumnVector<LeftType> * left_arg, const IColumn * right_arg) const
{
if (const auto right_arg_typed = checkAndGetColumn<ColumnVector<RightType>>(right_arg))
{
@ -157,8 +156,7 @@ private:
memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64));
}
columns[result].column = std::move(dst);
return true;
return dst;
}
if (const auto right_arg_typed = checkAndGetColumnConst<ColumnVector<RightType>>(right_arg))
{
@ -200,17 +198,17 @@ private:
memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64));
}
columns[result].column = std::move(dst);
return true;
return dst;
}
return false;
return nullptr;
}
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
{
const ColumnWithTypeAndName & col_left = columns[arguments[0]];
const ColumnWithTypeAndName & col_right = columns[arguments[1]];
const ColumnWithTypeAndName & col_left = arguments[0];
const ColumnWithTypeAndName & col_right = arguments[1];
ColumnPtr res;
auto call = [&](const auto & types) -> bool
{
@ -224,7 +222,7 @@ private:
if (const auto left_arg_typed = checkAndGetColumn<ColVecLeft>(left_arg))
{
if (executeTyped<LeftType, RightType>(columns, result, left_arg_typed, right_arg))
if ((res = executeTyped<LeftType, RightType>(left_arg_typed, right_arg)))
return true;
throw Exception{"Illegal column " + right_arg->getName() + " of second argument of function " + getName(),
@ -232,7 +230,7 @@ private:
}
if (const auto left_arg_typed = checkAndGetColumnConst<ColVecLeft>(left_arg))
{
if (executeTyped<LeftType, RightType>(columns, result, left_arg_typed, right_arg))
if ((res = executeTyped<LeftType, RightType>(left_arg_typed, right_arg)))
return true;
throw Exception{"Illegal column " + right_arg->getName() + " of second argument of function " + getName(),
@ -248,6 +246,8 @@ private:
if (!callOnBasicTypes<true, true, false, false>(left_index, right_index, call))
throw Exception{"Illegal column " + col_left.column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN};
return res;
}
};

View File

@ -25,9 +25,9 @@ private:
return std::make_shared<DataTypeFloat64>();
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers &, size_t result, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName &, const DataTypePtr & result_type, size_t input_rows_count) const override
{
columns[result].column = columns[result].type->createColumnConst(input_rows_count, Impl::value);
return result_type->createColumnConst(input_rows_count, Impl::value);
}
};

View File

@ -113,7 +113,7 @@ private:
}
template <typename T, typename ReturnType>
static bool execute(ColumnsWithTypeAndName & columns, const ColumnVector<T> * col, const size_t result)
static ColumnPtr execute(const ColumnVector<T> * col)
{
const auto & src_data = col->getData();
const size_t size = src_data.size();
@ -124,12 +124,11 @@ private:
executeInIterations(src_data.data(), dst_data.data(), size);
columns[result].column = std::move(dst);
return true;
return dst;
}
template <typename T, typename ReturnType>
static bool execute(ColumnsWithTypeAndName & columns, const ColumnDecimal<T> * col, const size_t result)
static ColumnPtr execute(const ColumnDecimal<T> * col)
{
const auto & src_data = col->getData();
const size_t size = src_data.size();
@ -144,15 +143,15 @@ private:
executeInIterations(dst_data.data(), dst_data.data(), size);
columns[result].column = std::move(dst);
return true;
return dst;
}
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnWithTypeAndName & col = columns[arguments[0]];
const ColumnWithTypeAndName & col = arguments[0];
ColumnPtr res;
auto call = [&](const auto & types) -> bool
{
@ -162,12 +161,14 @@ private:
using ColVecType = std::conditional_t<IsDecimalNumber<Type>, ColumnDecimal<Type>, ColumnVector<Type>>;
const auto col_vec = checkAndGetColumn<ColVecType>(col.column.get());
return execute<Type, ReturnType>(columns, col_vec, result);
return (res = execute<Type, ReturnType>(col_vec)) != nullptr;
};
if (!callOnBasicType<void, true, true, true, false>(col.type->getTypeId(), call))
throw Exception{"Illegal column " + col.column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN};
return res;
}
};

View File

@ -46,25 +46,28 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const auto in = columns[arguments.front()].column.get();
const auto * in = arguments.front().column.get();
if ( !execute<UInt8>(columns, in, result)
&& !execute<UInt16>(columns, in, result)
&& !execute<UInt32>(columns, in, result)
&& !execute<UInt64>(columns, in, result)
&& !execute<Int8>(columns, in, result)
&& !execute<Int16>(columns, in, result)
&& !execute<Int32>(columns, in, result)
&& !execute<Int64>(columns, in, result)
&& !execute<Float32>(columns, in, result)
&& !execute<Float64>(columns, in, result))
ColumnPtr res;
if (!((res = execute<UInt8>(in))
|| (res = execute<UInt16>(in))
|| (res = execute<UInt32>(in))
|| (res = execute<UInt64>(in))
|| (res = execute<Int8>(in))
|| (res = execute<Int16>(in))
|| (res = execute<Int32>(in))
|| (res = execute<Int64>(in))
|| (res = execute<Float32>(in))
|| (res = execute<Float64>(in))))
throw Exception{"Illegal column " + in->getName() + " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
return res;
}
template <typename T>
bool execute(ColumnsWithTypeAndName & columns, const IColumn * in_untyped, const size_t result) const
ColumnPtr execute(const IColumn * in_untyped) const
{
if (const auto in = checkAndGetColumn<ColumnVector<T>>(in_untyped))
{
@ -78,11 +81,10 @@ public:
for (const auto i : ext::range(0, size))
out_data[i] = Impl::execute(in_data[i]);
columns[result].column = std::move(out);
return true;
return out;
}
return false;
return nullptr;
}
};

View File

@ -63,10 +63,10 @@ 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
{
const IColumn * haystack_column = columns[arguments[0]].column.get();
const IColumn * needle_column = columns[arguments[1]].column.get();
const IColumn * haystack_column = arguments[0].column.get();
const IColumn * needle_column = arguments[1].column.get();
auto col_res = ColumnVector<UInt8>::create();
typename ColumnVector<UInt8>::Container & vec_res = col_res->getData();
@ -84,7 +84,7 @@ public:
else
throw Exception("Illegal combination of columns as arguments of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
columns[result].column = std::move(col_res);
return col_res;
}
private:
@ -159,9 +159,9 @@ public:
#endif
}
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
{
selector.selectAndExecute(columns, arguments, result, input_rows_count);
return selector.selectAndExecute(arguments, result_type, input_rows_count);
}
static FunctionPtr create(const Context & context)

View File

@ -50,9 +50,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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 ColumnPtr column = columns[arguments[0]].column;
const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{
auto col_res = ColumnVector<ResultType>::create();
@ -61,7 +61,7 @@ public:
vec_res.resize(col->size());
Impl::vector(col->getChars(), col->getOffsets(), vec_res);
columns[result].column = std::move(col_res);
return col_res;
}
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get()))
{
@ -70,7 +70,7 @@ public:
ResultType res = 0;
Impl::vectorFixedToConstant(col_fixed->getChars(), col_fixed->getN(), res);
columns[result].column = columns[result].type->createColumnConst(col_fixed->size(), toField(res));
return result_type->createColumnConst(col_fixed->size(), toField(res));
}
else
{
@ -80,7 +80,7 @@ public:
vec_res.resize(col_fixed->size());
Impl::vectorFixedToVector(col_fixed->getChars(), col_fixed->getN(), vec_res);
columns[result].column = std::move(col_res);
return col_res;
}
}
else if (const ColumnArray * col_arr = checkAndGetColumn<ColumnArray>(column.get()))
@ -91,10 +91,10 @@ public:
vec_res.resize(col_arr->size());
Impl::array(col_arr->getOffsets(), vec_res);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() + " of argument of function " + getName(),
throw Exception("Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
};

View File

@ -52,17 +52,17 @@ public:
return std::make_shared<DataTypeString>();
}
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
{
const ColumnPtr column_src = columns[arguments[0]].column;
const ColumnPtr column_needle = columns[arguments[1]].column;
const ColumnPtr column_replacement = columns[arguments[2]].column;
const ColumnPtr column_src = arguments[0].column;
const ColumnPtr column_needle = arguments[1].column;
const ColumnPtr column_replacement = arguments[2].column;
if (!isColumnConst(*column_needle) || !isColumnConst(*column_replacement))
throw Exception("2nd and 3rd arguments of function " + getName() + " must be constants.", ErrorCodes::ILLEGAL_COLUMN);
const IColumn * c1 = columns[arguments[1]].column.get();
const IColumn * c2 = columns[arguments[2]].column.get();
const IColumn * c1 = arguments[1].column.get();
const IColumn * c2 = arguments[2].column.get();
const ColumnConst * c1_const = typeid_cast<const ColumnConst *>(c1);
const ColumnConst * c2_const = typeid_cast<const ColumnConst *>(c2);
String needle = c1_const->getValue<String>();
@ -75,17 +75,17 @@ public:
{
auto col_res = ColumnString::create();
Impl::vector(col->getChars(), col->getOffsets(), needle, replacement, col_res->getChars(), col_res->getOffsets());
columns[result].column = std::move(col_res);
return col_res;
}
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column_src.get()))
{
auto col_res = ColumnString::create();
Impl::vectorFixed(col_fixed->getChars(), col_fixed->getN(), needle, replacement, col_res->getChars(), col_res->getOffsets());
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception(
"Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function " + getName(),
"Illegal column " + arguments[0].column->getName() + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
};

View File

@ -52,24 +52,24 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr column = columns[arguments[0]].column;
const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{
auto col_res = ColumnString::create();
Impl::vector(col->getChars(), col->getOffsets(), col_res->getChars(), col_res->getOffsets());
columns[result].column = std::move(col_res);
return col_res;
}
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get()))
{
auto col_res = ColumnFixedString::create(col_fixed->getN());
Impl::vectorFixed(col_fixed->getChars(), col_fixed->getN(), col_res->getChars());
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception(
"Illegal column " + columns[arguments[0]].column->getName() + " of argument of function " + getName(),
"Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
};

View File

@ -154,9 +154,10 @@ public:
return result;
}
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
{
bool valid = castType(columns[arguments[0]].type.get(), [&](const auto & type)
ColumnPtr result_column;
bool valid = castType(arguments[0].type.get(), [&](const auto & type)
{
using DataType = std::decay_t<decltype(type)>;
@ -164,13 +165,13 @@ public:
{
if constexpr (allow_fixed_string)
{
if (auto col = checkAndGetColumn<ColumnFixedString>(columns[arguments[0]].column.get()))
if (const auto * col = checkAndGetColumn<ColumnFixedString>(arguments[0].column.get()))
{
auto col_res = ColumnFixedString::create(col->getN());
auto & vec_res = col_res->getChars();
vec_res.resize(col->size() * col->getN());
FixedStringUnaryOperationImpl<Op<UInt8>>::vector(col->getChars(), vec_res);
columns[result].column = std::move(col_res);
result_column = std::move(col_res);
return true;
}
}
@ -180,13 +181,13 @@ public:
using T0 = typename DataType::FieldType;
if constexpr (allow_decimal)
{
if (auto col = checkAndGetColumn<ColumnDecimal<T0>>(columns[arguments[0]].column.get()))
if (auto col = checkAndGetColumn<ColumnDecimal<T0>>(arguments[0].column.get()))
{
auto col_res = ColumnDecimal<typename Op<T0>::ResultType>::create(0, type.getScale());
auto & vec_res = col_res->getData();
vec_res.resize(col->getData().size());
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
columns[result].column = std::move(col_res);
result_column = std::move(col_res);
return true;
}
}
@ -194,13 +195,13 @@ public:
else
{
using T0 = typename DataType::FieldType;
if (auto col = checkAndGetColumn<ColumnVector<T0>>(columns[arguments[0]].column.get()))
if (auto col = checkAndGetColumn<ColumnVector<T0>>(arguments[0].column.get()))
{
auto col_res = ColumnVector<typename Op<T0>::ResultType>::create();
auto & vec_res = col_res->getData();
vec_res.resize(col->getData().size());
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
columns[result].column = std::move(col_res);
result_column = std::move(col_res);
return true;
}
}
@ -209,6 +210,8 @@ public:
});
if (!valid)
throw Exception(getName() + "'s argument does not match the expected data type", ErrorCodes::LOGICAL_ERROR);
return result_column;
}
#if USE_EMBEDDED_COMPILER

View File

@ -65,13 +65,12 @@ public:
}
}
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
{
using SourceColumnType = typename SourceDataType::ColumnType;
using ResultColumnType = typename ResultDataType::ColumnType;
const auto & src = columns[arguments[0]];
auto & res = columns[result];
const auto & src = arguments[0];
const auto & col = *src.column;
const SourceColumnType * source_col_typed = checkAndGetColumn<SourceColumnType>(col);
@ -80,16 +79,16 @@ public:
+ std::string(SourceDataType::family_name),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
res.column = res.type->createColumn();
auto res_column = result_type->createColumn();
if (input_rows_count == 0)
return;
return res_column;
auto & result_data = assert_cast<ResultColumnType &>(res.column->assumeMutableRef()).getData();
auto & result_data = assert_cast<ResultColumnType &>(res_column->assumeMutableRef()).getData();
result_data.reserve(source_col_typed->size());
const auto & source_data = source_col_typed->getData();
const auto scale_diff = getScaleDiff(*checkAndGetDataType<SourceDataType>(src.type.get()), *checkAndGetDataType<ResultDataType>(res.type.get()));
const auto scale_diff = getScaleDiff(*checkAndGetDataType<SourceDataType>(src.type.get()), *checkAndGetDataType<ResultDataType>(result_type.get()));
if (scale_diff == 0)
{
static_assert(sizeof(typename SourceColumnType::Container::value_type) == sizeof(typename ResultColumnType::Container::value_type));
@ -114,6 +113,8 @@ public:
for (const auto & v : source_data)
result_data.push_back(static_cast<Int64>(toDestValue(v) / scale_multiplier));
}
return res_column;
}
private:

View File

@ -178,23 +178,23 @@ private:
return std::make_shared<DataTypeString>();
}
void executeImpl(DB::ColumnsWithTypeAndName & block, 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
{
using namespace OpenSSLDetails;
const auto mode = block[arguments[0]].column->getDataAt(0);
const auto mode = arguments[0].column->getDataAt(0);
if (mode.size == 0 || !std::string_view(mode).starts_with("aes-"))
throw Exception("Invalid mode: " + mode.toString(), ErrorCodes::BAD_ARGUMENTS);
auto evp_cipher = getCipherByName(mode);
const auto * evp_cipher = getCipherByName(mode);
if (evp_cipher == nullptr)
throw Exception("Invalid mode: " + mode.toString(), ErrorCodes::BAD_ARGUMENTS);
const auto cipher_mode = EVP_CIPHER_mode(evp_cipher);
const auto input_column = block[arguments[1]].column;
const auto key_column = block[arguments[2]].column;
const auto input_column = arguments[1].column;
const auto key_column = arguments[2].column;
OpenSSLDetails::validateCipherMode<compatibility_mode>(evp_cipher);
@ -203,7 +203,7 @@ private:
result_column = doEncrypt(evp_cipher, input_rows_count, input_column, key_column, nullptr, nullptr);
else
{
const auto iv_column = block[arguments[3]].column;
const auto iv_column = arguments[3].column;
if (compatibility_mode != OpenSSLDetails::CompatibilityMode::MySQL && EVP_CIPHER_iv_length(evp_cipher) == 0)
throw Exception(mode.toString() + " does not support IV", ErrorCodes::BAD_ARGUMENTS);
@ -216,12 +216,12 @@ private:
if (cipher_mode != EVP_CIPH_GCM_MODE)
throw Exception("AAD can be only set for GCM-mode", ErrorCodes::BAD_ARGUMENTS);
const auto aad_column = block[arguments[4]].column;
const auto aad_column = arguments[4].column;
result_column = doEncrypt(evp_cipher, input_rows_count, input_column, key_column, iv_column, aad_column);
}
}
block[result].column = std::move(result_column);
return result_column;
}
template <typename InputColumnType, typename KeyColumnType, typename IvColumnType, typename AadColumnType>
@ -262,7 +262,7 @@ private:
using namespace OpenSSLDetails;
auto evp_ctx_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)>(EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free);
auto evp_ctx = evp_ctx_ptr.get();
auto * evp_ctx = evp_ctx_ptr.get();
const auto block_size = static_cast<size_t>(EVP_CIPHER_block_size(evp_cipher));
const auto key_size = static_cast<size_t>(EVP_CIPHER_key_length(evp_cipher));
@ -293,7 +293,7 @@ private:
#endif
}
auto encrypted = encrypted_result_column_data.data();
auto * encrypted = encrypted_result_column_data.data();
KeyHolder<mode> key_holder;
@ -453,29 +453,29 @@ private:
return std::make_shared<DataTypeString>();
}
void executeImpl(DB::ColumnsWithTypeAndName & block, 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
{
using namespace OpenSSLDetails;
const auto mode = block[arguments[0]].column->getDataAt(0);
const auto mode = arguments[0].column->getDataAt(0);
if (mode.size == 0 || !std::string_view(mode).starts_with("aes-"))
throw Exception("Invalid mode: " + mode.toString(), ErrorCodes::BAD_ARGUMENTS);
auto evp_cipher = getCipherByName(mode);
const auto * evp_cipher = getCipherByName(mode);
if (evp_cipher == nullptr)
throw Exception("Invalid mode: " + mode.toString(), ErrorCodes::BAD_ARGUMENTS);
OpenSSLDetails::validateCipherMode<compatibility_mode>(evp_cipher);
const auto input_column = block[arguments[1]].column;
const auto key_column = block[arguments[2]].column;
const auto input_column = arguments[1].column;
const auto key_column = arguments[2].column;
ColumnPtr result_column;
if (arguments.size() <= 3)
result_column = doDecrypt(evp_cipher, input_rows_count, input_column, key_column, nullptr, nullptr);
else
{
const auto iv_column = block[arguments[3]].column;
const auto iv_column = arguments[3].column;
if (compatibility_mode != OpenSSLDetails::CompatibilityMode::MySQL && EVP_CIPHER_iv_length(evp_cipher) == 0)
throw Exception(mode.toString() + " does not support IV", ErrorCodes::BAD_ARGUMENTS);
@ -488,12 +488,12 @@ private:
if (EVP_CIPHER_mode(evp_cipher) != EVP_CIPH_GCM_MODE)
throw Exception("AAD can be only set for GCM-mode", ErrorCodes::BAD_ARGUMENTS);
const auto aad_column = block[arguments[4]].column;
const auto aad_column = arguments[4].column;
result_column = doDecrypt(evp_cipher, input_rows_count, input_column, key_column, iv_column, aad_column);
}
}
block[result].column = std::move(result_column);
return result_column;
}
template <typename InputColumnType, typename KeyColumnType, typename IvColumnType, typename AadColumnType>
@ -535,7 +535,7 @@ private:
using namespace OpenSSLDetails;
auto evp_ctx_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)>(EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free);
auto evp_ctx = evp_ctx_ptr.get();
auto * evp_ctx = evp_ctx_ptr.get();
[[maybe_unused]] const auto block_size = static_cast<size_t>(EVP_CIPHER_block_size(evp_cipher));
[[maybe_unused]] const auto iv_size = static_cast<size_t>(EVP_CIPHER_iv_length(evp_cipher));
@ -566,7 +566,7 @@ private:
decrypted_result_column_data.resize(resulting_size);
#endif
}
auto decrypted = decrypted_result_column_data.data();
auto * decrypted = decrypted_result_column_data.data();
KeyHolder<mode> key_holder;
for (size_t r = 0; r < input_rows_count; ++r)

View File

@ -104,7 +104,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() + ".",
@ -122,23 +122,23 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const IDataType * from_type = columns[arguments[0]].type.get();
auto array_type = typeid_cast<const DataTypeArray *>(from_type);
auto nested_type = array_type->getNestedType();
const IDataType * from_type = arguments[0].type.get();
const auto * array_type = typeid_cast<const DataTypeArray *>(from_type);
const auto & nested_type = array_type->getNestedType();
DataTypes argument_types = {nested_type};
WhichDataType which(nested_type);
if (which.isUInt8())
executeBitmapData<UInt8>(columns, argument_types, arguments, result);
return executeBitmapData<UInt8>(argument_types, arguments);
else if (which.isUInt16())
executeBitmapData<UInt16>(columns, argument_types, arguments, result);
return executeBitmapData<UInt16>(argument_types, arguments);
else if (which.isUInt32())
executeBitmapData<UInt32>(columns, argument_types, arguments, result);
return executeBitmapData<UInt32>(argument_types, arguments);
else if (which.isUInt64())
executeBitmapData<UInt64>(columns, argument_types, arguments, result);
return executeBitmapData<UInt64>(argument_types, arguments);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -146,11 +146,11 @@ public:
private:
template <typename T>
void executeBitmapData(ColumnsWithTypeAndName & columns, DataTypes & argument_types, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeBitmapData(DataTypes & argument_types, ColumnsWithTypeAndName & arguments) const
{
// input data
const ColumnArray * array = typeid_cast<const ColumnArray *>(columns[arguments[0]].column.get());
ColumnPtr mapped = array->getDataPtr();
const ColumnArray * array = typeid_cast<const ColumnArray *>(arguments[0].column.get());
const ColumnPtr & mapped = array->getDataPtr();
const ColumnArray::Offsets & offsets = array->getOffsets();
const ColumnVector<T> * column = checkAndGetColumn<ColumnVector<T>>(&*mapped);
const typename ColumnVector<T>::Container & input_data = column->getData();
@ -174,7 +174,7 @@ private:
bitmap_data.rbs.add(input_data[pos]);
}
}
columns[result].column = std::move(col_to);
return col_to;
}
};
@ -207,32 +207,32 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
// input data
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);
IColumn & res_data = res.getData();
ColumnArray::Offsets & res_offsets = res.getOffsets();
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, res_data, res_offsets);
executeIntType<UInt8>(arguments, input_rows_count, res_data, res_offsets);
else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, input_rows_count, res_data, res_offsets);
executeIntType<UInt16>(arguments, input_rows_count, res_data, res_offsets);
else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, input_rows_count, res_data, res_offsets);
executeIntType<UInt32>(arguments, input_rows_count, res_data, res_offsets);
else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, res_data, res_offsets);
executeIntType<UInt64>(arguments, input_rows_count, res_data, res_offsets);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
columns[result].column = std::move(res_ptr);
return res_ptr;
}
private:
@ -240,11 +240,11 @@ private:
template <typename T>
void executeIntType(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t input_rows_count, IColumn & res_data_col, ColumnArray::Offsets & res_offsets)
ColumnsWithTypeAndName & arguments, size_t input_rows_count, IColumn & res_data_col, ColumnArray::Offsets & res_offsets)
const
{
const ColumnAggregateFunction * column
= typeid_cast<const ColumnAggregateFunction *>(columns[arguments[0]].column.get());
= typeid_cast<const ColumnAggregateFunction *>(arguments[0].column.get());
PaddedPODArray<T> & res_data = typeid_cast<ColumnVector<T> &>(res_data_col).getData();
ColumnArray::Offset res_offset = 0;
@ -282,13 +282,13 @@ public:
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto arg_type1 = typeid_cast<const DataTypeNumber<UInt32> *>(arguments[1].get());
const auto * arg_type1 = typeid_cast<const DataTypeNumber<UInt32> *>(arguments[1].get());
if (!(arg_type1))
throw Exception(
"Second argument for function " + getName() + " must be UInt32 but it has type " + arguments[1]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto arg_type2 = typeid_cast<const DataTypeNumber<UInt32> *>(arguments[1].get());
const auto * arg_type2 = typeid_cast<const DataTypeNumber<UInt32> *>(arguments[1].get());
if (!(arg_type2))
throw Exception(
"Third argument for function " + getName() + " must be UInt32 but it has type " + arguments[2]->getName() + ".",
@ -299,19 +299,19 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, result, input_rows_count);
return executeIntType<UInt8>(arguments, input_rows_count);
else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, result, input_rows_count);
return executeIntType<UInt16>(arguments, input_rows_count);
else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, result, input_rows_count);
return executeIntType<UInt32>(arguments, input_rows_count);
else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, result, input_rows_count);
return executeIntType<UInt64>(arguments, input_rows_count);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -321,9 +321,7 @@ private:
using ToType = UInt64;
template <typename T>
void executeIntType(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count)
const
ColumnPtr executeIntType(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{
const IColumn * column_ptrs[3];
bool is_column_const[3];
@ -333,7 +331,7 @@ private:
for (size_t i = 0; i < 3; ++i)
{
column_ptrs[i] = columns[arguments[i]].column.get();
column_ptrs[i] = arguments[i].column.get();
is_column_const[i] = isColumnConst(*column_ptrs[i]);
}
if (is_column_const[0])
@ -367,7 +365,7 @@ private:
= *reinterpret_cast<AggregateFunctionGroupBitmapData<T> *>(col_to->getData()[i]);
Impl::apply(bitmap_data_0, range_start, range_end, bitmap_data_2);
}
columns[result].column = std::move(col_to);
return col_to;
}
};
@ -435,19 +433,19 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, result, input_rows_count);
return executeIntType<UInt8>(arguments, input_rows_count);
else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, result, input_rows_count);
return executeIntType<UInt16>(arguments, input_rows_count);
else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, result, input_rows_count);
return executeIntType<UInt32>(arguments, input_rows_count);
else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, result, input_rows_count);
return executeIntType<UInt64>(arguments, input_rows_count);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -457,8 +455,7 @@ private:
using ToType = UInt64;
template <typename T>
void executeIntType(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr executeIntType(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{
const IColumn * column_ptrs[3];
bool is_column_const[3];
@ -468,7 +465,7 @@ private:
for (size_t i = 0; i < 3; ++i)
{
column_ptrs[i] = columns[arguments[i]].column.get();
column_ptrs[i] = arguments[i].column.get();
is_column_const[i] = isColumnConst(*column_ptrs[i]);
}
if (is_column_const[0])
@ -485,7 +482,7 @@ private:
array = typeid_cast<const ColumnArray*>(typeid_cast<const ColumnConst*>(column_ptrs[1])->getDataColumnPtr().get());
else
{
array = typeid_cast<const ColumnArray *>(columns[arguments[1]].column.get());
array = typeid_cast<const ColumnArray *>(arguments[1].column.get());
}
const ColumnArray::Offsets & from_offsets = array->getOffsets();
const ColumnVector<UInt32>::Container & from_container = typeid_cast<const ColumnVector<UInt32> *>(&array->getData())->getData();
@ -493,7 +490,7 @@ private:
if (is_column_const[2])
array = typeid_cast<const ColumnArray*>(typeid_cast<const ColumnConst*>(column_ptrs[2])->getDataColumnPtr().get());
else
array = typeid_cast<const ColumnArray *>(columns[arguments[2]].column.get());
array = typeid_cast<const ColumnArray *>(arguments[2].column.get());
const ColumnArray::Offsets & to_offsets = array->getOffsets();
const ColumnVector<UInt32>::Container & to_container = typeid_cast<const ColumnVector<UInt32> *>(&array->getData())->getData();
@ -538,7 +535,7 @@ private:
bitmap_data_2.rbs.merge(bitmap_data_0.rbs);
bitmap_data_2.rbs.rb_replace(&from_container[from_start], &to_container[to_start], from_end - from_start);
}
columns[result].column = std::move(col_to);
return col_to;
}
};
@ -558,7 +555,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
auto bitmap_type = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
const auto * bitmap_type = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
if (!(bitmap_type && bitmap_type->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
@ -568,27 +565,27 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
auto col_to = ColumnVector<ToType>::create(input_rows_count);
typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt8>(arguments, input_rows_count, vec_to);
else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt16>(arguments, input_rows_count, vec_to);
else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt32>(arguments, input_rows_count, vec_to);
else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt64>(arguments, input_rows_count, vec_to);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
columns[result].column = std::move(col_to);
return col_to;
}
private:
@ -596,10 +593,10 @@ private:
template <typename T>
void executeIntType(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const
ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const
{
const ColumnAggregateFunction * column
= typeid_cast<const ColumnAggregateFunction *>(columns[arguments[0]].column.get());
= typeid_cast<const ColumnAggregateFunction *>(arguments[0].column.get());
for (size_t i = 0; i < input_rows_count; ++i)
{
const AggregateFunctionGroupBitmapData<T> & bitmap_data
@ -722,12 +719,12 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
auto bitmap_type0 = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
const auto * bitmap_type0 = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
if (!(bitmap_type0 && bitmap_type0->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto arg_type1 = typeid_cast<const DataTypeNumber<UInt32> *>(arguments[1].get());
const auto * arg_type1 = typeid_cast<const DataTypeNumber<UInt32> *>(arguments[1].get());
if (!(arg_type1))
throw Exception(
"Second argument for function " + getName() + " must be UInt32 but it has type " + arguments[1]->getName() + ".",
@ -738,33 +735,33 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
auto col_to = ColumnVector<UInt8>::create(input_rows_count);
typename ColumnVector<UInt8>::Container & vec_to = col_to->getData();
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt8>(arguments, input_rows_count, vec_to);
else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt16>(arguments, input_rows_count, vec_to);
else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt32>(arguments, input_rows_count, vec_to);
else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt64>(arguments, input_rows_count, vec_to);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
columns[result].column = std::move(col_to);
return col_to;
}
private:
template <typename T>
void executeIntType(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t input_rows_count, typename ColumnVector<UInt8>::Container & vec_to) const
ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<UInt8>::Container & vec_to) const
{
const IColumn * column_ptrs[2];
bool is_column_const[2];
@ -773,7 +770,7 @@ private:
for (size_t i = 0; i < 2; ++i)
{
column_ptrs[i] = columns[arguments[i]].column.get();
column_ptrs[i] = arguments[i].column.get();
is_column_const[i] = isColumnConst(*column_ptrs[i]);
}
if (is_column_const[0])
@ -812,13 +809,13 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
auto bitmap_type0 = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
const auto * bitmap_type0 = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
if (!(bitmap_type0 && bitmap_type0->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto bitmap_type1 = typeid_cast<const DataTypeAggregateFunction *>(arguments[1].get());
const auto * bitmap_type1 = typeid_cast<const DataTypeAggregateFunction *>(arguments[1].get());
if (!(bitmap_type1 && bitmap_type1->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception(
"Second argument for function " + getName() + " must be a bitmap but it has type " + arguments[1]->getName() + ".",
@ -835,46 +832,46 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
auto col_to = ColumnVector<ToType>::create(input_rows_count);
typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt8>(arguments, input_rows_count, vec_to);
else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt16>(arguments, input_rows_count, vec_to);
else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt32>(arguments, input_rows_count, vec_to);
else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, vec_to);
executeIntType<UInt64>(arguments, input_rows_count, vec_to);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
columns[result].column = std::move(col_to);
return col_to;
}
private:
template <typename T>
void executeIntType(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const
ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const
{
const ColumnAggregateFunction * column_ptrs[2];
bool is_column_const[2];
for (size_t i = 0; i < 2; ++i)
{
if (auto argument_column_const = checkAndGetColumn<ColumnConst>(columns[arguments[i]].column.get()))
if (const auto * argument_column_const = checkAndGetColumn<ColumnConst>(arguments[i].column.get()))
{
column_ptrs[i] = typeid_cast<const ColumnAggregateFunction*>(argument_column_const->getDataColumnPtr().get());
is_column_const[i] = true;
}
else
{
column_ptrs[i] = typeid_cast<const ColumnAggregateFunction*>(columns[arguments[i]].column.get());
column_ptrs[i] = typeid_cast<const ColumnAggregateFunction*>(arguments[i].column.get());
is_column_const[i] = false;
}
}
@ -947,13 +944,13 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
auto bitmap_type0 = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
const auto * bitmap_type0 = typeid_cast<const DataTypeAggregateFunction *>(arguments[0].get());
if (!(bitmap_type0 && bitmap_type0->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
auto bitmap_type1 = typeid_cast<const DataTypeAggregateFunction *>(arguments[1].get());
const auto * bitmap_type1 = typeid_cast<const DataTypeAggregateFunction *>(arguments[1].get());
if (!(bitmap_type1 && bitmap_type1->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception(
"Second argument for function " + getName() + " must be a bitmap but it has type " + arguments[1]->getName() + ".",
@ -970,19 +967,19 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8())
executeBitmapData<UInt8>(columns, arguments, result, input_rows_count);
return executeBitmapData<UInt8>(arguments, input_rows_count);
else if (which.isUInt16())
executeBitmapData<UInt16>(columns, arguments, result, input_rows_count);
return executeBitmapData<UInt16>(arguments, input_rows_count);
else if (which.isUInt32())
executeBitmapData<UInt32>(columns, arguments, result, input_rows_count);
return executeBitmapData<UInt32>(arguments, input_rows_count);
else if (which.isUInt64())
executeBitmapData<UInt64>(columns, arguments, result, input_rows_count);
return executeBitmapData<UInt64>(arguments, input_rows_count);
else
throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -990,20 +987,20 @@ public:
private:
template <typename T>
void executeBitmapData(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr executeBitmapData(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{
const ColumnAggregateFunction * column_ptrs[2];
bool is_column_const[2];
for (size_t i = 0; i < 2; ++i)
{
if (auto argument_column_const = typeid_cast<const ColumnConst *>(columns[arguments[i]].column.get()))
if (const auto * argument_column_const = typeid_cast<const ColumnConst *>(arguments[i].column.get()))
{
column_ptrs[i] = typeid_cast<const ColumnAggregateFunction *>(argument_column_const->getDataColumnPtr().get());
is_column_const[i] = true;
}
else
{
column_ptrs[i] = typeid_cast<const ColumnAggregateFunction *>(columns[arguments[i]].column.get());
column_ptrs[i] = typeid_cast<const ColumnAggregateFunction *>(arguments[i].column.get());
is_column_const[i] = false;
}
}
@ -1026,7 +1023,7 @@ private:
= *reinterpret_cast<const AggregateFunctionGroupBitmapData<T> *>(data_ptr_1);
Impl<T>::apply(bitmap_data_1, bitmap_data_2);
}
columns[result].column = std::move(col_to);
return col_to;
}
};

View File

@ -76,7 +76,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const auto ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
const auto * ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
if (!ptr || ptr->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + arguments[0]->getName() +
" of argument of function " + getName() +
@ -88,12 +88,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const auto & col_type_name = columns[arguments[0]];
const auto & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column;
if (const auto col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
if (const auto * col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
{
if (col_in->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + col_type_name.type->getName() +
@ -112,8 +112,8 @@ public:
vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1));
offsets_res.resize(size);
auto begin = reinterpret_cast<char *>(vec_res.data());
auto pos = begin;
auto * begin = reinterpret_cast<char *>(vec_res.data());
auto * pos = begin;
for (size_t offset = 0, i = 0; offset < vec_in.size(); offset += IPV6_BINARY_LENGTH, ++i)
{
@ -123,10 +123,10 @@ public:
vec_res.resize(pos - begin);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -145,7 +145,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const auto ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
const auto * ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
if (!ptr || ptr->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + arguments[0]->getName() +
" of argument 1 of function " + getName() +
@ -168,17 +168,17 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; }
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
{
const auto & col_type_name = columns[arguments[0]];
const auto & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column;
const auto & col_ipv6_zeroed_tail_bytes_type = columns[arguments[1]];
const auto & col_ipv6_zeroed_tail_bytes_type = arguments[1];
const auto & col_ipv6_zeroed_tail_bytes = col_ipv6_zeroed_tail_bytes_type.column;
const auto & col_ipv4_zeroed_tail_bytes_type = columns[arguments[2]];
const auto & col_ipv4_zeroed_tail_bytes_type = arguments[2];
const auto & col_ipv4_zeroed_tail_bytes = col_ipv4_zeroed_tail_bytes_type.column;
if (const auto col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
if (const auto * col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
{
if (col_in->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + col_type_name.type->getName() +
@ -187,7 +187,7 @@ public:
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
const auto ipv6_zeroed_tail_bytes = checkAndGetColumnConst<ColumnVector<UInt8>>(col_ipv6_zeroed_tail_bytes.get());
const auto * ipv6_zeroed_tail_bytes = checkAndGetColumnConst<ColumnVector<UInt8>>(col_ipv6_zeroed_tail_bytes.get());
if (!ipv6_zeroed_tail_bytes)
throw Exception("Illegal type " + col_ipv6_zeroed_tail_bytes_type.type->getName() +
" of argument 2 of function " + getName(),
@ -199,7 +199,7 @@ public:
" of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
const auto ipv4_zeroed_tail_bytes = checkAndGetColumnConst<ColumnVector<UInt8>>(col_ipv4_zeroed_tail_bytes.get());
const auto * ipv4_zeroed_tail_bytes = checkAndGetColumnConst<ColumnVector<UInt8>>(col_ipv4_zeroed_tail_bytes.get());
if (!ipv4_zeroed_tail_bytes)
throw Exception("Illegal type " + col_ipv4_zeroed_tail_bytes_type.type->getName() +
" of argument 3 of function " + getName(),
@ -221,12 +221,12 @@ public:
vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1));
offsets_res.resize(size);
auto begin = reinterpret_cast<char *>(vec_res.data());
auto pos = begin;
auto * begin = reinterpret_cast<char *>(vec_res.data());
auto * pos = begin;
for (size_t offset = 0, i = 0; offset < vec_in.size(); offset += IPV6_BINARY_LENGTH, ++i)
{
const auto address = &vec_in[offset];
const auto * address = &vec_in[offset];
UInt8 zeroed_tail_bytes_count = isIPv4Mapped(address) ? ipv4_zeroed_tail_bytes_count : ipv6_zeroed_tail_bytes_count;
cutAddress(reinterpret_cast<const unsigned char *>(address), pos, zeroed_tail_bytes_count);
offsets_res[i] = pos - begin;
@ -234,22 +234,22 @@ public:
vec_res.resize(pos - begin);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
private:
bool isIPv4Mapped(const UInt8 * address) const
static bool isIPv4Mapped(const UInt8 * address)
{
return (unalignedLoad<UInt64>(address) == 0) &&
((unalignedLoad<UInt64>(address + 8) & 0x00000000FFFFFFFFull) == 0x00000000FFFF0000ull);
}
void cutAddress(const unsigned char * address, char *& dst, UInt8 zeroed_tail_bytes_count) const
static void cutAddress(const unsigned char * address, char *& dst, UInt8 zeroed_tail_bytes_count)
{
formatIPv6(address, dst, zeroed_tail_bytes_count);
}
@ -277,11 +277,11 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
if (const auto col_in = checkAndGetColumn<ColumnString>(column.get()))
if (const auto * col_in = checkAndGetColumn<ColumnString>(column.get()))
{
auto col_res = ColumnFixedString::create(IPV6_BINARY_LENGTH);
@ -301,10 +301,10 @@ public:
src_offset = offsets_src[i];
}
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -339,9 +339,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
if (const ColumnUInt32 * col = typeid_cast<const ColumnUInt32 *>(column.get()))
{
@ -365,10 +365,10 @@ public:
vec_res.resize(pos - begin);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -407,9 +407,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{
@ -428,10 +428,10 @@ public:
prev_offset = offsets_src[i];
}
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -460,12 +460,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const auto & col_type_name = columns[arguments[0]];
const auto & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column;
if (const auto col_in = typeid_cast<const ColumnUInt32 *>(column.get()))
if (const auto * col_in = typeid_cast<const ColumnUInt32 *>(column.get()))
{
auto col_res = ColumnFixedString::create(IPV6_BINARY_LENGTH);
@ -477,16 +477,16 @@ public:
for (size_t out_offset = 0, i = 0; out_offset < vec_res.size(); out_offset += IPV6_BINARY_LENGTH, ++i)
mapIPv4ToIPv6(vec_in[i], &vec_res[out_offset]);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
private:
void mapIPv4ToIPv6(UInt32 in, UInt8 * buf) const
static void mapIPv4ToIPv6(UInt32 in, UInt8 * buf)
{
unalignedStore<UInt64>(buf, 0);
unalignedStore<UInt64>(buf + 8, 0x00000000FFFF0000ull | (static_cast<UInt64>(ntohl(in)) << 32));
@ -578,9 +578,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
if (const ColumnUInt64 * col = typeid_cast<const ColumnUInt64 *>(column.get()))
{
@ -602,10 +602,10 @@ public:
offsets_res[i] = current_offset;
}
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -688,9 +688,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{
@ -716,10 +716,10 @@ public:
prev_offset = current_offset;
}
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -743,7 +743,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const auto ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
const auto * ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
if (!ptr || ptr->getN() != uuid_bytes_length)
throw Exception("Illegal type " + arguments[0]->getName() +
" of argument of function " + getName() +
@ -755,12 +755,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnWithTypeAndName & col_type_name = columns[arguments[0]];
const ColumnWithTypeAndName & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column;
if (const auto col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
if (const auto * col_in = checkAndGetColumn<ColumnFixedString>(column.get()))
{
if (col_in->getN() != uuid_bytes_length)
throw Exception("Illegal type " + col_type_name.type->getName() +
@ -792,10 +792,10 @@ public:
offsets_res[i] = dst_offset;
}
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -844,7 +844,7 @@ public:
/// String or FixedString(36)
if (!isString(arguments[0]))
{
const auto ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
const auto * ptr = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
if (!ptr || ptr->getN() != uuid_text_length)
throw Exception("Illegal type " + arguments[0]->getName() +
" of argument of function " + getName() +
@ -857,12 +857,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnWithTypeAndName & col_type_name = columns[arguments[0]];
const ColumnWithTypeAndName & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column;
if (const auto col_in = checkAndGetColumn<ColumnString>(column.get()))
if (const auto * col_in = checkAndGetColumn<ColumnString>(column.get()))
{
const auto & vec_in = col_in->getChars();
const auto & offsets_in = col_in->getOffsets();
@ -891,9 +891,9 @@ public:
src_offset += string_size;
}
columns[result].column = std::move(col_res);
return col_res;
}
else if (const auto col_in_fixed = checkAndGetColumn<ColumnFixedString>(column.get()))
else if (const auto * col_in_fixed = checkAndGetColumn<ColumnFixedString>(column.get()))
{
if (col_in_fixed->getN() != uuid_text_length)
throw Exception("Illegal type " + col_type_name.type->getName() +
@ -920,10 +920,10 @@ public:
dst_offset += uuid_bytes_length;
}
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
}
};
@ -1083,7 +1083,7 @@ public:
}
void executeOneString(const UInt8 * pos, const UInt8 * end, char *& out) const
static void executeOneString(const UInt8 * pos, const UInt8 * end, char *& out)
{
while (pos < end)
{
@ -1095,7 +1095,7 @@ public:
++out;
}
bool tryExecuteString(const IColumn * col, ColumnPtr & col_res) const
static bool tryExecuteString(const IColumn * col, ColumnPtr & col_res)
{
const ColumnString * col_str_in = checkAndGetColumn<ColumnString>(col);
@ -1139,7 +1139,7 @@ public:
}
}
bool tryExecuteFixedString(const IColumn * col, ColumnPtr & col_res) const
static bool tryExecuteFixedString(const IColumn * col, ColumnPtr & col_res)
{
const ColumnFixedString * col_fstr_in = checkAndGetColumn<ColumnFixedString>(col);
@ -1187,10 +1187,10 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const IColumn * column = columns[arguments[0]].column.get();
ColumnPtr & res_column = columns[result].column;
const IColumn * column = arguments[0].column.get();
ColumnPtr res_column;
if (tryExecuteUInt<UInt8>(column, res_column) ||
tryExecuteUInt<UInt16>(column, res_column) ||
@ -1203,9 +1203,9 @@ public:
tryExecuteDecimal<Decimal32>(column, res_column) ||
tryExecuteDecimal<Decimal64>(column, res_column) ||
tryExecuteDecimal<Decimal128>(column, res_column))
return;
return res_column;
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -1235,7 +1235,7 @@ public:
return std::make_shared<DataTypeString>();
}
void unhexOne(const char * pos, const char * end, char *& out) const
static void unhexOne(const char * pos, const char * end, char *& out)
{
if ((end - pos) & 1)
{
@ -1255,9 +1255,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{
@ -1290,11 +1290,11 @@ public:
out_vec.resize(pos - begin);
columns[result].column = std::move(col_res);
return col_res;
}
else
{
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -1335,7 +1335,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
auto col_str = ColumnString::create();
ColumnString::Chars & out_vec = col_str->getChars();
@ -1355,7 +1355,7 @@ public:
for (size_t idx = 0; idx < arguments.size(); ++idx)
{
//partial const column
columns_holder[idx] = columns[arguments[idx]].column->convertToFullColumnIfConst();
columns_holder[idx] = arguments[idx].column->convertToFullColumnIfConst();
const IColumn * column = columns_holder[idx].get();
if (!(executeNumber<UInt8>(*column, out_vec, idx, input_rows_count, size_per_row)
@ -1369,12 +1369,12 @@ public:
|| executeNumber<Float32>(*column, out_vec, idx, input_rows_count, size_per_row)
|| executeNumber<Float64>(*column, out_vec, idx, input_rows_count, size_per_row)))
{
throw Exception{"Illegal column " + columns[arguments[idx]].column->getName()
throw Exception{"Illegal column " + arguments[idx].column->getName()
+ " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
}
columns[result].column = std::move(col_str);
return col_str;
}
private:
@ -1461,10 +1461,10 @@ public:
}
}
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
{
const IColumn * in_column = columns[arguments[0]].column.get();
ColumnPtr & out_column = columns[result].column;
const IColumn * in_column = arguments[0].column.get();
ColumnPtr out_column;
if (tryExecute<UInt8>(in_column, out_column) ||
tryExecute<UInt16>(in_column, out_column) ||
@ -1474,9 +1474,9 @@ public:
tryExecute<Int16>(in_column, out_column) ||
tryExecute<Int32>(in_column, out_column) ||
tryExecute<Int64>(in_column, out_column))
return;
return out_column;
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);
}
@ -1506,7 +1506,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
bool tryExecuteString(const IColumn * col, ColumnPtr & col_res) const
static bool tryExecuteString(const IColumn * col, ColumnPtr & col_res)
{
const ColumnString * col_str_in = checkAndGetColumn<ColumnString>(col);
@ -1553,7 +1553,7 @@ public:
}
}
bool tryExecuteFixedString(const IColumn * col, ColumnPtr & col_res) const
static bool tryExecuteFixedString(const IColumn * col, ColumnPtr & col_res)
{
const ColumnFixedString * col_fstr_in = checkAndGetColumn<ColumnFixedString>(col);
@ -1599,15 +1599,15 @@ public:
}
}
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
{
const IColumn * column = columns[arguments[0]].column.get();
ColumnPtr & res_column = columns[result].column;
const IColumn * column = arguments[0].column.get();
ColumnPtr res_column;
if (tryExecuteFixedString(column, res_column) || tryExecuteString(column, res_column))
return;
return res_column;
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -1648,7 +1648,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const auto first_argument = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
const auto * first_argument = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
if (!first_argument || first_argument->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + arguments[0]->getName() +
" of first argument of function " + getName() +
@ -1659,7 +1659,7 @@ public:
if (!isUInt8(second_argument))
throw Exception{"Illegal type " + second_argument->getName()
+ " of second argument of function " + getName()
+ ", expected numeric type.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
+ ", expected UInt8", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
DataTypePtr element = DataTypeFactory::instance().get("IPv6");
return std::make_shared<DataTypeTuple>(DataTypes{element, element});
@ -1668,38 +1668,38 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const auto & col_type_name_ip = columns[arguments[0]];
const auto & col_type_name_ip = arguments[0];
const ColumnPtr & column_ip = col_type_name_ip.column;
const auto col_ip_in = checkAndGetColumn<ColumnFixedString>(column_ip.get());
const auto * col_const_ip_in = checkAndGetColumnConst<ColumnFixedString>(column_ip.get());
const auto * col_ip_in = checkAndGetColumn<ColumnFixedString>(column_ip.get());
if (!col_ip_in)
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
if (!col_ip_in && !col_const_ip_in)
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
if (col_ip_in->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + col_type_name_ip.type->getName() +
" of column " + col_ip_in->getName() +
" argument of function " + getName() +
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if ((col_const_ip_in && col_const_ip_in->getValue<String>().size() != IPV6_BINARY_LENGTH) ||
(col_ip_in && col_ip_in->getN() != IPV6_BINARY_LENGTH))
throw Exception("Illegal type " + col_type_name_ip.type->getName() +
" of column " + column_ip->getName() +
" argument of function " + getName() +
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
const auto & col_type_name_cidr = columns[arguments[1]];
const auto & col_type_name_cidr = arguments[1];
const ColumnPtr & column_cidr = col_type_name_cidr.column;
const auto col_const_cidr_in = checkAndGetColumnConst<ColumnUInt8>(column_cidr.get());
const auto col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
const auto * col_const_cidr_in = checkAndGetColumnConst<ColumnUInt8>(column_cidr.get());
const auto * col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
if (!col_const_cidr_in && !col_cidr_in)
throw Exception("Illegal column " + columns[arguments[1]].column->getName()
throw Exception("Illegal column " + arguments[1].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
const auto & vec_in = col_ip_in->getChars();
auto col_res_lower_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
auto col_res_upper_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
@ -1711,17 +1711,27 @@ public:
static constexpr UInt8 max_cidr_mask = IPV6_BINARY_LENGTH * 8;
const String col_const_ip_str = col_const_ip_in ? col_const_ip_in->getValue<String>() : "";
const UInt8 * col_const_ip_value = col_const_ip_in ? reinterpret_cast<const UInt8 *>(col_const_ip_str.c_str()) : nullptr;
for (size_t offset = 0; offset < input_rows_count; ++offset)
{
const size_t offset_ipv6 = offset * IPV6_BINARY_LENGTH;
const UInt8 * ip = col_const_ip_in
? col_const_ip_value
: &col_ip_in->getChars()[offset_ipv6];
UInt8 cidr = col_const_cidr_in
? col_const_cidr_in->getValue<UInt8>()
: col_cidr_in->getData()[offset];
cidr = std::min(cidr, max_cidr_mask);
applyCIDRMask(&vec_in[offset_ipv6], &vec_res_lower_range[offset_ipv6], &vec_res_upper_range[offset_ipv6], cidr);
applyCIDRMask(ip, &vec_res_lower_range[offset_ipv6], &vec_res_upper_range[offset_ipv6], cidr);
}
columns[result].column = ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
return ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
}
};
@ -1763,7 +1773,7 @@ public:
if (!isUInt8(second_argument))
throw Exception{"Illegal type " + second_argument->getName()
+ " of second argument of function " + getName()
+ ", expected numeric type.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
+ ", expected UInt8", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
DataTypePtr element = DataTypeFactory::instance().get("IPv4");
return std::make_shared<DataTypeTuple>(DataTypes{element, element});
@ -1772,30 +1782,29 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const auto & col_type_name_ip = columns[arguments[0]];
const auto & col_type_name_ip = arguments[0];
const ColumnPtr & column_ip = col_type_name_ip.column;
const auto col_ip_in = checkAndGetColumn<ColumnUInt32>(column_ip.get());
if (!col_ip_in)
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
const auto * col_const_ip_in = checkAndGetColumnConst<ColumnUInt32>(column_ip.get());
const auto * col_ip_in = checkAndGetColumn<ColumnUInt32>(column_ip.get());
if (!col_const_ip_in && !col_ip_in)
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
const auto & col_type_name_cidr = columns[arguments[1]];
const auto & col_type_name_cidr = arguments[1];
const ColumnPtr & column_cidr = col_type_name_cidr.column;
const auto col_const_cidr_in = checkAndGetColumnConst<ColumnUInt8>(column_cidr.get());
const auto col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
const auto * col_const_cidr_in = checkAndGetColumnConst<ColumnUInt8>(column_cidr.get());
const auto * col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
if (!col_const_cidr_in && !col_cidr_in)
throw Exception("Illegal column " + columns[arguments[1]].column->getName()
throw Exception("Illegal column " + arguments[1].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
const auto & vec_in = col_ip_in->getData();
auto col_res_lower_range = ColumnUInt32::create();
auto col_res_upper_range = ColumnUInt32::create();
@ -1807,14 +1816,18 @@ public:
for (size_t i = 0; i < input_rows_count; ++i)
{
UInt32 ip = col_const_ip_in
? col_const_ip_in->getValue<UInt32>()
: col_ip_in->getData()[i];
UInt8 cidr = col_const_cidr_in
? col_const_cidr_in->getValue<UInt8>()
: col_cidr_in->getData()[i];
std::tie(vec_res_lower_range[i], vec_res_upper_range[i]) = applyCIDRMask(vec_in[i], cidr);
std::tie(vec_res_lower_range[i], vec_res_upper_range[i]) = applyCIDRMask(ip, cidr);
}
columns[result].column = ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
return ColumnTuple::create(Columns{std::move(col_res_lower_range), std::move(col_res_upper_range)});
}
};

View File

@ -561,7 +561,7 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionComparison>(context); }
FunctionComparison(const Context & context_)
explicit FunctionComparison(const Context & context_)
: context(context_),
check_decimal_overflow(decimalCheckComparisonOverflow(context))
{}
@ -571,7 +571,7 @@ private:
bool check_decimal_overflow = true;
template <typename T0, typename T1>
bool executeNumRightType(ColumnsWithTypeAndName & columns, size_t result, const ColumnVector<T0> * col_left, const IColumn * col_right_untyped) const
ColumnPtr executeNumRightType(const ColumnVector<T0> * col_left, const IColumn * col_right_untyped) const
{
if (const ColumnVector<T1> * col_right = checkAndGetColumn<ColumnVector<T1>>(col_right_untyped))
{
@ -581,8 +581,7 @@ private:
vec_res.resize(col_left->getData().size());
NumComparisonImpl<T0, T1, Op<T0, T1>>::vectorVector(col_left->getData(), col_right->getData(), vec_res);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
else if (auto col_right_const = checkAndGetColumnConst<ColumnVector<T1>>(col_right_untyped))
{
@ -592,15 +591,14 @@ private:
vec_res.resize(col_left->size());
NumComparisonImpl<T0, T1, Op<T0, T1>>::vectorConstant(col_left->getData(), col_right_const->template getValue<T1>(), vec_res);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
return false;
return nullptr;
}
template <typename T0, typename T1>
bool executeNumConstRightType(ColumnsWithTypeAndName & columns, size_t result, const ColumnConst * col_left, const IColumn * col_right_untyped) const
ColumnPtr executeNumConstRightType(const ColumnConst * col_left, const IColumn * col_right_untyped) const
{
if (const ColumnVector<T1> * col_right = checkAndGetColumn<ColumnVector<T1>>(col_right_untyped))
{
@ -610,41 +608,40 @@ private:
vec_res.resize(col_left->size());
NumComparisonImpl<T0, T1, Op<T0, T1>>::constantVector(col_left->template getValue<T0>(), col_right->getData(), vec_res);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
else if (auto col_right_const = checkAndGetColumnConst<ColumnVector<T1>>(col_right_untyped))
{
UInt8 res = 0;
NumComparisonImpl<T0, T1, Op<T0, T1>>::constantConstant(col_left->template getValue<T0>(), col_right_const->template getValue<T1>(), res);
columns[result].column = DataTypeUInt8().createColumnConst(col_left->size(), toField(res));
return true;
return DataTypeUInt8().createColumnConst(col_left->size(), toField(res));
}
return false;
return nullptr;
}
template <typename T0>
bool executeNumLeftType(ColumnsWithTypeAndName & columns, size_t result, const IColumn * col_left_untyped, const IColumn * col_right_untyped) const
ColumnPtr executeNumLeftType(const IColumn * col_left_untyped, const IColumn * col_right_untyped) const
{
ColumnPtr res = nullptr;
if (const ColumnVector<T0> * col_left = checkAndGetColumn<ColumnVector<T0>>(col_left_untyped))
{
if ( executeNumRightType<T0, UInt8>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, UInt16>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, UInt32>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, UInt64>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, UInt128>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, UInt256>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Int8>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Int16>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Int32>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Int64>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Int128>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Int256>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Float32>(columns, result, col_left, col_right_untyped)
|| executeNumRightType<T0, Float64>(columns, result, col_left, col_right_untyped))
return true;
if ( (res = executeNumRightType<T0, UInt8>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, UInt16>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, UInt32>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, UInt64>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, UInt128>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, UInt256>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Int8>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Int16>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Int32>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Int64>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Int128>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Int256>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Float32>(col_left, col_right_untyped))
|| (res = executeNumRightType<T0, Float64>(col_left, col_right_untyped)))
return res;
else
throw Exception("Illegal column " + col_right_untyped->getName()
+ " of second argument of function " + getName(),
@ -652,34 +649,35 @@ private:
}
else if (auto col_left_const = checkAndGetColumnConst<ColumnVector<T0>>(col_left_untyped))
{
if ( executeNumConstRightType<T0, UInt8>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, UInt16>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, UInt32>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, UInt64>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, UInt128>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, UInt256>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Int8>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Int16>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Int32>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Int64>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Int128>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Int256>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Float32>(columns, result, col_left_const, col_right_untyped)
|| executeNumConstRightType<T0, Float64>(columns, result, col_left_const, col_right_untyped))
return true;
if ( (res = executeNumConstRightType<T0, UInt8>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, UInt16>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, UInt32>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, UInt64>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, UInt128>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, UInt256>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Int8>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Int16>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Int32>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Int64>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Int128>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Int256>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Float32>(col_left_const, col_right_untyped))
|| (res = executeNumConstRightType<T0, Float64>(col_left_const, col_right_untyped)))
return res;
else
throw Exception("Illegal column " + col_right_untyped->getName()
+ " of second argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
return false;
return nullptr;
}
void executeDecimal(ColumnsWithTypeAndName & columns, size_t result, const ColumnWithTypeAndName & col_left, const ColumnWithTypeAndName & col_right) const
ColumnPtr executeDecimal(const ColumnWithTypeAndName & col_left, const ColumnWithTypeAndName & col_right) const
{
TypeIndex left_number = col_left.type->getTypeId();
TypeIndex right_number = col_right.type->getTypeId();
ColumnPtr res;
auto call = [&](const auto & types) -> bool
{
@ -688,18 +686,19 @@ private:
using RightDataType = typename Types::RightType;
if (check_decimal_overflow)
DecimalComparison<LeftDataType, RightDataType, Op, true>(columns, result, col_left, col_right);
return (res = DecimalComparison<LeftDataType, RightDataType, Op, true>::apply(col_left, col_right)) != nullptr;
else
DecimalComparison<LeftDataType, RightDataType, Op, false>(columns, result, col_left, col_right);
return true;
return (res = DecimalComparison<LeftDataType, RightDataType, Op, false>::apply(col_left, col_right)) != nullptr;
};
if (!callOnBasicTypes<true, false, true, true>(left_number, right_number, call))
throw Exception("Wrong call for " + getName() + " with " + col_left.type->getName() + " and " + col_right.type->getName(),
ErrorCodes::LOGICAL_ERROR);
return res;
}
bool executeString(ColumnsWithTypeAndName & columns, size_t result, const IColumn * c0, const IColumn * c1) const
ColumnPtr executeString(const IColumn * c0, const IColumn * c1) const
{
const ColumnString * c0_string = checkAndGetColumn<ColumnString>(c0);
const ColumnString * c1_string = checkAndGetColumn<ColumnString>(c1);
@ -710,7 +709,7 @@ private:
const ColumnConst * c1_const = checkAndGetColumnConstStringOrFixedString(c1);
if (!((c0_string || c0_fixed_string || c0_const) && (c1_string || c1_fixed_string || c1_const)))
return false;
return nullptr;
const ColumnString::Chars * c0_const_chars = nullptr;
const ColumnString::Chars * c1_const_chars = nullptr;
@ -759,12 +758,11 @@ private:
if (c0_const && c1_const)
{
auto res = executeString(columns, result, &c0_const->getDataColumn(), &c1_const->getDataColumn());
auto res = executeString(&c0_const->getDataColumn(), &c1_const->getDataColumn());
if (!res)
return false;
return nullptr;
columns[result].column = ColumnConst::create(columns[result].column, c0_const->size());
return true;
return ColumnConst::create(res, c0_const->size());
}
else
{
@ -818,13 +816,12 @@ private:
+ " of arguments of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
columns[result].column = std::move(c_res);
return true;
return c_res;
}
}
bool executeWithConstString(
ColumnsWithTypeAndName & columns, size_t result, const IColumn * col_left_untyped, const IColumn * col_right_untyped,
ColumnPtr executeWithConstString(
const DataTypePtr & result_type, const IColumn * col_left_untyped, const IColumn * col_right_untyped,
const DataTypePtr & left_type, const DataTypePtr & right_type, size_t input_rows_count) const
{
/// To compare something with const string, we cast constant to appropriate type and compare as usual.
@ -835,7 +832,7 @@ private:
const ColumnConst * right_const = checkAndGetColumnConstStringOrFixedString(col_right_untyped);
if (!left_const && !right_const)
return false;
return nullptr;
const IDataType * type_string = left_const ? left_type.get() : right_type.get();
const DataTypePtr & type_to_compare = !left_const ? left_type : right_type;
@ -846,29 +843,25 @@ private:
/// If not possible to convert, comparison with =, <, >, <=, >= yields to false and comparison with != yields to true.
if (converted.isNull())
{
columns[result].column = DataTypeUInt8().createColumnConst(input_rows_count, IsOperation<Op>::not_equals);
return DataTypeUInt8().createColumnConst(input_rows_count, IsOperation<Op>::not_equals);
}
else
{
auto column_converted = type_to_compare->createColumnConst(input_rows_count, converted);
ColumnsWithTypeAndName tmp_columns_columns
ColumnsWithTypeAndName tmp_columns
{
{ left_const ? column_converted : col_left_untyped->getPtr(), type_to_compare, "" },
{ !left_const ? column_converted : col_right_untyped->getPtr(), type_to_compare, "" },
columns[result]
};
executeImpl(tmp_columns_columns, {0, 1}, 2, input_rows_count);
columns[result].column = std::move(tmp_columns_columns[2].column);
return executeImpl(tmp_columns, result_type, input_rows_count);
}
return true;
}
void executeTuple(ColumnsWithTypeAndName & columns, size_t result, const ColumnWithTypeAndName & c0, const ColumnWithTypeAndName & c1,
size_t input_rows_count) const
ColumnPtr executeTuple(
const DataTypePtr & result_type, const ColumnWithTypeAndName & c0, const ColumnWithTypeAndName & c1,
size_t input_rows_count) const
{
/** We will lexicographically compare the tuples. This is done as follows:
* x == y : x1 == y1 && x2 == y2 ...
@ -892,12 +885,8 @@ private:
if (tuple_size != typeid_cast<const DataTypeTuple &>(*c1.type).getElements().size())
throw Exception("Cannot compare tuples of different sizes.", ErrorCodes::BAD_ARGUMENTS);
auto & res = columns[result];
if (res.type->onlyNull())
{
res.column = res.type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
if (result_type->onlyNull())
return result_type->createColumnConstWithDefaultValue(input_rows_count);
ColumnsWithTypeAndName x(tuple_size);
ColumnsWithTypeAndName y(tuple_size);
@ -927,18 +916,16 @@ private:
y[i].column = y_columns[i];
}
executeTupleImpl(columns, result, x, y, tuple_size, input_rows_count);
return executeTupleImpl(x, y, tuple_size, input_rows_count);
}
void executeTupleImpl(ColumnsWithTypeAndName & columns, size_t result, const ColumnsWithTypeAndName & x,
ColumnPtr executeTupleImpl(const ColumnsWithTypeAndName & x,
const ColumnsWithTypeAndName & y, size_t tuple_size,
size_t input_rows_count) const;
void executeTupleEqualityImpl(
ColumnPtr executeTupleEqualityImpl(
std::shared_ptr<IFunctionOverloadResolver> func_compare,
std::shared_ptr<IFunctionOverloadResolver> func_convolution,
ColumnsWithTypeAndName & columns,
size_t result,
const ColumnsWithTypeAndName & x,
const ColumnsWithTypeAndName & y,
size_t tuple_size,
@ -947,84 +934,70 @@ private:
if (0 == tuple_size)
throw Exception("Comparison of zero-sized tuples is not implemented.", ErrorCodes::NOT_IMPLEMENTED);
ColumnsWithTypeAndName convolution_types(tuple_size);
ColumnsWithTypeAndName convolution_columns(tuple_size);
ColumnsWithTypeAndName tmp_columns(2);
ColumnsWithTypeAndName tmp_columns;
for (size_t i = 0; i < tuple_size; ++i)
{
tmp_columns.emplace_back(x[i]);
tmp_columns.emplace_back(y[i]);
tmp_columns[0] = x[i];
tmp_columns[1] = y[i];
auto impl = func_compare->build({x[i], y[i]});
convolution_types[i].type = impl->getReturnType();
auto impl = func_compare->build(tmp_columns);
convolution_columns[i].type = impl->getResultType();
/// Comparison of the elements.
tmp_columns.emplace_back(ColumnWithTypeAndName{ nullptr, impl->getReturnType(), "" });
impl->execute(tmp_columns, {i * 3, i * 3 + 1}, i * 3 + 2, input_rows_count);
convolution_columns[i].column = impl->execute(tmp_columns, impl->getResultType(), input_rows_count);
}
if (tuple_size == 1)
{
/// Do not call AND for single-element tuple.
columns[result].column = tmp_columns[2].column;
return;
return convolution_columns[0].column;
}
/// Logical convolution.
ColumnNumbers convolution_args(tuple_size);
for (size_t i = 0; i < tuple_size; ++i)
convolution_args[i] = i * 3 + 2;
auto impl = func_convolution->build(convolution_types);
tmp_columns.emplace_back(ColumnWithTypeAndName{ nullptr, impl->getReturnType(), "" });
impl->execute(tmp_columns, convolution_args, tuple_size * 3, input_rows_count);
columns[result].column = tmp_columns[tuple_size * 3].column;
auto impl = func_convolution->build(convolution_columns);
return impl->execute(convolution_columns, impl->getResultType(), input_rows_count);
}
void executeTupleLessGreaterImpl(
ColumnPtr executeTupleLessGreaterImpl(
std::shared_ptr<IFunctionOverloadResolver> func_compare_head,
std::shared_ptr<IFunctionOverloadResolver> func_compare_tail,
std::shared_ptr<IFunctionOverloadResolver> func_and,
std::shared_ptr<IFunctionOverloadResolver> func_or,
std::shared_ptr<IFunctionOverloadResolver> func_equals,
ColumnsWithTypeAndName & columns,
size_t result,
const ColumnsWithTypeAndName & x,
const ColumnsWithTypeAndName & y,
size_t tuple_size,
size_t input_rows_count) const
{
ColumnsWithTypeAndName tmp_columns;
ColumnsWithTypeAndName less_columns(tuple_size);
ColumnsWithTypeAndName equal_columns(tuple_size - 1);
ColumnsWithTypeAndName tmp_columns(2);
/// Pairwise comparison of the inequality of all elements; on the equality of all elements except the last.
/// (x[i], y[i], x[i] < y[i], x[i] == y[i])
for (size_t i = 0; i < tuple_size; ++i)
{
tmp_columns.emplace_back(x[i]);
tmp_columns.emplace_back(y[i]);
tmp_columns.emplace_back(ColumnWithTypeAndName()); // pos == i * 4 + 2
tmp_columns[0] = x[i];
tmp_columns[1] = y[i];
if (i + 1 != tuple_size)
{
auto impl_head = func_compare_head->build({x[i], y[i]});
tmp_columns[i * 4 + 2].type = impl_head->getReturnType();
impl_head->execute(tmp_columns, {i * 4, i * 4 + 1}, i * 4 + 2, input_rows_count);
auto impl_head = func_compare_head->build(tmp_columns);
less_columns[i].type = impl_head->getResultType();
less_columns[i].column = impl_head->execute(tmp_columns, less_columns[i].type, input_rows_count);
tmp_columns.emplace_back(ColumnWithTypeAndName()); // i * 4 + 3
auto impl_equals = func_equals->build({x[i], y[i]});
tmp_columns[i * 4 + 3].type = impl_equals->getReturnType();
impl_equals->execute(tmp_columns, {i * 4, i * 4 + 1}, i * 4 + 3, input_rows_count);
auto impl_equals = func_equals->build(tmp_columns);
equal_columns[i].type = impl_equals->getResultType();
equal_columns[i].column = impl_equals->execute(tmp_columns, equal_columns[i].type, input_rows_count);
}
else
{
auto impl_tail = func_compare_tail->build({x[i], y[i]});
tmp_columns[i * 4 + 2].type = impl_tail->getReturnType();
impl_tail->execute(tmp_columns, {i * 4, i * 4 + 1}, i * 4 + 2, input_rows_count);
auto impl_tail = func_compare_tail->build(tmp_columns);
less_columns[i].type = impl_tail->getResultType();
less_columns[i].column = impl_tail->execute(tmp_columns, less_columns[i].type, input_rows_count);
}
}
@ -1035,38 +1008,28 @@ private:
/// for (int i = tuple_size - 2; i >= 0; --i)
/// res = (res && `x == y`[i]) || `x < y`[i];
size_t i = tuple_size - 1;
tmp_columns[0] = less_columns[i];
while (i > 0)
{
--i;
size_t and_lhs_pos = tmp_columns.size() - 1; // res
size_t and_rhs_pos = i * 4 + 3; // `x == y`[i]
tmp_columns.emplace_back(ColumnWithTypeAndName());
tmp_columns[1] = equal_columns[i];
auto func_and_adaptor = func_and->build(tmp_columns);
ColumnsWithTypeAndName and_args = {{ nullptr, tmp_columns[and_lhs_pos].type, "" },
{ nullptr, tmp_columns[and_rhs_pos].type, "" }};
tmp_columns[0].column = func_and_adaptor->execute(tmp_columns, func_and_adaptor->getResultType(), input_rows_count);
tmp_columns[0].type = func_and_adaptor->getResultType();
auto func_and_adaptor = func_and->build(and_args);
tmp_columns[tmp_columns.size() - 1].type = func_and_adaptor->getReturnType();
func_and_adaptor->execute(tmp_columns, {and_lhs_pos, and_rhs_pos}, tmp_columns.size() - 1, input_rows_count);
size_t or_lhs_pos = tmp_columns.size() - 1; // (res && `x == y`[i])
size_t or_rhs_pos = i * 4 + 2; // `x < y`[i]
tmp_columns.emplace_back(ColumnWithTypeAndName());
ColumnsWithTypeAndName or_args = {{ nullptr, tmp_columns[or_lhs_pos].type, "" },
{ nullptr, tmp_columns[or_rhs_pos].type, "" }};
auto func_or_adaptor = func_or->build(or_args);
tmp_columns[tmp_columns.size() - 1].type = func_or_adaptor->getReturnType();
func_or_adaptor->execute(tmp_columns, {or_lhs_pos, or_rhs_pos}, tmp_columns.size() - 1, input_rows_count);
tmp_columns[1] = less_columns[i];
auto func_or_adaptor = func_or->build(tmp_columns);
tmp_columns[0].column = func_or_adaptor->execute(tmp_columns, func_or_adaptor->getResultType(), input_rows_count);
tmp_columns[tmp_columns.size() - 1].type = func_or_adaptor->getResultType();
}
columns[result].column = tmp_columns[tmp_columns.size() - 1].column;
return tmp_columns[0].column;
}
void executeGenericIdenticalTypes(ColumnsWithTypeAndName & columns, size_t result, const IColumn * c0, const IColumn * c1) const
ColumnPtr executeGenericIdenticalTypes(const IColumn * c0, const IColumn * c1) const
{
bool c0_const = isColumnConst(*c0);
bool c1_const = isColumnConst(*c1);
@ -1075,7 +1038,7 @@ private:
{
UInt8 res = 0;
GenericComparisonImpl<Op<int, int>>::constantConstant(*c0, *c1, res);
columns[result].column = DataTypeUInt8().createColumnConst(c0->size(), toField(res));
return DataTypeUInt8().createColumnConst(c0->size(), toField(res));
}
else
{
@ -1090,18 +1053,18 @@ private:
else
GenericComparisonImpl<Op<int, int>>::vectorVector(*c0, *c1, vec_res);
columns[result].column = std::move(c_res);
return c_res;
}
}
void executeGeneric(ColumnsWithTypeAndName & columns, size_t result, const ColumnWithTypeAndName & c0, const ColumnWithTypeAndName & c1) const
ColumnPtr executeGeneric(const ColumnWithTypeAndName & c0, const ColumnWithTypeAndName & c1) const
{
DataTypePtr common_type = getLeastSupertype({c0.type, c1.type});
ColumnPtr c0_converted = castColumn(c0, common_type);
ColumnPtr c1_converted = castColumn(c1, common_type);
executeGenericIdenticalTypes(columns, result, c0_converted.get(), c1_converted.get());
return executeGenericIdenticalTypes(c0_converted.get(), c1_converted.get());
}
public:
@ -1157,7 +1120,7 @@ public:
{
ColumnsWithTypeAndName args = {{nullptr, left_tuple->getElements()[i], ""},
{nullptr, right_tuple->getElements()[i], ""}};
auto element_type = adaptor.build(args)->getReturnType();
auto element_type = adaptor.build(args)->getResultType();
has_nullable = has_nullable || element_type->isNullable();
has_null = has_null || element_type->onlyNull();
}
@ -1173,10 +1136,10 @@ 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 & result_type, size_t input_rows_count) const override
{
const auto & col_with_type_and_name_left = columns[arguments[0]];
const auto & col_with_type_and_name_right = columns[arguments[1]];
const auto & col_with_type_and_name_left = arguments[0];
const auto & col_with_type_and_name_right = arguments[1];
const IColumn * col_left_untyped = col_with_type_and_name_left.column.get();
const IColumn * col_right_untyped = col_with_type_and_name_right.column.get();
@ -1194,13 +1157,11 @@ public:
|| IsOperation<Op>::less_or_equals
|| IsOperation<Op>::greater_or_equals)
{
columns[result].column = DataTypeUInt8().createColumnConst(input_rows_count, 1u);
return;
return DataTypeUInt8().createColumnConst(input_rows_count, 1u);
}
else
{
columns[result].column = DataTypeUInt8().createColumnConst(input_rows_count, 0u);
return;
return DataTypeUInt8().createColumnConst(input_rows_count, 0u);
}
}
@ -1216,39 +1177,44 @@ public:
bool date_and_datetime = (which_left.idx != which_right.idx) &&
which_left.isDateOrDateTime() && which_right.isDateOrDateTime();
ColumnPtr res;
if (left_is_num && right_is_num && !date_and_datetime)
{
if (!(executeNumLeftType<UInt8>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<UInt16>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<UInt32>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<UInt64>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<UInt128>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<UInt256>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Int8>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Int16>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Int32>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Int64>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Int128>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Int256>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Float32>(columns, result, col_left_untyped, col_right_untyped)
|| executeNumLeftType<Float64>(columns, result, col_left_untyped, col_right_untyped)))
if (!((res = executeNumLeftType<UInt8>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<UInt16>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<UInt32>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<UInt64>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<UInt128>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<UInt256>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Int8>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Int16>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Int32>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Int64>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Int128>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Int256>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Float32>(col_left_untyped, col_right_untyped))
|| (res = executeNumLeftType<Float64>(col_left_untyped, col_right_untyped))))
throw Exception("Illegal column " + col_left_untyped->getName()
+ " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
return res;
}
else if (checkAndGetDataType<DataTypeTuple>(left_type.get())
&& checkAndGetDataType<DataTypeTuple>(right_type.get()))
{
executeTuple(columns, result, col_with_type_and_name_left, col_with_type_and_name_right, input_rows_count);
return executeTuple(result_type, col_with_type_and_name_left, col_with_type_and_name_right, input_rows_count);
}
else if (left_is_string && right_is_string && executeString(columns, result, col_left_untyped, col_right_untyped))
else if (left_is_string && right_is_string && (res = executeString(col_left_untyped, col_right_untyped)))
{
return res;
}
else if (executeWithConstString(
columns, result, col_left_untyped, col_right_untyped,
else if ((res = executeWithConstString(
result_type, col_left_untyped, col_right_untyped,
left_type, right_type,
input_rows_count))
input_rows_count)))
{
return res;
}
else if (isColumnedAsDecimal(left_type) || isColumnedAsDecimal(right_type))
{
@ -1257,15 +1223,15 @@ public:
throw Exception("No operation " + getName() + " between " + left_type->getName() + " and " + right_type->getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
executeDecimal(columns, result, col_with_type_and_name_left, col_with_type_and_name_right);
return executeDecimal(col_with_type_and_name_left, col_with_type_and_name_right);
}
else if (left_type->equals(*right_type))
{
executeGenericIdenticalTypes(columns, result, col_left_untyped, col_right_untyped);
return executeGenericIdenticalTypes(col_left_untyped, col_right_untyped);
}
else
{
executeGeneric(columns, result, col_with_type_and_name_left, col_with_type_and_name_right);
return executeGeneric(col_with_type_and_name_left, col_with_type_and_name_right);
}
}

View File

@ -65,10 +65,10 @@ public:
return {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 (isColumnConst(*columns[arguments[1]].column))
executeConstBuckets(columns, arguments, result);
if (isColumnConst(*arguments[1].column))
return executeConstBuckets(arguments);
else
throw Exception(
"The second argument of function " + getName() + " (number of buckets) must be constant", ErrorCodes::BAD_ARGUMENTS);
@ -93,9 +93,9 @@ private:
return static_cast<BucketsType>(buckets);
}
void executeConstBuckets(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeConstBuckets(ColumnsWithTypeAndName & arguments) const
{
Field buckets_field = (*columns[arguments[1]].column)[0];
Field buckets_field = (*arguments[1].column)[0];
BucketsType num_buckets;
if (buckets_field.getType() == Field::Types::Int64)
@ -106,8 +106,8 @@ private:
throw Exception("Illegal type " + String(buckets_field.getTypeName()) + " of the second argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
const auto & hash_col = columns[arguments[0]].column;
const IDataType * hash_type = columns[arguments[0]].type.get();
const auto & hash_col = arguments[0].column;
const IDataType * hash_type = arguments[0].type.get();
auto res_col = ColumnVector<ResultType>::create();
WhichDataType which(hash_type);
@ -132,7 +132,7 @@ private:
throw Exception("Illegal type " + hash_type->getName() + " of the first argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
columns[result].column = std::move(res_col);
return res_col;
}
template <typename CurrentHashType>

File diff suppressed because it is too large Load Diff

View File

@ -183,17 +183,17 @@ public:
bool isDeterministic() const override { return false; }
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
{
/// The dictionary key that defines the "point of view".
std::string dict_key;
if (arguments.size() == 2)
{
const ColumnConst * key_col = checkAndGetColumnConst<ColumnString>(columns[arguments[1]].column.get());
const ColumnConst * key_col = checkAndGetColumnConst<ColumnString>(arguments[1].column.get());
if (!key_col)
throw Exception("Illegal column " + columns[arguments[1]].column->getName()
throw Exception("Illegal column " + arguments[1].column->getName()
+ " of second ('point of view') argument of function " + name
+ ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN);
@ -203,7 +203,7 @@ public:
const typename DictGetter::Dst & dict = DictGetter::get(*owned_dict, dict_key);
if (const ColumnVector<T> * col_from = checkAndGetColumn<ColumnVector<T>>(columns[arguments[0]].column.get()))
if (const ColumnVector<T> * col_from = checkAndGetColumn<ColumnVector<T>>(arguments[0].column.get()))
{
auto col_to = ColumnVector<T>::create();
@ -215,10 +215,10 @@ public:
for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(vec_from[i], dict);
columns[result].column = std::move(col_to);
return col_to;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + name,
ErrorCodes::ILLEGAL_COLUMN);
}
@ -279,17 +279,17 @@ public:
bool isDeterministic() const override { return false; }
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
{
/// The dictionary key that defines the "point of view".
std::string dict_key;
if (arguments.size() == 3)
{
const ColumnConst * key_col = checkAndGetColumnConst<ColumnString>(columns[arguments[2]].column.get());
const ColumnConst * key_col = checkAndGetColumnConst<ColumnString>(arguments[2].column.get());
if (!key_col)
throw Exception("Illegal column " + columns[arguments[2]].column->getName()
throw Exception("Illegal column " + arguments[2].column->getName()
+ " of third ('point of view') argument of function " + name
+ ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN);
@ -299,10 +299,10 @@ public:
const typename DictGetter::Dst & dict = DictGetter::get(*owned_dict, dict_key);
const ColumnVector<T> * col_vec1 = checkAndGetColumn<ColumnVector<T>>(columns[arguments[0]].column.get());
const ColumnVector<T> * col_vec2 = checkAndGetColumn<ColumnVector<T>>(columns[arguments[1]].column.get());
const ColumnConst * col_const1 = checkAndGetColumnConst<ColumnVector<T>>(columns[arguments[0]].column.get());
const ColumnConst * col_const2 = checkAndGetColumnConst<ColumnVector<T>>(columns[arguments[1]].column.get());
const ColumnVector<T> * col_vec1 = checkAndGetColumn<ColumnVector<T>>(arguments[0].column.get());
const ColumnVector<T> * col_vec2 = checkAndGetColumn<ColumnVector<T>>(arguments[1].column.get());
const ColumnConst * col_const1 = checkAndGetColumnConst<ColumnVector<T>>(arguments[0].column.get());
const ColumnConst * col_const2 = checkAndGetColumnConst<ColumnVector<T>>(arguments[1].column.get());
if (col_vec1 && col_vec2)
{
@ -317,7 +317,7 @@ public:
for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(vec_from1[i], vec_from2[i], dict);
columns[result].column = std::move(col_to);
return col_to;
}
else if (col_vec1 && col_const2)
{
@ -332,7 +332,7 @@ public:
for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(vec_from1[i], const_from2, dict);
columns[result].column = std::move(col_to);
return col_to;
}
else if (col_const1 && col_vec2)
{
@ -347,16 +347,16 @@ public:
for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(const_from1, vec_from2[i], dict);
columns[result].column = std::move(col_to);
return col_to;
}
else if (col_const1 && col_const2)
{
columns[result].column = DataTypeUInt8().createColumnConst(col_const1->size(),
return DataTypeUInt8().createColumnConst(col_const1->size(),
toField(Transform::apply(col_const1->template getValue<T>(), col_const2->template getValue<T>(), dict)));
}
else
throw Exception("Illegal columns " + columns[arguments[0]].column->getName()
+ " and " + columns[arguments[1]].column->getName()
throw Exception("Illegal columns " + arguments[0].column->getName()
+ " and " + arguments[1].column->getName()
+ " of arguments of function " + name,
ErrorCodes::ILLEGAL_COLUMN);
}
@ -415,17 +415,17 @@ public:
bool isDeterministic() const override { return false; }
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
{
/// The dictionary key that defines the "point of view".
std::string dict_key;
if (arguments.size() == 2)
{
const ColumnConst * key_col = checkAndGetColumnConst<ColumnString>(columns[arguments[1]].column.get());
const ColumnConst * key_col = checkAndGetColumnConst<ColumnString>(arguments[1].column.get());
if (!key_col)
throw Exception("Illegal column " + columns[arguments[1]].column->getName()
throw Exception("Illegal column " + arguments[1].column->getName()
+ " of second ('point of view') argument of function " + name
+ ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN);
@ -435,7 +435,7 @@ public:
const typename DictGetter::Dst & dict = DictGetter::get(*owned_dict, dict_key);
if (const ColumnVector<T> * col_from = checkAndGetColumn<ColumnVector<T>>(columns[arguments[0]].column.get()))
if (const ColumnVector<T> * col_from = checkAndGetColumn<ColumnVector<T>>(arguments[0].column.get()))
{
auto col_values = ColumnVector<T>::create();
auto col_offsets = ColumnArray::ColumnOffsets::create();
@ -459,10 +459,10 @@ public:
res_offsets[i] = res_values.size();
}
columns[result].column = ColumnArray::create(std::move(col_values), std::move(col_offsets));
return ColumnArray::create(std::move(col_values), std::move(col_offsets));
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + name,
ErrorCodes::ILLEGAL_COLUMN);
}
@ -620,24 +620,24 @@ public:
bool isDeterministic() const override { return false; }
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
{
RegionsNames::Language language = RegionsNames::Language::ru;
/// If the result language is specified
if (arguments.size() == 2)
{
if (const ColumnConst * col_language = checkAndGetColumnConst<ColumnString>(columns[arguments[1]].column.get()))
if (const ColumnConst * col_language = checkAndGetColumnConst<ColumnString>(arguments[1].column.get()))
language = RegionsNames::getLanguageEnum(col_language->getValue<String>());
else
throw Exception("Illegal column " + columns[arguments[1]].column->getName()
throw Exception("Illegal column " + arguments[1].column->getName()
+ " of the second argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
const RegionsNames & dict = *owned_dict;
if (const ColumnUInt32 * col_from = typeid_cast<const ColumnUInt32 *>(columns[arguments[0]].column.get()))
if (const ColumnUInt32 * col_from = typeid_cast<const ColumnUInt32 *>(arguments[0].column.get()))
{
auto col_to = ColumnString::create();
@ -649,10 +649,10 @@ public:
col_to->insertDataWithTerminatingZero(name_ref.data, name_ref.size + 1);
}
columns[result].column = std::move(col_to);
return col_to;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of the first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}

File diff suppressed because it is too large Load Diff

View File

@ -69,9 +69,9 @@ DataTypePtr FunctionModelEvaluate::getReturnTypeImpl(const ColumnsWithTypeAndNam
return type;
}
void FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const
ColumnPtr FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{
const auto * name_col = checkAndGetColumnConst<ColumnString>(columns[arguments[0]].column.get());
const auto * name_col = checkAndGetColumnConst<ColumnString>(arguments[0].column.get());
if (!name_col)
throw Exception("First argument of function " + getName() + " must be a constant string",
ErrorCodes::ILLEGAL_COLUMN);
@ -85,7 +85,7 @@ void FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & columns, const
column_ptrs.reserve(arguments.size());
for (auto arg : ext::range(1, arguments.size()))
{
auto & column = columns[arguments[arg]].column;
auto & column = arguments[arg].column;
column_ptrs.push_back(column.get());
if (auto full_column = column->convertToFullColumnIfConst())
{
@ -130,7 +130,7 @@ void FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & columns, const
res = ColumnNullable::create(res, null_map);
}
columns[result].column = res;
return res;
}
void registerFunctionsExternalModels(FunctionFactory & factory)

View File

@ -32,7 +32,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:
const ExternalModelsLoader & models_loader;

View File

@ -543,9 +543,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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 (const ColumnString * col_from = checkAndGetColumn<ColumnString>(columns[arguments[0]].column.get()))
if (const ColumnString * col_from = checkAndGetColumn<ColumnString>(arguments[0].column.get()))
{
auto col_to = ColumnFixedString::create(Impl::length);
@ -566,10 +566,10 @@ public:
current_offset = offsets[i];
}
columns[result].column = std::move(col_to);
return col_to;
}
else if (
const ColumnFixedString * col_from_fix = checkAndGetColumn<ColumnFixedString>(columns[arguments[0]].column.get()))
const ColumnFixedString * col_from_fix = checkAndGetColumn<ColumnFixedString>(arguments[0].column.get()))
{
auto col_to = ColumnFixedString::create(Impl::length);
const typename ColumnFixedString::Chars & data = col_from_fix->getChars();
@ -582,10 +582,10 @@ public:
Impl::apply(
reinterpret_cast<const char *>(&data[i * length]), length, reinterpret_cast<uint8_t *>(&chars_to[i * Impl::length]));
}
columns[result].column = std::move(col_to);
return col_to;
}
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);
}
@ -604,11 +604,11 @@ private:
using ToType = typename Impl::ReturnType;
template <typename FromType>
void executeType(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result) const
ColumnPtr executeType(ColumnsWithTypeAndName & arguments) const
{
using ColVecType = std::conditional_t<IsDecimalNumber<FromType>, ColumnDecimal<FromType>, ColumnVector<FromType>>;
if (const ColVecType * col_from = checkAndGetColumn<ColVecType>(columns[arguments[0]].column.get()))
if (const ColVecType * col_from = checkAndGetColumn<ColVecType>(arguments[0].column.get()))
{
auto col_to = ColumnVector<ToType>::create();
@ -620,10 +620,10 @@ private:
for (size_t i = 0; i < size; ++i)
vec_to[i] = Impl::apply(vec_from[i]);
columns[result].column = std::move(col_to);
return col_to;
}
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + Name::name,
ErrorCodes::ILLEGAL_COLUMN);
}
@ -647,25 +647,37 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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
{
const IDataType * from_type = columns[arguments[0]].type.get();
const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type);
if (which.isUInt8()) executeType<UInt8>(columns, arguments, result);
else if (which.isUInt16()) executeType<UInt16>(columns, arguments, result);
else if (which.isUInt32()) executeType<UInt32>(columns, arguments, result);
else if (which.isUInt64()) executeType<UInt64>(columns, arguments, result);
else if (which.isInt8()) executeType<Int8>(columns, arguments, result);
else if (which.isInt16()) executeType<Int16>(columns, arguments, result);
else if (which.isInt32()) executeType<Int32>(columns, arguments, result);
else if (which.isInt64()) executeType<Int64>(columns, arguments, result);
else if (which.isDate()) executeType<UInt16>(columns, arguments, result);
else if (which.isDateTime()) executeType<UInt32>(columns, arguments, result);
else if (which.isDecimal32()) executeType<Decimal32>(columns, arguments, result);
else if (which.isDecimal64()) executeType<Decimal64>(columns, arguments, result);
if (which.isUInt8())
return executeType<UInt8>(arguments);
else if (which.isUInt16())
return executeType<UInt16>(arguments);
else if (which.isUInt32())
return executeType<UInt32>(arguments);
else if (which.isUInt64())
return executeType<UInt64>(arguments);
else if (which.isInt8())
return executeType<Int8>(arguments);
else if (which.isInt16())
return executeType<Int16>(arguments);
else if (which.isInt32())
return executeType<Int32>(arguments);
else if (which.isInt64())
return executeType<Int64>(arguments);
else if (which.isDate())
return executeType<UInt16>(arguments);
else if (which.isDateTime())
return executeType<UInt32>(arguments);
else if (which.isDecimal32())
return executeType<Decimal32>(arguments);
else if (which.isDecimal64())
return executeType<Decimal64>(arguments);
else
throw Exception("Illegal type " + columns[arguments[0]].type->getName() + " of argument of function " + getName(),
throw Exception("Illegal type " + arguments[0].type->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
};
@ -689,9 +701,9 @@ public:
#endif
}
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
{
selector.selectAndExecute(columns, arguments, result, input_rows_count);
return selector.selectAndExecute(arguments, result_type, input_rows_count);
}
static FunctionPtr create(const Context & context)
@ -886,7 +898,7 @@ private:
}
else if (const ColumnConst * col_from_const = checkAndGetColumnConstStringOrFixedString(column))
{
String value = col_from_const->getValue<String>().data();
String value = col_from_const->getValue<String>();
const ToType hash = Impl::apply(value.data(), value.size());
const size_t size = vec_to.size();
@ -1041,7 +1053,7 @@ public:
return std::make_shared<DataTypeNumber<ToType>>();
}
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;
auto col_to = ColumnVector<ToType>::create(rows);
@ -1057,13 +1069,10 @@ public:
/// The function supports arbitrary number of arguments of arbitrary types.
bool is_first_argument = true;
for (size_t i = 0; i < arguments.size(); ++i)
{
const ColumnWithTypeAndName & col = columns[arguments[i]];
for (const auto & col : arguments)
executeForArgument(col.type.get(), col.column.get(), vec_to, is_first_argument);
}
columns[result].column = std::move(col_to);
return col_to;
}
};
@ -1086,9 +1095,9 @@ public:
#endif
}
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
{
selector.selectAndExecute(columns, arguments, result, input_rows_count);
return selector.selectAndExecute(arguments, result_type, input_rows_count);
}
static FunctionPtr create(const Context & context)
@ -1118,7 +1127,7 @@ struct URLHierarchyHashImpl
{
static size_t findLevelLength(const UInt64 level, const char * begin, const char * end)
{
auto pos = begin;
const auto * pos = begin;
/// Let's parse everything that goes before the path
@ -1192,7 +1201,7 @@ public:
throw Exception{"Number of arguments for function " + getName() + " doesn't match: passed " +
toString(arg_count) + ", should be 1 or 2.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
const auto first_arg = arguments.front().get();
const auto * first_arg = arguments.front().get();
if (!WhichDataType(first_arg).isString())
throw Exception{"Illegal type " + first_arg->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
@ -1209,24 +1218,24 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {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
{
const auto arg_count = arguments.size();
if (arg_count == 1)
executeSingleArg(columns, arguments, result);
return executeSingleArg(arguments);
else if (arg_count == 2)
executeTwoArgs(columns, arguments, result);
return executeTwoArgs(arguments);
else
throw Exception{"got into IFunction::execute with unexpected number of arguments", ErrorCodes::LOGICAL_ERROR};
}
private:
void executeSingleArg(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, const size_t result) const
ColumnPtr executeSingleArg(ColumnsWithTypeAndName & arguments) const
{
const auto col_untyped = columns[arguments.front()].column.get();
const auto * col_untyped = arguments.front().column.get();
if (const auto col_from = checkAndGetColumn<ColumnString>(col_untyped))
if (const auto * col_from = checkAndGetColumn<ColumnString>(col_untyped))
{
const auto size = col_from->size();
auto col_to = ColumnUInt64::create(size);
@ -1245,23 +1254,23 @@ private:
current_offset = offsets[i];
}
columns[result].column = std::move(col_to);
return col_to;
}
else
throw Exception{"Illegal column " + columns[arguments[0]].column->getName() +
throw Exception{"Illegal column " + arguments[0].column->getName() +
" of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
void executeTwoArgs(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, const size_t result) const
ColumnPtr executeTwoArgs(ColumnsWithTypeAndName & arguments) const
{
const auto level_col = columns[arguments.back()].column.get();
const auto * level_col = arguments.back().column.get();
if (!isColumnConst(*level_col))
throw Exception{"Second argument of function " + getName() + " must be an integral constant", ErrorCodes::ILLEGAL_COLUMN};
const auto level = level_col->get64(0);
const auto col_untyped = columns[arguments.front()].column.get();
if (const auto col_from = checkAndGetColumn<ColumnString>(col_untyped))
const auto * col_untyped = arguments.front().column.get();
if (const auto * col_from = checkAndGetColumn<ColumnString>(col_untyped))
{
const auto size = col_from->size();
auto col_to = ColumnUInt64::create(size);
@ -1281,10 +1290,10 @@ private:
current_offset = offsets[i];
}
columns[result].column = std::move(col_to);
return col_to;
}
else
throw Exception{"Illegal column " + columns[arguments[0]].column->getName() +
throw Exception{"Illegal column " + arguments[0].column->getName() +
" of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
};

View File

@ -10,13 +10,13 @@ namespace ErrorCodes
}
std::vector<FunctionJSONHelpers::Move> FunctionJSONHelpers::prepareMoves(const char * function_name, ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t first_index_argument, size_t num_index_arguments)
std::vector<FunctionJSONHelpers::Move> FunctionJSONHelpers::prepareMoves(const char * function_name, ColumnsWithTypeAndName & columns, size_t first_index_argument, size_t num_index_arguments)
{
std::vector<Move> moves;
moves.reserve(num_index_arguments);
for (const auto i : ext::range(first_index_argument, first_index_argument + num_index_arguments))
{
const auto & column = columns[arguments[i]];
const auto & column = columns[i];
if (!isString(column.type) && !isInteger(column.type))
throw Exception{"The argument " + std::to_string(i + 1) + " of function " + String(function_name)
+ " should be a string specifying key or an integer specifying index, illegal type: " + column.type->getName(),

View File

@ -55,22 +55,22 @@ public:
class Executor
{
public:
static void run(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_pos, size_t input_rows_count)
static ColumnPtr run(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count)
{
MutableColumnPtr to{columns[result_pos].type->createColumn()};
MutableColumnPtr to{result_type->createColumn()};
to->reserve(input_rows_count);
if (arguments.size() < 1)
if (arguments.empty())
throw Exception{"Function " + String(Name::name) + " requires at least one argument", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
const auto & first_column = columns[arguments[0]];
const auto & first_column = arguments[0];
if (!isString(first_column.type))
throw Exception{"The first argument of function " + String(Name::name) + " should be a string containing JSON, illegal type: " + first_column.type->getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
const ColumnPtr & arg_json = first_column.column;
auto col_json_const = typeid_cast<const ColumnConst *>(arg_json.get());
auto col_json_string
const auto * col_json_const = typeid_cast<const ColumnConst *>(arg_json.get());
const auto * col_json_string
= typeid_cast<const ColumnString *>(col_json_const ? col_json_const->getDataColumnPtr().get() : arg_json.get());
if (!col_json_string)
@ -79,8 +79,8 @@ public:
const ColumnString::Chars & chars = col_json_string->getChars();
const ColumnString::Offsets & offsets = col_json_string->getOffsets();
size_t num_index_arguments = Impl<JSONParser>::getNumberOfIndexArguments(columns, arguments);
std::vector<Move> moves = prepareMoves(Name::name, columns, arguments, 1, num_index_arguments);
size_t num_index_arguments = Impl<JSONParser>::getNumberOfIndexArguments(arguments);
std::vector<Move> moves = prepareMoves(Name::name, arguments, 1, num_index_arguments);
/// Preallocate memory in parser if necessary.
JSONParser parser;
@ -94,8 +94,8 @@ public:
Impl<JSONParser> impl;
/// prepare() does Impl-specific preparation before handling each row.
if constexpr (has_member_function_prepare<void (Impl<JSONParser>::*)(const char *, const ColumnsWithTypeAndName &, const ColumnNumbers &, size_t)>::value)
impl.prepare(Name::name, columns, arguments, result_pos);
if constexpr (has_member_function_prepare<void (Impl<JSONParser>::*)(const char *, const ColumnsWithTypeAndName &, const DataTypePtr &)>::value)
impl.prepare(Name::name, arguments, result_type);
using Element = typename JSONParser::Element;
@ -121,7 +121,7 @@ public:
/// Perform moves.
Element element;
std::string_view last_key;
bool moves_ok = performMoves<JSONParser>(columns, arguments, i, document, moves, element, last_key);
bool moves_ok = performMoves<JSONParser>(arguments, i, document, moves, element, last_key);
if (moves_ok)
added_to_column = impl.insertResultToColumn(*to, element, last_key);
@ -131,7 +131,7 @@ public:
if (!added_to_column)
to->insertDefault();
}
columns[result_pos].column = std::move(to);
return to;
}
};
@ -166,11 +166,11 @@ private:
String key;
};
static std::vector<Move> prepareMoves(const char * function_name, ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t first_index_argument, size_t num_index_arguments);
static std::vector<Move> prepareMoves(const char * function_name, ColumnsWithTypeAndName & columns, size_t first_index_argument, size_t num_index_arguments);
/// Performs moves of types MoveType::Index and MoveType::ConstIndex.
template <typename JSONParser>
static bool performMoves(const ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t row,
static bool performMoves(const ColumnsWithTypeAndName & arguments, size_t row,
const typename JSONParser::Element & document, const std::vector<Move> & moves,
typename JSONParser::Element & element, std::string_view & last_key)
{
@ -196,14 +196,14 @@ private:
}
case MoveType::Index:
{
Int64 index = (*columns[arguments[j + 1]].column)[row].get<Int64>();
Int64 index = (*arguments[j + 1].column)[row].get<Int64>();
if (!moveToElementByIndex<JSONParser>(res_element, index, key))
return false;
break;
}
case MoveType::Key:
{
key = std::string_view{(*columns[arguments[j + 1]].column).getDataAt(row)};
key = std::string_view{(*arguments[j + 1].column).getDataAt(row)};
if (!moveToElementByKey<JSONParser>(res_element, key))
return false;
break;
@ -286,21 +286,18 @@ public:
return Impl<DummyJSONParser>::getReturnType(Name::name, arguments);
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_pos, size_t input_rows_count) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{
/// Choose JSONParser.
#if USE_SIMDJSON
if (context.getSettingsRef().allow_simdjson)
{
FunctionJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(columns, arguments, result_pos, input_rows_count);
return;
}
return FunctionJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(arguments, result_type, input_rows_count);
#endif
#if USE_RAPIDJSON
FunctionJSONHelpers::Executor<Name, Impl, RapidJSONParser>::run(columns, arguments, result_pos, input_rows_count);
return FunctionJSONHelpers::Executor<Name, Impl, RapidJSONParser>::run(arguments, result_type, input_rows_count);
#else
FunctionJSONHelpers::Executor<Name, Impl, DummyJSONParser>::run(columns, arguments, result_pos, input_rows_count);
return FunctionJSONHelpers::Executor<Name, Impl, DummyJSONParser>::run(arguments, result_type, input_rows_count);
#endif
}
@ -334,7 +331,7 @@ public:
static DataTypePtr getReturnType(const char *, const ColumnsWithTypeAndName &) { return std::make_shared<DataTypeUInt8>(); }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view &)
{
@ -362,7 +359,7 @@ public:
return std::make_shared<DataTypeUInt8>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers &) { return 0; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &) { return 0; }
static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view &)
{
@ -386,7 +383,7 @@ public:
return std::make_shared<DataTypeUInt64>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -416,7 +413,7 @@ public:
return std::make_shared<DataTypeString>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view & last_key)
{
@ -450,7 +447,7 @@ public:
return std::make_shared<DataTypeEnum<Int8>>(values);
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -492,7 +489,7 @@ public:
return std::make_shared<DataTypeNumber<NumberType>>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -557,7 +554,7 @@ public:
return std::make_shared<DataTypeUInt8>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -582,7 +579,7 @@ public:
return std::make_shared<DataTypeString>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -909,11 +906,11 @@ public:
return DataTypeFactory::instance().get(col_type_const->getValue<String>());
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 2; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 2; }
void prepare(const char * function_name, const ColumnsWithTypeAndName & columns, const ColumnNumbers &, size_t result_pos)
void prepare(const char * function_name, const ColumnsWithTypeAndName &, const DataTypePtr & result_type)
{
extract_tree = JSONExtractTree<JSONParser>::build(function_name, columns[result_pos].type);
extract_tree = JSONExtractTree<JSONParser>::build(function_name, result_type);
}
bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
@ -950,11 +947,10 @@ public:
return std::make_unique<DataTypeArray>(tuple_type);
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 2; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 2; }
void prepare(const char * function_name, const ColumnsWithTypeAndName & columns, const ColumnNumbers &, size_t result_pos)
void prepare(const char * function_name, const ColumnsWithTypeAndName &, const DataTypePtr & result_type)
{
const auto & result_type = columns[result_pos].type;
const auto tuple_type = typeid_cast<const DataTypeArray *>(result_type.get())->getNestedType();
const auto value_type = typeid_cast<const DataTypeTuple *>(tuple_type.get())->getElements()[1];
extract_tree = JSONExtractTree<JSONParser>::build(function_name, value_type);
@ -1002,7 +998,7 @@ public:
return std::make_shared<DataTypeString>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -1106,7 +1102,7 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>());
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
@ -1138,7 +1134,7 @@ public:
return std::make_unique<DataTypeArray>(tuple_type);
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &, const ColumnNumbers & arguments) { return arguments.size() - 1; }
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{

View File

@ -342,7 +342,7 @@ struct OperationApplier<Op, OperationApplierImpl, 0>
template <class Op>
static void executeForTernaryLogicImpl(ColumnRawPtrs arguments, ColumnWithTypeAndName & result_info, size_t input_rows_count)
static ColumnPtr executeForTernaryLogicImpl(ColumnRawPtrs arguments, const DataTypePtr & result_type, size_t input_rows_count)
{
/// Combine all constant columns into a single constant value.
UInt8 const_3v_value = 0;
@ -351,11 +351,10 @@ static void executeForTernaryLogicImpl(ColumnRawPtrs arguments, ColumnWithTypeAn
/// If the constant value uniquely determines the result, return it.
if (has_consts && (arguments.empty() || Op::isSaturatedValueTernary(const_3v_value)))
{
result_info.column = ColumnConst::create(
buildColumnFromTernaryData(UInt8Container({const_3v_value}), result_info.type->isNullable()),
return ColumnConst::create(
buildColumnFromTernaryData(UInt8Container({const_3v_value}), result_type->isNullable()),
input_rows_count
);
return;
}
const auto result_column = has_consts ?
@ -363,7 +362,7 @@ static void executeForTernaryLogicImpl(ColumnRawPtrs arguments, ColumnWithTypeAn
OperationApplier<Op, AssociativeGenericApplierImpl>::apply(arguments, result_column->getData(), has_consts);
result_info.column = buildColumnFromTernaryData(result_column->getData(), result_info.type->isNullable());
return buildColumnFromTernaryData(result_column->getData(), result_type->isNullable());
}
@ -418,7 +417,7 @@ struct TypedExecutorInvoker<Op>
/// Types of all of the arguments are guaranteed to be non-nullable here
template <class Op>
static void basicExecuteImpl(ColumnRawPtrs arguments, ColumnWithTypeAndName & result_info, size_t input_rows_count)
static ColumnPtr basicExecuteImpl(ColumnRawPtrs arguments, size_t input_rows_count)
{
/// Combine all constant columns into a single constant value.
UInt8 const_val = 0;
@ -429,8 +428,7 @@ static void basicExecuteImpl(ColumnRawPtrs arguments, ColumnWithTypeAndName & re
{
if (!arguments.empty())
const_val = Op::apply(const_val, 0);
result_info.column = DataTypeUInt8().createColumnConst(input_rows_count, toField(const_val));
return;
return DataTypeUInt8().createColumnConst(input_rows_count, toField(const_val));
}
/// If the constant value is a neutral element, let's forget about it.
@ -448,8 +446,7 @@ static void basicExecuteImpl(ColumnRawPtrs arguments, ColumnWithTypeAndName & re
else
FastApplierImpl<Op>::apply(*arguments[0], *arguments[1], col_res->getData());
result_info.column = std::move(col_res);
return;
return col_res;
}
/// Convert all columns to UInt8
@ -470,7 +467,7 @@ static void basicExecuteImpl(ColumnRawPtrs arguments, ColumnWithTypeAndName & re
OperationApplier<Op, AssociativeApplierImpl>::apply(uint8_args, col_res->getData(), has_consts);
result_info.column = std::move(col_res);
return col_res;
}
}
@ -511,18 +508,17 @@ DataTypePtr FunctionAnyArityLogical<Impl, Name>::getReturnTypeImpl(const DataTyp
}
template <typename Impl, typename Name>
void FunctionAnyArityLogical<Impl, Name>::executeImpl(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_index, size_t input_rows_count) const
ColumnPtr FunctionAnyArityLogical<Impl, Name>::executeImpl(
ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
ColumnRawPtrs args_in;
for (const auto arg_index : arguments)
args_in.push_back(columns[arg_index].column.get());
for (const auto & arg_index : arguments)
args_in.push_back(arg_index.column.get());
auto & result_info = columns[result_index];
if (result_info.type->isNullable())
executeForTernaryLogicImpl<Impl>(std::move(args_in), result_info, input_rows_count);
if (result_type->isNullable())
return executeForTernaryLogicImpl<Impl>(std::move(args_in), result_type, input_rows_count);
else
basicExecuteImpl<Impl>(std::move(args_in), result_info, input_rows_count);
return basicExecuteImpl<Impl>(std::move(args_in), input_rows_count);
}
@ -554,9 +550,9 @@ DataTypePtr FunctionUnaryLogical<Impl, Name>::getReturnTypeImpl(const DataTypes
}
template <template <typename> class Impl, typename T>
bool functionUnaryExecuteType(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result)
ColumnPtr functionUnaryExecuteType(ColumnsWithTypeAndName & arguments)
{
if (auto col = checkAndGetColumn<ColumnVector<T>>(columns[arguments[0]].column.get()))
if (auto col = checkAndGetColumn<ColumnVector<T>>(arguments[0].column.get()))
{
auto col_res = ColumnUInt8::create();
@ -564,29 +560,31 @@ bool functionUnaryExecuteType(ColumnsWithTypeAndName & columns, const ColumnNumb
vec_res.resize(col->getData().size());
UnaryOperationImpl<T, Impl<T>>::vector(col->getData(), vec_res);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
return false;
return nullptr;
}
template <template <typename> class Impl, typename Name>
void FunctionUnaryLogical<Impl, Name>::executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const
ColumnPtr FunctionUnaryLogical<Impl, Name>::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{
if (!(functionUnaryExecuteType<Impl, UInt8>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, UInt16>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, UInt32>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, UInt64>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, Int8>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, Int16>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, Int32>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, Int64>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, Float32>(columns, arguments, result)
|| functionUnaryExecuteType<Impl, Float64>(columns, arguments, result)))
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
ColumnPtr res;
if (!((res = functionUnaryExecuteType<Impl, UInt8>(arguments))
|| (res = functionUnaryExecuteType<Impl, UInt16>(arguments))
|| (res = functionUnaryExecuteType<Impl, UInt32>(arguments))
|| (res = functionUnaryExecuteType<Impl, UInt64>(arguments))
|| (res = functionUnaryExecuteType<Impl, Int8>(arguments))
|| (res = functionUnaryExecuteType<Impl, Int16>(arguments))
|| (res = functionUnaryExecuteType<Impl, Int32>(arguments))
|| (res = functionUnaryExecuteType<Impl, Int64>(arguments))
|| (res = functionUnaryExecuteType<Impl, Float32>(arguments))
|| (res = functionUnaryExecuteType<Impl, Float64>(arguments))))
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
return res;
}
}

View File

@ -154,7 +154,7 @@ public:
/// Get result types by argument types. If the function does not apply to these arguments, throw an exception.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_index, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override;
#if USE_EMBEDDED_COMPILER
bool isCompilableImpl(const DataTypes &) const override { return useDefaultImplementationForNulls(); }
@ -217,7 +217,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
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 USE_EMBEDDED_COMPILER
bool isCompilableImpl(const DataTypes &) const override { return true; }

View File

@ -35,19 +35,19 @@ public:
String getName() const override { return "FunctionExpression"; }
void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) override
{
DB::Block expr_columns;
for (size_t i = 0; i < arguments.size(); ++i)
{
const auto & argument = columns[arguments[i]];
const auto & argument = arguments[i];
/// Replace column name with value from argument_names.
expr_columns.insert({argument.column, argument.type, signature->argument_names[i]});
}
expression_actions->execute(expr_columns);
columns[result].column = expr_columns.getByName(signature->return_name).column;
return expr_columns.getByName(signature->return_name).column;
}
bool useDefaultImplementationForNulls() const override { return false; }
@ -79,9 +79,9 @@ public:
bool isDeterministicInScopeOfQuery() const override { return true; }
const DataTypes & getArgumentTypes() const override { return argument_types; }
const DataTypePtr & getReturnType() const override { return return_type; }
const DataTypePtr & getResultType() const override { return return_type; }
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName &, const ColumnNumbers &, size_t) const override
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName &) const override
{
return std::make_unique<ExecutableFunctionExpression>(expression_actions, signature);
}
@ -119,11 +119,8 @@ public:
bool useDefaultImplementationForNulls() const override { return false; }
bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }
void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) override
{
ColumnsWithTypeAndName columns_to_catpure;
columns_to_catpure.reserve(arguments.size());
Names names;
DataTypes types;
@ -139,13 +136,10 @@ public:
types.push_back(lambda_argument.type);
}
for (const auto & argument : arguments)
columns_to_catpure.push_back(columns[argument]);
auto function = std::make_unique<FunctionExpression>(expression_actions, types, names,
capture->return_type, capture->return_name);
auto function_adaptor = std::make_shared<FunctionBaseAdaptor>(std::move(function));
columns[result].column = ColumnFunction::create(input_rows_count, std::move(function_adaptor), columns_to_catpure);
return ColumnFunction::create(input_rows_count, std::move(function_adaptor), arguments);
}
private:
@ -177,9 +171,9 @@ public:
bool isDeterministicInScopeOfQuery() const override { return true; }
const DataTypes & getArgumentTypes() const override { return capture->captured_types; }
const DataTypePtr & getReturnType() const override { return return_type; }
const DataTypePtr & getResultType() const override { return return_type; }
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName &, const ColumnNumbers &, size_t) const override
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName &) const override
{
return std::make_unique<ExecutableFunctionCapture>(expression_actions, capture);
}

View File

@ -66,15 +66,15 @@ public:
return Impl::getReturnType();
}
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
{
using ResultType = typename Impl::ResultType;
const ColumnPtr & column_haystack = columns[arguments[0]].column;
const ColumnPtr & column_haystack = arguments[0].column;
const ColumnString * col_haystack_vector = checkAndGetColumn<ColumnString>(&*column_haystack);
const ColumnPtr & num_ptr = columns[arguments[1]].column;
const ColumnPtr & num_ptr = arguments[1].column;
const ColumnConst * col_const_num = nullptr;
UInt32 edit_distance = 0;
@ -86,17 +86,17 @@ public:
edit_distance = col_const_num->getValue<UInt32>();
else
throw Exception(
"Illegal column " + columns[arguments[1]].column->getName()
"Illegal column " + arguments[1].column->getName()
+ ". The number is not const or does not fit in UInt32",
ErrorCodes::ILLEGAL_COLUMN);
const ColumnPtr & arr_ptr = columns[arguments[2]].column;
const ColumnPtr & arr_ptr = arguments[2].column;
const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arr_ptr.get());
if (!col_const_arr)
throw Exception(
"Illegal column " + columns[arguments[2]].column->getName() + ". The array is not const",
"Illegal column " + arguments[2].column->getName() + ". The array is not const",
ErrorCodes::ILLEGAL_COLUMN);
Array src_arr = col_const_arr->getValue<Array>();
@ -124,12 +124,12 @@ public:
Impl::vectorConstant(
col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res, offsets_res, edit_distance);
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName(), ErrorCodes::ILLEGAL_COLUMN);
throw Exception("Illegal column " + arguments[0].column->getName(), ErrorCodes::ILLEGAL_COLUMN);
if constexpr (Impl::is_column_array)
columns[result].column = ColumnArray::create(std::move(col_res), std::move(col_offsets));
return ColumnArray::create(std::move(col_res), std::move(col_offsets));
else
columns[result].column = std::move(col_res);
return col_res;
}
};

View File

@ -73,20 +73,20 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeUInt64>());
}
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
{
using ResultType = typename Impl::ResultType;
const ColumnPtr & column_haystack = columns[arguments[0]].column;
const ColumnPtr & column_haystack = arguments[0].column;
const ColumnString * col_haystack_vector = checkAndGetColumn<ColumnString>(&*column_haystack);
const ColumnPtr & arr_ptr = columns[arguments[1]].column;
const ColumnPtr & arr_ptr = arguments[1].column;
const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arr_ptr.get());
if (!col_const_arr)
throw Exception(
"Illegal column " + columns[arguments[1]].column->getName() + ". The array is not const",
"Illegal column " + arguments[1].column->getName() + ". The array is not const",
ErrorCodes::ILLEGAL_COLUMN);
Array src_arr = col_const_arr->getValue<Array>();
@ -114,7 +114,7 @@ public:
if (col_haystack_vector)
Impl::vectorConstant(col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res);
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName(), ErrorCodes::ILLEGAL_COLUMN);
throw Exception("Illegal column " + arguments[0].column->getName(), ErrorCodes::ILLEGAL_COLUMN);
size_t refs_size = refs.size();
size_t accum = refs_size;
@ -122,7 +122,7 @@ public:
for (size_t i = 0; i < column_haystack_size; ++i, accum += refs_size)
offsets_res[i] = accum;
columns[result].column = ColumnArray::create(std::move(col_res), std::move(col_offsets));
return ColumnArray::create(std::move(col_res), std::move(col_offsets));
}
};

View File

@ -75,20 +75,20 @@ public:
return Impl::getReturnType();
}
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
{
using ResultType = typename Impl::ResultType;
const ColumnPtr & column_haystack = columns[arguments[0]].column;
const ColumnPtr & column_haystack = arguments[0].column;
const ColumnString * col_haystack_vector = checkAndGetColumn<ColumnString>(&*column_haystack);
const ColumnPtr & arr_ptr = columns[arguments[1]].column;
const ColumnPtr & arr_ptr = arguments[1].column;
const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arr_ptr.get());
if (!col_const_arr)
throw Exception(
"Illegal column " + columns[arguments[1]].column->getName() + ". The array is not const",
"Illegal column " + arguments[1].column->getName() + ". The array is not const",
ErrorCodes::ILLEGAL_COLUMN);
Array src_arr = col_const_arr->getValue<Array>();
@ -115,12 +115,12 @@ public:
if (col_haystack_vector)
Impl::vectorConstant(col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res, offsets_res);
else
throw Exception("Illegal column " + columns[arguments[0]].column->getName(), ErrorCodes::ILLEGAL_COLUMN);
throw Exception("Illegal column " + arguments[0].column->getName(), ErrorCodes::ILLEGAL_COLUMN);
if constexpr (Impl::is_column_array)
columns[result].column = ColumnArray::create(std::move(col_res), std::move(col_offsets));
return ColumnArray::create(std::move(col_res), std::move(col_offsets));
else
columns[result].column = std::move(col_res);
return col_res;
}
};

View File

@ -74,7 +74,7 @@ public:
return std::make_shared<DataTypeNumber<ToType>>();
}
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
{
auto col_to = ColumnVector<ToType>::create();
typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
@ -83,7 +83,7 @@ public:
vec_to.resize(size);
RandImpl::execute(reinterpret_cast<char *>(vec_to.data()), vec_to.size() * sizeof(ToType));
columns[result].column = std::move(col_to);
return col_to;
}
};
@ -102,9 +102,9 @@ public:
#endif
}
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
{
selector.selectAndExecute(columns, arguments, result, input_rows_count);
return selector.selectAndExecute(arguments, result_type, input_rows_count);
}
static FunctionPtr create(const Context & context)

View File

@ -458,7 +458,7 @@ class Dispatcher
FloatRoundingImpl<T, rounding_mode, scale_mode>,
IntegerRoundingImpl<T, rounding_mode, scale_mode, tie_breaking_mode>>;
static void apply(ColumnsWithTypeAndName & columns, const ColumnVector<T> * col, Int64 scale_arg, size_t result)
static ColumnPtr apply(const ColumnVector<T> * col, Int64 scale_arg)
{
auto col_res = ColumnVector<T>::create();
@ -484,10 +484,10 @@ class Dispatcher
}
}
columns[result].column = std::move(col_res);
return col_res;
}
static void apply(ColumnsWithTypeAndName & columns, const ColumnDecimal<T> * col, Int64 scale_arg, size_t result)
static ColumnPtr apply(const ColumnDecimal<T> * col, Int64 scale_arg)
{
const typename ColumnDecimal<T>::Container & vec_src = col->getData();
@ -497,16 +497,16 @@ class Dispatcher
if (!vec_res.empty())
DecimalRoundingImpl<T, rounding_mode, tie_breaking_mode>::apply(col->getData(), vec_res, scale_arg);
columns[result].column = std::move(col_res);
return col_res;
}
public:
static void apply(ColumnsWithTypeAndName & columns, const IColumn * column, Int64 scale_arg, size_t result)
static ColumnPtr apply(const IColumn * column, Int64 scale_arg)
{
if constexpr (IsNumber<T>)
apply(columns, checkAndGetColumn<ColumnVector<T>>(column), scale_arg, result);
return apply(checkAndGetColumn<ColumnVector<T>>(column), scale_arg);
else if constexpr (IsDecimalNumber<T>)
apply(columns, checkAndGetColumn<ColumnDecimal<T>>(column), scale_arg, result);
return apply(checkAndGetColumn<ColumnDecimal<T>>(column), scale_arg);
}
};
@ -520,7 +520,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context &) { return std::make_shared<FunctionRounding>(); }
public:
String getName() const override
{
return name;
@ -532,7 +531,7 @@ public:
/// Get result types by argument types. If the function does not apply to these arguments, throw an exception.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if ((arguments.size() < 1) || (arguments.size() > 2))
if ((arguments.empty()) || (arguments.size() > 2))
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
+ toString(arguments.size()) + ", should be 1 or 2.",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
@ -545,11 +544,11 @@ public:
return arguments[0];
}
static Int64 getScaleArg(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments)
static Int64 getScaleArg(ColumnsWithTypeAndName & arguments)
{
if (arguments.size() == 2)
{
const IColumn & scale_column = *columns[arguments[1]].column;
const IColumn & scale_column = *arguments[1].column;
if (!isColumnConst(scale_column))
throw Exception("Scale argument for rounding functions must be constant.", ErrorCodes::ILLEGAL_COLUMN);
@ -566,11 +565,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {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
{
const ColumnWithTypeAndName & column = columns[arguments[0]];
Int64 scale_arg = getScaleArg(columns, arguments);
const ColumnWithTypeAndName & column = arguments[0];
Int64 scale_arg = getScaleArg(arguments);
ColumnPtr res;
auto call = [&](const auto & types) -> bool
{
using Types = std::decay_t<decltype(types)>;
@ -579,7 +579,7 @@ public:
if constexpr (IsDataTypeNumber<DataType> || IsDataTypeDecimal<DataType>)
{
using FieldType = typename DataType::FieldType;
Dispatcher<FieldType, rounding_mode, tie_breaking_mode>::apply(columns, column.column.get(), scale_arg, result);
res = Dispatcher<FieldType, rounding_mode, tie_breaking_mode>::apply(column.column.get(), scale_arg);
return true;
}
return false;
@ -590,6 +590,8 @@ public:
throw Exception("Illegal column " + column.name + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
return res;
}
bool hasInformationAboutMonotonicity() const override
@ -613,7 +615,6 @@ public:
static constexpr auto name = "roundDown";
static FunctionPtr create(const Context &) { return std::make_shared<FunctionRoundDown>(); }
public:
String getName() const override { return name; }
bool isVariadic() const override { return false; }
@ -646,25 +647,25 @@ public:
return getLeastSupertype({type_x, type_arr_nested});
}
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
{
auto in_column = columns[arguments[0]].column;
const auto & in_type = columns[arguments[0]].type;
auto in_column = arguments[0].column;
const auto & in_type = arguments[0].type;
auto array_column = columns[arguments[1]].column;
const auto & array_type = columns[arguments[1]].type;
auto array_column = arguments[1].column;
const auto & array_type = arguments[1].type;
const auto & return_type = columns[result].type;
const auto & return_type = result_type;
auto column_result = return_type->createColumn();
auto out = column_result.get();
auto * out = column_result.get();
if (!in_type->equals(*return_type))
in_column = castColumn(columns[arguments[0]], return_type);
in_column = castColumn(arguments[0], return_type);
if (!array_type->equals(*return_type))
array_column = castColumn(columns[arguments[1]], std::make_shared<DataTypeArray>(return_type));
array_column = castColumn(arguments[1], std::make_shared<DataTypeArray>(return_type));
const auto in = in_column.get();
const auto * in = in_column.get();
auto boundaries = typeid_cast<const ColumnConst &>(*array_column).getValue<Array>();
size_t num_boundaries = boundaries.size();
if (!num_boundaries)
@ -687,7 +688,7 @@ public:
throw Exception{"Illegal column " + in->getName() + " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
}
columns[result].column = std::move(column_result);
return column_result;
}
private:

View File

@ -75,7 +75,7 @@ public:
}
/// Initialize by the function arguments.
void init(ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) {}
void init(ColumnsWithTypeAndName & /*arguments*/) {}
/// Called for each next string.
void set(Pos pos_, Pos end_)
@ -136,12 +136,12 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
void init(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments)
void init(ColumnsWithTypeAndName & arguments)
{
const ColumnConst * col = checkAndGetColumnConstStringOrFixedString(columns[arguments[0]].column.get());
const ColumnConst * col = checkAndGetColumnConstStringOrFixedString(arguments[0].column.get());
if (!col)
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName() + ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN);
@ -204,12 +204,12 @@ public:
SplitByCharImpl::checkArguments(arguments);
}
void init(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments)
void init(ColumnsWithTypeAndName & arguments)
{
const ColumnConst * col = checkAndGetColumnConstStringOrFixedString(columns[arguments[0]].column.get());
const ColumnConst * col = checkAndGetColumnConstStringOrFixedString(arguments[0].column.get());
if (!col)
throw Exception("Illegal column " + columns[arguments[0]].column->getName()
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName() + ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN);
@ -284,12 +284,12 @@ public:
}
/// Initialize by the function arguments.
void init(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments)
void init(ColumnsWithTypeAndName & arguments)
{
const ColumnConst * col = checkAndGetColumnConstStringOrFixedString(columns[arguments[1]].column.get());
const ColumnConst * col = checkAndGetColumnConstStringOrFixedString(arguments[1].column.get());
if (!col)
throw Exception("Illegal column " + columns[arguments[1]].column->getName()
throw Exception("Illegal column " + arguments[1].column->getName()
+ " of first argument of function " + getName() + ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN);
@ -361,15 +361,15 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>());
}
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
{
Generator generator;
generator.init(columns, arguments);
size_t array_argument_position = arguments[generator.getStringsArgumentPosition()];
generator.init(arguments);
const auto & array_argument = arguments[generator.getStringsArgumentPosition()];
const ColumnString * col_str = checkAndGetColumn<ColumnString>(columns[array_argument_position].column.get());
const ColumnString * col_str = checkAndGetColumn<ColumnString>(array_argument.column.get());
const ColumnConst * col_const_str =
checkAndGetColumnConstStringOrFixedString(columns[array_argument_position].column.get());
checkAndGetColumnConstStringOrFixedString(array_argument.column.get());
auto col_res = ColumnArray::create(ColumnString::create());
ColumnString & res_strings = typeid_cast<ColumnString &>(col_res->getData());
@ -419,7 +419,7 @@ public:
res_offsets.push_back(current_dst_offset);
}
columns[result].column = std::move(col_res);
return col_res;
}
else if (col_const_str)
{
@ -433,11 +433,11 @@ public:
while (generator.get(token_begin, token_end))
dst.push_back(String(token_begin, token_end - token_begin));
columns[result].column = columns[result].type->createColumnConst(col_const_str->size(), dst);
return result_type->createColumnConst(col_const_str->size(), dst);
}
else
throw Exception("Illegal columns " + columns[array_argument_position].column->getName()
+ ", " + columns[array_argument_position].column->getName()
throw Exception("Illegal columns " + array_argument.column->getName()
+ ", " + array_argument.column->getName()
+ " of arguments of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
@ -536,19 +536,19 @@ public:
return std::make_shared<DataTypeString>();
}
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
{
String delimiter;
if (arguments.size() == 2)
{
const ColumnConst * col_delim = checkAndGetColumnConstStringOrFixedString(columns[arguments[1]].column.get());
const ColumnConst * col_delim = checkAndGetColumnConstStringOrFixedString(arguments[1].column.get());
if (!col_delim)
throw Exception("Second argument for function " + getName() + " must be constant string.", ErrorCodes::ILLEGAL_COLUMN);
delimiter = col_delim->getValue<String>();
}
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(columns[arguments[0]].column.get()))
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arguments[0].column.get()))
{
Array src_arr = col_const_arr->getValue<Array>();
String dst_str;
@ -559,11 +559,11 @@ public:
dst_str += src_arr[i].get<const String &>();
}
columns[result].column = columns[result].type->createColumnConst(col_const_arr->size(), dst_str);
return result_type->createColumnConst(col_const_arr->size(), dst_str);
}
else
{
const ColumnArray & col_arr = assert_cast<const ColumnArray &>(*columns[arguments[0]].column);
const ColumnArray & col_arr = assert_cast<const ColumnArray &>(*arguments[0].column);
const ColumnString & col_string = assert_cast<const ColumnString &>(col_arr.getData());
auto col_res = ColumnString::create();
@ -573,7 +573,7 @@ public:
delimiter.data(), delimiter.size(),
col_res->getChars(), col_res->getOffsets());
columns[result].column = std::move(col_res);
return col_res;
}
}
};

View File

@ -97,16 +97,16 @@ public:
return std::make_shared<DataTypeNumber<typename Impl::ResultType>>();
}
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
{
using ResultType = typename Impl::ResultType;
const ColumnPtr & column_haystack = columns[arguments[0]].column;
const ColumnPtr & column_needle = columns[arguments[1]].column;
const ColumnPtr & column_haystack = arguments[0].column;
const ColumnPtr & column_needle = arguments[1].column;
ColumnPtr column_start_pos = nullptr;
if (arguments.size() >= 3)
column_start_pos = columns[arguments[2]].column;
column_start_pos = arguments[2].column;
const ColumnConst * col_haystack_const = typeid_cast<const ColumnConst *>(&*column_haystack);
const ColumnConst * col_needle_const = typeid_cast<const ColumnConst *>(&*column_needle);
@ -127,12 +127,9 @@ public:
vec_res);
if (is_col_start_pos_const)
columns[result].column
= columns[result].type->createColumnConst(col_haystack_const->size(), toField(vec_res[0]));
return result_type->createColumnConst(col_haystack_const->size(), toField(vec_res[0]));
else
columns[result].column = std::move(col_res);
return;
return col_res;
}
}
@ -175,11 +172,11 @@ public:
vec_res);
else
throw Exception(
"Illegal columns " + columns[arguments[0]].column->getName() + " and "
+ columns[arguments[1]].column->getName() + " of arguments of function " + getName(),
"Illegal columns " + arguments[0].column->getName() + " and "
+ arguments[1].column->getName() + " of arguments of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
columns[result].column = std::move(col_res);
return col_res;
}
};

View File

@ -58,10 +58,10 @@ public:
return std::make_shared<DataTypeString>();
}
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
{
const ColumnPtr column = columns[arguments[0]].column;
const ColumnPtr column_needle = columns[arguments[1]].column;
const ColumnPtr column = arguments[0].column;
const ColumnPtr column_needle = arguments[1].column;
const ColumnConst * col_needle = typeid_cast<const ColumnConst *>(&*column_needle);
if (!col_needle)
@ -75,11 +75,11 @@ public:
ColumnString::Offsets & offsets_res = col_res->getOffsets();
Impl::vector(col->getChars(), col->getOffsets(), col_needle->getValue<String>(), vec_res, offsets_res);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception(
"Illegal column " + columns[arguments[0]].column->getName() + " of argument of function " + getName(),
"Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
};

View File

@ -51,12 +51,12 @@ public:
return std::make_shared<DataTypeNumber<typename Impl::ResultType>>();
}
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
{
using ResultType = typename Impl::ResultType;
const ColumnPtr & column_haystack = columns[arguments[0]].column;
const ColumnPtr & column_needle = columns[arguments[1]].column;
const ColumnPtr & column_haystack = arguments[0].column;
const ColumnPtr & column_needle = arguments[1].column;
const ColumnConst * col_haystack_const = typeid_cast<const ColumnConst *>(&*column_haystack);
const ColumnConst * col_needle_const = typeid_cast<const ColumnConst *>(&*column_needle);
@ -73,9 +73,7 @@ public:
ErrorCodes::TOO_LARGE_STRING_SIZE);
}
Impl::constantConstant(col_haystack_const->getValue<String>(), needle, res);
columns[result].column
= columns[result].type->createColumnConst(col_haystack_const->size(), toField(res));
return;
return result_type->createColumnConst(col_haystack_const->size(), toField(res));
}
auto col_res = ColumnVector<ResultType>::create();
@ -122,12 +120,12 @@ public:
else
{
throw Exception(
"Illegal columns " + columns[arguments[0]].column->getName() + " and "
+ columns[arguments[1]].column->getName() + " of arguments of function " + getName(),
"Illegal columns " + arguments[0].column->getName() + " and "
+ arguments[1].column->getName() + " of arguments of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}
columns[result].column = std::move(col_res);
return col_res;
}
};

View File

@ -14,7 +14,6 @@
#include <Functions/FunctionHelpers.h>
#include <Interpreters/ExpressionActions.h>
#include <IO/WriteHelpers.h>
#include <ext/range.h>
#include <ext/collection_cast.h>
#include <cstdlib>
#include <memory>
@ -104,7 +103,7 @@ void ExecutableFunctionAdaptor::createLowCardinalityResultCache(size_t cache_siz
}
ColumnPtr wrapInNullable(const ColumnPtr & src, const ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count)
ColumnPtr wrapInNullable(const ColumnPtr & src, const ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count)
{
ColumnPtr result_null_map_column;
@ -119,16 +118,14 @@ ColumnPtr wrapInNullable(const ColumnPtr & src, const ColumnsWithTypeAndName & c
result_null_map_column = nullable->getNullMapColumnPtr();
}
for (const auto & arg : args)
for (const auto & elem : args)
{
const ColumnWithTypeAndName & elem = columns[arg];
if (!elem.type->isNullable())
continue;
/// Const Nullable that are NULL.
if (elem.column->onlyNull())
{
auto result_type = columns[result].type;
assert(result_type->isNullable());
return result_type->createColumnConstWithDefaultValue(input_rows_count);
}
@ -175,23 +172,6 @@ struct NullPresence
bool has_null_constant = false;
};
NullPresence getNullPresense(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args)
{
NullPresence res;
for (const auto & arg : args)
{
const auto & elem = columns[arg];
if (!res.has_nullable)
res.has_nullable = elem.type->isNullable();
if (!res.has_null_constant)
res.has_null_constant = elem.type->onlyNull();
}
return res;
}
NullPresence getNullPresense(const ColumnsWithTypeAndName & args)
{
NullPresence res;
@ -207,35 +187,36 @@ NullPresence getNullPresense(const ColumnsWithTypeAndName & args)
return res;
}
bool allArgumentsAreConstants(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args)
bool allArgumentsAreConstants(const ColumnsWithTypeAndName & args)
{
for (auto arg : args)
if (!isColumnConst(*columns[arg].column))
for (const auto & arg : args)
if (!isColumnConst(*arg.column))
return false;
return true;
}
}
bool ExecutableFunctionAdaptor::defaultImplementationForConstantArguments(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run)
ColumnPtr ExecutableFunctionAdaptor::defaultImplementationForConstantArguments(
ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run)
{
ColumnNumbers arguments_to_remain_constants = impl->getArgumentsThatAreAlwaysConstant();
/// Check that these arguments are really constant.
for (auto arg_num : arguments_to_remain_constants)
if (arg_num < args.size() && !isColumnConst(*columns[args[arg_num]].column))
if (arg_num < args.size() && !isColumnConst(*args[arg_num].column))
throw Exception("Argument at index " + toString(arg_num) + " for function " + getName() + " must be constant", ErrorCodes::ILLEGAL_COLUMN);
if (args.empty() || !impl->useDefaultImplementationForConstants() || !allArgumentsAreConstants(columns, args))
return false;
if (args.empty() || !impl->useDefaultImplementationForConstants() || !allArgumentsAreConstants(args))
return nullptr;
ColumnsWithTypeAndName temporary_columns;
bool have_converted_columns = false;
size_t arguments_size = args.size();
temporary_columns.reserve(arguments_size);
for (size_t arg_num = 0; arg_num < arguments_size; ++arg_num)
{
const ColumnWithTypeAndName & column = columns[args[arg_num]];
const ColumnWithTypeAndName & column = args[arg_num];
if (arguments_to_remain_constants.end() != std::find(arguments_to_remain_constants.begin(), arguments_to_remain_constants.end(), arg_num))
{
@ -255,80 +236,72 @@ bool ExecutableFunctionAdaptor::defaultImplementationForConstantArguments(
throw Exception("Number of arguments for function " + getName() + " doesn't match: the function requires more arguments",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
temporary_columns.emplace_back(columns[result]);
ColumnPtr result_column = executeWithoutLowCardinalityColumns(temporary_columns, result_type, 1, dry_run);
ColumnNumbers temporary_argument_numbers(arguments_size);
for (size_t i = 0; i < arguments_size; ++i)
temporary_argument_numbers[i] = i;
executeWithoutLowCardinalityColumns(temporary_columns, temporary_argument_numbers, arguments_size, 1, dry_run);
ColumnPtr result_column;
/// extremely rare case, when we have function with completely const arguments
/// but some of them produced by non isDeterministic function
if (temporary_columns[arguments_size].column->size() > 1)
result_column = temporary_columns[arguments_size].column->cloneResized(1);
else
result_column = temporary_columns[arguments_size].column;
if (result_column->size() > 1)
result_column = result_column->cloneResized(1);
columns[result].column = ColumnConst::create(result_column, input_rows_count);
return true;
return ColumnConst::create(result_column, input_rows_count);
}
bool ExecutableFunctionAdaptor::defaultImplementationForNulls(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run)
ColumnPtr ExecutableFunctionAdaptor::defaultImplementationForNulls(ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run)
{
if (args.empty() || !impl->useDefaultImplementationForNulls())
return false;
return nullptr;
NullPresence null_presence = getNullPresense(columns, args);
NullPresence null_presence = getNullPresense(args);
if (null_presence.has_null_constant)
{
auto & result_column = columns[result].column;
auto result_type = columns[result].type;
// Default implementation for nulls returns null result for null arguments,
// so the result type must be nullable.
assert(result_type->isNullable());
result_column = result_type->createColumnConstWithDefaultValue(input_rows_count);
return true;
return result_type->createColumnConstWithDefaultValue(input_rows_count);
}
if (null_presence.has_nullable)
{
ColumnsWithTypeAndName temporary_columns = createBlockWithNestedColumns(columns, args, result);
executeWithoutLowCardinalityColumns(temporary_columns, args, result, input_rows_count, dry_run);
columns[result].column = wrapInNullable(temporary_columns[result].column, columns, args, result, input_rows_count);
return true;
ColumnsWithTypeAndName temporary_columns = createBlockWithNestedColumns(args);
auto temporary_result_type = removeNullable(result_type);
auto res = executeWithoutLowCardinalityColumns(temporary_columns, temporary_result_type, input_rows_count, dry_run);
return wrapInNullable(res, args, result_type, input_rows_count);
}
return false;
return nullptr;
}
void ExecutableFunctionAdaptor::executeWithoutLowCardinalityColumns(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run)
ColumnPtr ExecutableFunctionAdaptor::executeWithoutLowCardinalityColumns(
ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run)
{
if (defaultImplementationForConstantArguments(columns, args, result, input_rows_count, dry_run))
return;
if (auto res = defaultImplementationForConstantArguments(args, result_type, input_rows_count, dry_run))
return res;
if (defaultImplementationForNulls(columns, args, result, input_rows_count, dry_run))
return;
if (auto res = defaultImplementationForNulls(args, result_type, input_rows_count, dry_run))
return res;
ColumnPtr res;
if (dry_run)
impl->executeDryRun(columns, args, result, input_rows_count);
res = impl->executeDryRun(args, result_type, input_rows_count);
else
impl->execute(columns, args, result, input_rows_count);
res = impl->execute(args, result_type, input_rows_count);
if (!res)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Empty column was returned by function {}", getName());
return res;
}
static const ColumnLowCardinality * findLowCardinalityArgument(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args)
static const ColumnLowCardinality * findLowCardinalityArgument(const ColumnsWithTypeAndName & arguments)
{
const ColumnLowCardinality * result_column = nullptr;
for (auto arg : args)
for (const auto & column : arguments)
{
const ColumnWithTypeAndName & column = columns[arg];
if (const auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
{
if (result_column)
@ -342,15 +315,14 @@ static const ColumnLowCardinality * findLowCardinalityArgument(const ColumnsWith
}
static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, bool can_be_executed_on_default_arguments, size_t input_rows_count)
ColumnsWithTypeAndName & args, bool can_be_executed_on_default_arguments, size_t input_rows_count)
{
size_t num_rows = input_rows_count;
ColumnPtr indexes;
/// Find first LowCardinality column and replace it to nested dictionary.
for (auto arg : args)
for (auto & column : args)
{
ColumnWithTypeAndName & column = columns[arg];
if (const auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
{
/// Single LowCardinality column is supported now.
@ -384,9 +356,8 @@ static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
}
/// Change size of constants.
for (auto arg : args)
for (auto & column : args)
{
ColumnWithTypeAndName & column = columns[arg];
if (const auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
{
column.column = column_const->removeLowCardinality()->cloneResized(num_rows);
@ -397,41 +368,24 @@ static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
return indexes;
}
static void convertLowCardinalityColumnsToFull(ColumnsWithTypeAndName & columns, const ColumnNumbers & args)
static void convertLowCardinalityColumnsToFull(ColumnsWithTypeAndName & args)
{
for (auto arg : args)
for (auto & column : args)
{
ColumnWithTypeAndName & column = columns[arg];
column.column = recursiveRemoveLowCardinality(column.column);
column.type = recursiveRemoveLowCardinality(column.type);
}
}
static ColumnsWithTypeAndName cloneWithEmptyColumns(const ColumnsWithTypeAndName & columns)
{
ColumnsWithTypeAndName res;
size_t num_columns = columns.size();
for (size_t i = 0; i < num_columns; ++i)
res.emplace_back(ColumnWithTypeAndName{ nullptr, columns[i].type, columns[i].name });
return res;
}
void ExecutableFunctionAdaptor::execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count, bool dry_run)
ColumnPtr ExecutableFunctionAdaptor::execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run)
{
if (impl->useDefaultImplementationForLowCardinalityColumns())
{
auto & res = columns[result];
ColumnsWithTypeAndName columns_without_low_cardinality = cloneWithEmptyColumns(columns);
ColumnsWithTypeAndName columns_without_low_cardinality = arguments;
for (auto arg : arguments)
columns_without_low_cardinality[arg].column = columns[arg].column;
if (const auto * res_low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(res.type.get()))
if (const auto * res_low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(result_type.get()))
{
const auto * low_cardinality_column = findLowCardinalityArgument(columns, arguments);
const auto * low_cardinality_column = findLowCardinalityArgument(arguments);
bool can_be_executed_on_default_arguments = impl->canBeExecutedOnDefaultArguments();
bool use_cache = low_cardinality_result_cache && can_be_executed_on_default_arguments
&& low_cardinality_column && low_cardinality_column->isSharedDictionary();
@ -446,22 +400,20 @@ void ExecutableFunctionAdaptor::execute(ColumnsWithTypeAndName & columns, const
if (cached_values)
{
auto indexes = cached_values->index_mapping->index(low_cardinality_column->getIndexes(), 0);
res.column = ColumnLowCardinality::create(cached_values->function_result, indexes, true);
return;
return ColumnLowCardinality::create(cached_values->function_result, indexes, true);
}
}
columns_without_low_cardinality[result].type = res_low_cardinality_type->getDictionaryType();
const auto & dictionary_type = res_low_cardinality_type->getDictionaryType();
ColumnPtr indexes = replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
columns_without_low_cardinality, arguments, can_be_executed_on_default_arguments, input_rows_count);
columns_without_low_cardinality, can_be_executed_on_default_arguments, input_rows_count);
size_t new_input_rows_count = arguments.empty()
size_t new_input_rows_count = columns_without_low_cardinality.empty()
? input_rows_count
: columns_without_low_cardinality[arguments.front()].column->size();
: columns_without_low_cardinality.front().column->size();
executeWithoutLowCardinalityColumns(columns_without_low_cardinality, arguments, result, new_input_rows_count, dry_run);
auto keys = columns_without_low_cardinality[result].column->convertToFullColumnIfConst();
auto res = executeWithoutLowCardinalityColumns(columns_without_low_cardinality, dictionary_type, new_input_rows_count, dry_run);
auto keys = res->convertToFullColumnIfConst();
auto res_mut_dictionary = DataTypeLowCardinality::createColumnUnique(*res_low_cardinality_type->getDictionaryType());
ColumnPtr res_indexes = res_mut_dictionary->uniqueInsertRangeFrom(*keys, 0, keys->size());
@ -481,22 +433,21 @@ void ExecutableFunctionAdaptor::execute(ColumnsWithTypeAndName & columns, const
res_indexes = cache_values->index_mapping;
}
res.column = ColumnLowCardinality::create(res_dictionary, res_indexes->index(*indexes, 0), use_cache);
return ColumnLowCardinality::create(res_dictionary, res_indexes->index(*indexes, 0), use_cache);
}
else
{
res.column = ColumnLowCardinality::create(res_dictionary, res_indexes);
return ColumnLowCardinality::create(res_dictionary, res_indexes);
}
}
else
{
convertLowCardinalityColumnsToFull(columns_without_low_cardinality, arguments);
executeWithoutLowCardinalityColumns(columns_without_low_cardinality, arguments, result, input_rows_count, dry_run);
res.column = columns_without_low_cardinality[result].column;
convertLowCardinalityColumnsToFull(columns_without_low_cardinality);
return executeWithoutLowCardinalityColumns(columns_without_low_cardinality, result_type, input_rows_count, dry_run);
}
}
else
executeWithoutLowCardinalityColumns(columns, arguments, result, input_rows_count, dry_run);
return executeWithoutLowCardinalityColumns(arguments, result_type, input_rows_count, dry_run);
}
void FunctionOverloadResolverAdaptor::checkNumberOfArguments(size_t number_of_arguments) const
@ -526,9 +477,7 @@ DataTypePtr FunctionOverloadResolverAdaptor::getReturnTypeWithoutLowCardinality(
}
if (null_presence.has_nullable)
{
Block nested_columns = createBlockWithNestedColumns(
arguments,
ext::collection_cast<ColumnNumbers>(ext::range(0, arguments.size())));
Block nested_columns = createBlockWithNestedColumns(arguments);
auto return_type = impl->getReturnType(ColumnsWithTypeAndName(nested_columns.begin(), nested_columns.end()));
return makeNullable(return_type);
}

View File

@ -46,7 +46,7 @@ public:
/// Get the main function name.
virtual String getName() const = 0;
virtual void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count, bool dry_run) = 0;
virtual ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run) = 0;
virtual void createLowCardinalityResultCache(size_t cache_size) = 0;
};
@ -67,16 +67,16 @@ public:
virtual String getName() const = 0;
virtual const DataTypes & getArgumentTypes() const = 0;
virtual const DataTypePtr & getReturnType() const = 0;
virtual const DataTypePtr & getResultType() const = 0;
/// Do preparations and return executable.
/// sample_columns should contain data types of arguments and values of constants, if relevant.
virtual ExecutableFunctionPtr prepare(const ColumnsWithTypeAndName & sample_columns, const ColumnNumbers & arguments, size_t result) const = 0;
virtual ExecutableFunctionPtr prepare(const ColumnsWithTypeAndName & arguments) const = 0;
/// TODO: make const
virtual void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count, bool dry_run = false)
virtual ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run = false)
{
return prepare(columns, arguments, result)->execute(columns, arguments, result, input_rows_count, dry_run);
return prepare(arguments)->execute(arguments, result_type, input_rows_count, dry_run);
}
#if USE_EMBEDDED_COMPILER
@ -111,7 +111,7 @@ public:
* There is no need to implement function if it has zero arguments.
* Must return ColumnConst with single row or nullptr.
*/
virtual ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) const { return nullptr; }
virtual ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & /*columns*/) const { return nullptr; }
/** Function is called "injective" if it returns different result for different values of arguments.
* Example: hex, negate, tuple...
@ -226,9 +226,9 @@ public:
using FunctionOverloadResolverPtr = std::shared_ptr<IFunctionOverloadResolver>;
/** Return ColumnNullable of src, with null map as OR-ed null maps of args columns in columnss.
/** Return ColumnNullable of src, with null map as OR-ed null maps of args columns.
* Or ColumnConst(ColumnNullable) if the result is always NULL or if the result is constant and always not NULL.
*/
ColumnPtr wrapInNullable(const ColumnPtr & src, const ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count);
ColumnPtr wrapInNullable(const ColumnPtr & src, const ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count);
}

View File

@ -14,7 +14,7 @@ public:
String getName() const final { return impl->getName(); }
void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count, bool dry_run) final;
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run) final;
void createLowCardinalityResultCache(size_t cache_size) override;
@ -24,14 +24,14 @@ private:
/// Cache is created by function createLowCardinalityResultCache()
ExecutableFunctionLowCardinalityResultCachePtr low_cardinality_result_cache;
bool defaultImplementationForConstantArguments(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run);
ColumnPtr defaultImplementationForConstantArguments(
ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run);
bool defaultImplementationForNulls(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run);
ColumnPtr defaultImplementationForNulls(
ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run);
void executeWithoutLowCardinalityColumns(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run);
ColumnPtr executeWithoutLowCardinalityColumns(
ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run);
};
class FunctionBaseAdaptor final : public IFunctionBase
@ -42,12 +42,11 @@ public:
String getName() const final { return impl->getName(); }
const DataTypes & getArgumentTypes() const final { return impl->getArgumentTypes(); }
const DataTypePtr & getReturnType() const final { return impl->getReturnType(); }
const DataTypePtr & getResultType() const final { return impl->getResultType(); }
ExecutableFunctionPtr prepare(const ColumnsWithTypeAndName & sample_columns, const ColumnNumbers & arguments, size_t result) const final
ExecutableFunctionPtr prepare(const ColumnsWithTypeAndName & arguments) const final
{
ColumnsWithTypeAndName columns(const_cast<ColumnsWithTypeAndName &>(sample_columns));
return std::make_shared<ExecutableFunctionAdaptor>(impl->prepare(columns, arguments, result));
return std::make_shared<ExecutableFunctionAdaptor>(impl->prepare(arguments));
}
#if USE_EMBEDDED_COMPILER
@ -64,9 +63,9 @@ public:
bool isStateful() const final { return impl->isStateful(); }
bool isSuitableForConstantFolding() const final { return impl->isSuitableForConstantFolding(); }
ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments) const final
ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & arguments) const final
{
return impl->getResultIfAlwaysReturnsConstantAndHasArguments(columns, arguments);
return impl->getResultIfAlwaysReturnsConstantAndHasArguments(arguments);
}
bool isInjective(const ColumnsWithTypeAndName & sample_columns) const final { return impl->isInjective(sample_columns); }
@ -148,13 +147,13 @@ public:
String getName() const override { return function->getName(); }
protected:
void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) final
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) final
{
return function->executeImpl(columns, arguments, result, input_rows_count);
return function->executeImpl(arguments, result_type, input_rows_count);
}
void executeDryRun(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) final
ColumnPtr executeDryRun(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) final
{
return function->executeImplDryRun(columns, arguments, result, input_rows_count);
return function->executeImplDryRun(arguments, result_type, input_rows_count);
}
bool useDefaultImplementationForNulls() const final { return function->useDefaultImplementationForNulls(); }
bool useDefaultImplementationForConstants() const final { return function->useDefaultImplementationForConstants(); }
@ -169,31 +168,31 @@ private:
class DefaultFunction final : public IFunctionBaseImpl
{
public:
DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, DataTypePtr return_type_)
: function(std::move(function_)), arguments(std::move(arguments_)), return_type(std::move(return_type_)) {}
DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, DataTypePtr result_type_)
: function(std::move(function_)), arguments(std::move(arguments_)), result_type(std::move(result_type_)) {}
String getName() const override { return function->getName(); }
const DataTypes & getArgumentTypes() const override { return arguments; }
const DataTypePtr & getReturnType() const override { return return_type; }
const DataTypePtr & getResultType() const override { return result_type; }
#if USE_EMBEDDED_COMPILER
bool isCompilable() const override { return function->isCompilable(arguments); }
bool isCompilable() const override { return function->isCompilable(getArgumentTypes()); }
llvm::Value * compile(llvm::IRBuilderBase & builder, ValuePlaceholders values) const override { return function->compile(builder, arguments, std::move(values)); }
llvm::Value * compile(llvm::IRBuilderBase & builder, ValuePlaceholders values) const override { return function->compile(builder, getArgumentTypes(), std::move(values)); }
#endif
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & /*sample_columns*/, const ColumnNumbers & /*arguments*/, size_t /*result*/) const override
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & /*arguments*/) const override
{
return std::make_unique<DefaultExecutable>(function);
}
bool isSuitableForConstantFolding() const override { return function->isSuitableForConstantFolding(); }
ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments_) const override
ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & arguments_) const override
{
return function->getResultIfAlwaysReturnsConstantAndHasArguments(columns, arguments_);
return function->getResultIfAlwaysReturnsConstantAndHasArguments(arguments_);
}
bool isStateful() const override { return function->isStateful(); }
@ -214,7 +213,7 @@ public:
private:
std::shared_ptr<IFunction> function;
DataTypes arguments;
DataTypePtr return_type;
DataTypePtr result_type;
};
class DefaultOverloadResolver : public IFunctionOverloadResolverImpl
@ -244,12 +243,12 @@ public:
bool useDefaultImplementationForLowCardinalityColumns() const override { return function->useDefaultImplementationForLowCardinalityColumns(); }
bool canBeExecutedOnLowCardinalityDictionary() const override { return function->canBeExecutedOnLowCardinalityDictionary(); }
FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type) const override
FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) const override
{
DataTypes data_types(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i)
data_types[i] = arguments[i].type;
return std::make_unique<DefaultFunction>(function, data_types, return_type);
return std::make_unique<DefaultFunction>(function, data_types, result_type);
}
void getLambdaArgumentTypes(DataTypes & arguments) const override { function->getLambdaArgumentTypes(arguments); }

View File

@ -35,10 +35,10 @@ public:
virtual String getName() const = 0;
virtual void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) = 0;
virtual void executeDryRun(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count)
virtual ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) = 0;
virtual ColumnPtr executeDryRun(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count)
{
execute(columns, arguments, result, input_rows_count);
return execute(arguments, result_type, input_rows_count);
}
/** Default implementation in presence of Nullable arguments or NULL constants as arguments is the following:
@ -87,9 +87,9 @@ public:
virtual String getName() const = 0;
virtual const DataTypes & getArgumentTypes() const = 0;
virtual const DataTypePtr & getReturnType() const = 0;
virtual const DataTypePtr & getResultType() const = 0;
virtual ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & sample_columns, const ColumnNumbers & arguments, size_t result) const = 0;
virtual ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & arguments) const = 0;
#if USE_EMBEDDED_COMPILER
@ -105,7 +105,7 @@ public:
virtual bool isStateful() const { return false; }
virtual bool isSuitableForConstantFolding() const { return true; }
virtual ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) const { return nullptr; }
virtual ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & /*arguments*/) const { return nullptr; }
virtual bool isInjective(const ColumnsWithTypeAndName & /*sample_columns*/) const { return false; }
virtual bool isDeterministic() const { return true; }
@ -130,7 +130,7 @@ public:
virtual String getName() const = 0;
virtual FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type) const = 0;
virtual FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) const = 0;
virtual DataTypePtr getReturnType(const DataTypes & /*arguments*/) const
{
@ -197,10 +197,10 @@ public:
virtual String getName() const = 0;
virtual void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const = 0;
virtual void executeImplDryRun(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
virtual ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const = 0;
virtual ColumnPtr executeImplDryRun(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
executeImpl(columns, arguments, result, input_rows_count);
return executeImpl(arguments, result_type, input_rows_count);
}
/** Default implementation in presence of Nullable arguments or NULL constants as arguments is the following:
@ -252,7 +252,7 @@ public:
/// Properties from IFunctionBase (see IFunction.h)
virtual bool isSuitableForConstantFolding() const { return true; }
virtual ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) const { return nullptr; }
virtual ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const ColumnsWithTypeAndName & /*arguments*/) const { return nullptr; }
virtual bool isInjective(const ColumnsWithTypeAndName & /*sample_columns*/) const { return false; }
virtual bool isDeterministic() const { return true; }
virtual bool isDeterministicInScopeOfQuery() const { return true; }

View File

@ -46,20 +46,15 @@ private:
return 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 & result_type, size_t input_rows_count) const override
{
size_t num_arguments = arguments.size();
if (1 == num_arguments)
{
columns[result].column = columns[arguments[0]].column;
return;
}
auto result_type = columns[result].type;
return arguments[0].column;
Columns converted_columns(num_arguments);
for (size_t arg = 0; arg < num_arguments; ++arg)
converted_columns[arg] = castColumn(columns[arguments[arg]], result_type)->convertToFullColumnIfConst();
converted_columns[arg] = castColumn(arguments[arg], result_type)->convertToFullColumnIfConst();
auto result_column = result_type->createColumn();
result_column->reserve(input_rows_count);
@ -86,7 +81,7 @@ private:
result_column->insertFrom(*converted_columns[best_arg], row_num);
}
columns[result].column = std::move(result_column);
return result_column;
}
};

View File

@ -204,7 +204,7 @@ public:
* If FunctionInterface is IFunction, then "executeImpl" method of the implementation will be called
* and "execute" otherwise.
*/
void selectAndExecute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
ColumnPtr selectAndExecute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{
if (implementations.empty())
throw Exception("There are no available implementations for function " "TODO(dakovalkov): add name",
@ -212,14 +212,15 @@ public:
/// Statistics shouldn't rely on small columnss.
bool considerable = (input_rows_count > 1000);
ColumnPtr res;
size_t id = statistics.select(considerable);
Stopwatch watch;
if constexpr (std::is_same_v<FunctionInterface, IFunction>)
implementations[id]->executeImpl(columns, arguments, result, input_rows_count);
res = implementations[id]->executeImpl(arguments, result_type, input_rows_count);
else
implementations[id]->execute(columns, arguments, result, input_rows_count);
res = implementations[id]->execute(arguments, result_type, input_rows_count);
watch.stop();
@ -228,6 +229,8 @@ public:
// TODO(dakovalkov): Calculate something more informative than rows count.
statistics.complete(id, watch.elapsedSeconds(), input_rows_count);
}
return res;
}
/* Register new implementation for function.

View File

@ -29,7 +29,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
void init(ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) {}
void init(ColumnsWithTypeAndName & /*arguments*/) {}
/// Returns the position of the argument that is the column of rows
static size_t getStringsArgumentPosition()

View File

@ -28,7 +28,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
void init(ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) {}
void init(ColumnsWithTypeAndName & /*arguments*/) {}
/// Returns the position of the argument that is the column of rows
static size_t getStringsArgumentPosition()

View File

@ -34,7 +34,7 @@ public:
return 0;
}
void init(ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) {}
void init(ColumnsWithTypeAndName & /*arguments*/) {}
/// Called for each next string.
void set(Pos pos_, Pos end_)

View File

@ -28,7 +28,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
void init(ColumnsWithTypeAndName & /*columns*/, const ColumnNumbers & /*arguments*/) {}
void init(ColumnsWithTypeAndName & /*arguments*/) {}
/// Returns the position of the argument that is the column of rows
static size_t getStringsArgumentPosition()

View File

@ -48,18 +48,18 @@ struct FunctionPort : public IFunction
}
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override
{
UInt16 default_port = 0;
if (arguments.size() == 2)
{
const auto * port_column = checkAndGetColumn<ColumnConst>(columns[arguments[1]].column.get());
const auto * port_column = checkAndGetColumn<ColumnConst>(arguments[1].column.get());
if (!port_column)
throw Exception("Second argument for function " + getName() + " must be constant UInt16", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
default_port = port_column->getValue<UInt16>();
}
const ColumnPtr url_column = columns[arguments[0]].column;
const ColumnPtr url_column = arguments[0].column;
if (const ColumnString * url_strs = checkAndGetColumn<ColumnString>(url_column.get()))
{
auto col_res = ColumnVector<UInt16>::create();
@ -67,11 +67,11 @@ struct FunctionPort : public IFunction
vec_res.resize(url_column->size());
vector(default_port, url_strs->getChars(), url_strs->getOffsets(), vec_res);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception(
"Illegal column " + columns[arguments[0]].column->getName() + " of argument of function " + getName(),
"Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN);
}

View File

@ -216,20 +216,17 @@ public:
return true;
}
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 (input_rows_count == 0)
{
columns[result].column = ColumnString::create();
return;
}
return ColumnString::create();
PODArray<Float64> xs, ys;
PODArray<String> variant_names;
String dist;
bool higher_is_better;
if (const ColumnConst * col_dist = checkAndGetColumnConst<ColumnString>(columns[arguments[0]].column.get()))
if (const ColumnConst * col_dist = checkAndGetColumnConst<ColumnString>(arguments[0].column.get()))
{
dist = col_dist->getDataAt(0).data;
dist = Poco::toLower(dist);
@ -239,16 +236,13 @@ public:
else
throw Exception("First argument for function " + getName() + " must be Constant string", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (const ColumnConst * col_higher_is_better = checkAndGetColumnConst<ColumnUInt8>(columns[arguments[1]].column.get()))
if (const ColumnConst * col_higher_is_better = checkAndGetColumnConst<ColumnUInt8>(arguments[1].column.get()))
higher_is_better = col_higher_is_better->getBool(0);
else
throw Exception("Second argument for function " + getName() + " must be Constatnt boolean", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(columns[arguments[2]].column.get()))
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arguments[2].column.get()))
{
if (!col_const_arr)
throw Exception("Third argument for function " + getName() + " must be Array of constant strings", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
Array src_arr = col_const_arr->getValue<Array>();
for (size_t i = 0; i < src_arr.size(); ++i)
@ -258,22 +252,24 @@ public:
variant_names.push_back(src_arr[i].get<const String &>());
}
}
else
throw Exception("Third argument for function " + getName() + " must be Array of constant strings", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(columns[arguments[3]].column.get()))
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arguments[3].column.get()))
{
if (!col_const_arr)
throw Exception("Forth argument for function " + getName() + " must be Array of constant numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (!toFloat64(col_const_arr, xs))
throw Exception("Forth and fifth Argument for function " + getName() + " must be Array of constant Numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
else
throw Exception("Forth argument for function " + getName() + " must be Array of constant numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(columns[arguments[4]].column.get()))
if (const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arguments[4].column.get()))
{
if (!col_const_arr)
throw Exception("Fifth argument for function " + getName() + " must be Array of constant numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (!toFloat64(col_const_arr, ys))
throw Exception("Fifth Argument for function " + getName() + " must be Array of constant Numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
else
throw Exception("Fifth argument for function " + getName() + " must be Array of constant numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (variant_names.size() != xs.size() || xs.size() != ys.size())
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Sizes of arguments doesn't match: variant_names: {}, xs: {}, ys: {}", variant_names.size(), xs.size(), ys.size());
@ -294,7 +290,7 @@ public:
auto dst = ColumnString::create();
std::string result_str = convertToJson(variant_names, variants);
dst->insertData(result_str.c_str(), result_str.length());
columns[result].column = std::move(dst);
return dst;
}
};

View File

@ -72,9 +72,9 @@ public:
return true;
}
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
{
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get());
if (!column_concrete)
@ -89,7 +89,7 @@ public:
result_column->insertData(res_str.data, res_str.size);
}
columns[result].column = std::move(result_column);
return result_column;
}
private:

View File

@ -64,11 +64,11 @@ public:
return true;
}
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
{
const SymbolIndex & symbol_index = SymbolIndex::instance();
const ColumnPtr & column = columns[arguments[0]].column;
const ColumnPtr & column = arguments[0].column;
const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get());
if (!column_concrete)
@ -85,7 +85,7 @@ public:
result_column->insertDefault();
}
columns[result].column = std::move(result_column);
return result_column;
}
};

View File

@ -55,10 +55,10 @@ private:
bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {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
{
const auto & column = columns[arguments[0]].column;
const auto & column_char = columns[arguments[1]].column;
const auto & column = arguments[0].column;
const auto & column_char = arguments[1].column;
if (!checkColumnConst<ColumnString>(column_char.get()))
throw Exception{"Second argument of function " + getName() + " must be a constant string", ErrorCodes::ILLEGAL_COLUMN};
@ -103,10 +103,10 @@ private:
}
dst_data.resize_assume_reserved(dst_offset);
columns[result].column = std::move(col_res);
return col_res;
}
else
throw Exception{"Illegal column " + columns[arguments[0]].column->getName() + " of argument of function " + getName(),
throw Exception{"Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN};
}
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -396,9 +396,9 @@ public:
* (they are vectors of Fields, which may represent the NULL value),
* they do not require any preprocessing.
*/
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const override
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override
{
ColumnPtr& ptr = columns[arguments[0]].column;
ColumnPtr& ptr = arguments[0].column;
/**
* The columns here have two general cases, either being Array(T) or Const(Array(T)).
@ -411,11 +411,11 @@ public:
if (col_array)
nullable = checkAndGetColumn<ColumnNullable>(col_array->getData());
auto & arg_column = columns[arguments[1]].column;
auto & arg_column = arguments[1].column;
const ColumnNullable * arg_nullable = checkAndGetColumn<ColumnNullable>(*arg_column);
if (!nullable && !arg_nullable)
executeOnNonNullable(columns, arguments, result);
return executeOnNonNullable(arguments, result_type);
else
{
/**
@ -424,7 +424,7 @@ public:
* {0, 1, 2, 3, 4}
* {data (array) argument, "value" argument, data null map, "value" null map, function result}.
*/
ColumnsWithTypeAndName source_columns = { {}, {}, {}, {}, {nullptr, columns[result].type, ""} };
ColumnsWithTypeAndName source_columns(4);
if (nullable)
{
@ -436,7 +436,7 @@ public:
data.type = std::make_shared<DataTypeArray>(
static_cast<const DataTypeNullable &>(
*static_cast<const DataTypeArray &>(
*columns[arguments[0]].type
*arguments[0].type
).getNestedType()
).getNestedType());
@ -448,7 +448,7 @@ public:
else
{
auto & data = source_columns[0];
data = columns[arguments[0]];
data = arguments[0];
}
if (arg_nullable)
@ -457,7 +457,7 @@ public:
arg.column = arg_nullable->getNestedColumnPtr();
arg.type =
static_cast<const DataTypeNullable &>(
*columns[arguments[1]].type
*arguments[1].type
).getNestedType();
auto & null_map = source_columns[3];
@ -467,16 +467,11 @@ public:
else
{
auto & arg = source_columns[1];
arg = columns[arguments[1]];
arg = arguments[1];
}
/// Now perform the function.
executeOnNonNullable(source_columns, {0, 1, 2, 3}, 4);
/// Move the result to its final position.
const ColumnWithTypeAndName & source_col = source_columns[4];
ColumnWithTypeAndName & dest_col = columns[result];
dest_col.column = std::move(source_col.column);
return executeOnNonNullable(source_columns, result_type);
}
}
@ -492,12 +487,11 @@ private:
const IColumn& left;
const IColumn& right;
const ColumnArray::Offsets& offsets;
ColumnsWithTypeAndName & columns;
size_t result_pos;
ColumnPtr result_column;
NullMaps maps;
ResultColumnPtr result { ResultColumnType::create() };
inline void moveResult() { columns[result_pos].column = std::move(result); }
inline void moveResult() { result_column = std::move(result); }
};
static inline bool allowNested(const DataTypePtr & left, const DataTypePtr & right)
@ -584,14 +578,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(),
@ -599,13 +593,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;
}
/**
@ -619,7 +616,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};
@ -627,10 +624,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};
@ -642,26 +639,28 @@ 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 ColumnPtr right_converted_ptr = columns[arguments[1]].column->convertToFullColumnIfLowCardinality();
const ColumnPtr right_converted_ptr = arguments[1].column->convertToFullColumnIfLowCardinality();
const IColumn& right = *right_converted_ptr.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;
return nullptr;
}
template <class ...Integral>
@ -733,22 +732,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))
{
@ -764,12 +762,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);
@ -788,8 +785,7 @@ private:
data.resize_fill(offsets_size);
columns[result].column = std::move(col_result);
return true;
return col_result;
}
}
@ -801,8 +797,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
{
@ -827,19 +822,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))
@ -848,11 +844,14 @@ 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;
}
return nullptr;
}
static bool dispatchConvertedLCColumns(ExecutionData& data)
@ -875,28 +874,31 @@ 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 ColumnPtr right_ptr = columns[arguments[1]].column->convertToFullColumnIfLowCardinality();
const ColumnPtr right_ptr = arguments[1].column->convertToFullColumnIfLowCardinality();
const IColumn & right = *right_ptr.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)
@ -961,17 +963,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 ColumnPtr right_ptr = columns[arguments[1]].column->convertToFullColumnIfLowCardinality();
const ColumnPtr right_ptr = arguments[1].column->convertToFullColumnIfLowCardinality();
const IColumn * item_arg = right_ptr.get();
if (isColumnConst(*item_arg))
@ -990,8 +991,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
{
@ -999,7 +999,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();
@ -1033,27 +1033,25 @@ 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 ColumnPtr right_ptr = columns[arguments[1]].column->convertToFullColumnIfLowCardinality();
const ColumnPtr right_ptr = arguments[1].column->convertToFullColumnIfLowCardinality();
const IColumn & item_arg = *right_ptr.get();
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(
@ -1077,8 +1075,7 @@ private:
null_map_data,
null_map_item);
columns[result].column = std::move(col_res);
return true;
return col_res;
}
};
}

View File

@ -48,7 +48,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
bool useDefaultImplementationForConstants() const override { return true; }
@ -88,7 +88,7 @@ private:
ColumnsWithTypeAndName casted;
};
static CastArgumentsResult castColumns(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments,
static CastArgumentsResult castColumns(ColumnsWithTypeAndName & arguments,
const DataTypePtr & return_type, const DataTypePtr & return_type_with_nulls);
UnpackedArrays prepareArrays(const ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & initial_columns) const;
@ -206,8 +206,7 @@ ColumnPtr FunctionArrayIntersect::castRemoveNullable(const ColumnPtr & column, c
}
FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, const DataTypePtr & return_type,
const DataTypePtr & return_type_with_nulls)
ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, const DataTypePtr & return_type_with_nulls)
{
size_t num_args = arguments.size();
ColumnsWithTypeAndName initial_columns(num_args);
@ -233,7 +232,7 @@ FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
for (size_t i = 0; i < num_args; ++i)
{
const ColumnWithTypeAndName & arg = columns[arguments[i]];
const ColumnWithTypeAndName & arg = arguments[i];
initial_columns[i] = arg;
casted_columns[i] = arg;
auto & column = casted_columns[i];
@ -284,18 +283,9 @@ FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
static ColumnPtr callFunctionNotEquals(ColumnWithTypeAndName first, ColumnWithTypeAndName second, const Context & context)
{
ColumnsWithTypeAndName args;
args.reserve(2);
args.emplace_back(std::move(first));
args.emplace_back(std::move(second));
ColumnsWithTypeAndName args{first, second};
auto eq_func = FunctionFactory::instance().get("notEquals", context)->build(args);
args.emplace_back(ColumnWithTypeAndName{nullptr, eq_func->getReturnType(), ""});
eq_func->execute(args, {0, 1}, 2, args.front().column->size());
return args[2].column;
return eq_func->execute(args, eq_func->getResultType(), args.front().column->size());
}
FunctionArrayIntersect::UnpackedArrays FunctionArrayIntersect::prepareArrays(
@ -383,10 +373,9 @@ 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 & result_type, size_t input_rows_count) const
{
const auto & return_type = columns[result].type;
const auto * return_type_array = checkAndGetDataType<DataTypeArray>(return_type.get());
const auto * return_type_array = checkAndGetDataType<DataTypeArray>(result_type.get());
if (!return_type_array)
throw Exception{"Return type for function " + getName() + " must be array.", ErrorCodes::LOGICAL_ERROR};
@ -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 result_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, result_type, return_type_with_nulls);
UnpackedArrays arrays = prepareArrays(casted_columns.casted, casted_columns.initial);
@ -442,11 +428,11 @@ void FunctionArrayIntersect::executeImpl(ColumnsWithTypeAndName & columns, const
else
{
column = assert_cast<const DataTypeArray &>(*return_type_with_nulls).getNestedType()->createColumn();
result_column = castRemoveNullable(execute<StringMap, IColumn, false>(arrays, std::move(column)), return_type);
result_column = castRemoveNullable(execute<StringMap, IColumn, false>(arrays, std::move(column)), result_type);
}
}
columns[result].column = std::move(result_column);
return result_column;
}
template <typename T, size_t>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More