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( void LinearModelData::predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const Context & context) const 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 void LinearModelData::returnWeights(IColumn & to) const
@ -449,15 +448,14 @@ void IWeightsUpdater::addToBatch(
void LogisticRegression::predict( void LogisticRegression::predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
Float64 bias, Float64 bias,
const Context & /*context*/) const 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) if (offset > rows_num || offset + limit > rows_num)
throw Exception("Invalid offset and limit for LogisticRegression::predict. " 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) 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)) if (!isNativeNumber(cur_col.type))
throw Exception("Prediction arguments must have numeric type", ErrorCodes::BAD_ARGUMENTS); throw Exception("Prediction arguments must have numeric type", ErrorCodes::BAD_ARGUMENTS);
@ -518,10 +516,9 @@ void LogisticRegression::compute(
void LinearRegression::predict( void LinearRegression::predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
Float64 bias, Float64 bias,
const Context & /*context*/) const 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); 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) if (offset > rows_num || offset + limit > rows_num)
throw Exception("Invalid offset and limit for LogisticRegression::predict. " 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) 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)) if (!isNativeNumber(cur_col.type))
throw Exception("Prediction arguments must have numeric type", ErrorCodes::BAD_ARGUMENTS); throw Exception("Prediction arguments must have numeric type", ErrorCodes::BAD_ARGUMENTS);

View File

@ -39,10 +39,9 @@ public:
virtual void predict( virtual void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
Float64 bias, Float64 bias,
const Context & context) const = 0; const Context & context) const = 0;
@ -65,10 +64,9 @@ public:
void predict( void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
Float64 bias, Float64 bias,
const Context & context) const override; const Context & context) const override;
@ -91,10 +89,9 @@ public:
void predict( void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
Float64 bias, Float64 bias,
const Context & context) const override; const Context & context) const override;
@ -264,10 +261,9 @@ public:
void predict( void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const Context & context) const; const Context & context) const;
void returnWeights(IColumn & to) const; void returnWeights(IColumn & to) const;
@ -364,10 +360,9 @@ public:
void predictValues( void predictValues(
ConstAggregateDataPtr place, ConstAggregateDataPtr place,
IColumn & to, IColumn & to,
ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const ColumnNumbers & arguments,
const Context & context) const override const Context & context) const override
{ {
if (arguments.size() != param_num + 1) 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", throw Exception("Cast of column of predictions is incorrect. getReturnTypeToPredict must return same value as it is casted to",
ErrorCodes::LOGICAL_ERROR); 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. /** 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( virtual void predictValues(
ConstAggregateDataPtr /* place */, ConstAggregateDataPtr /* place */,
IColumn & /*to*/, IColumn & /*to*/,
ColumnsWithTypeAndName & /*block*/, ColumnsWithTypeAndName & /*arguments*/,
size_t /*offset*/, size_t /*offset*/,
size_t /*limit*/, size_t /*limit*/,
const ColumnNumbers & /*arguments*/,
const Context & /*context*/) const const Context & /*context*/) const
{ {
throw Exception("Method predictValues is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED); 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; 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(); MutableColumnPtr res = func->getReturnTypeToPredict()->createColumn();
res->reserve(data.size()); res->reserve(data.size());
@ -172,7 +172,7 @@ MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName &
if (data.size() == 1) if (data.size() == 1)
{ {
/// Case for const column. Predict using single model. /// 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 else
{ {
@ -180,7 +180,7 @@ MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName &
size_t row_num = 0; size_t row_num = 0;
for (auto * val : data) 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; ++row_num;
} }
} }

View File

@ -119,7 +119,7 @@ public:
const char * getFamilyName() const override { return "AggregateFunction"; } const char * getFamilyName() const override { return "AggregateFunction"; }
TypeIndex getDataType() const override { return TypeIndex::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 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); "arguments but " + toString(captured) + " columns were captured.", ErrorCodes::LOGICAL_ERROR);
auto columns = captured_columns; auto columns = captured_columns;
columns.emplace_back(ColumnWithTypeAndName {nullptr, function->getReturnType(), ""}); ColumnWithTypeAndName res{nullptr, function->getResultType(), ""};
ColumnNumbers arguments(captured_columns.size()); res.column = function->execute(columns, res.type, size_);
for (size_t i = 0; i < captured_columns.size(); ++i) return res;
arguments[i] = i;
function->execute(columns, arguments, captured_columns.size(), size_);
return columns[captured_columns.size()];
} }
} }

View File

@ -30,6 +30,8 @@ namespace ProfileEvents
static constexpr size_t log_peak_memory_usage_every = 1ULL << 30; 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); MemoryTracker total_memory_tracker(nullptr, VariableContext::Global);
@ -56,13 +58,15 @@ MemoryTracker::~MemoryTracker()
void MemoryTracker::logPeakMemoryUsage() const void MemoryTracker::logPeakMemoryUsage() const
{ {
const auto * description = description_ptr.load(std::memory_order_relaxed); 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 void MemoryTracker::logMemoryUsage(Int64 current) const
{ {
const auto * description = description_ptr.load(std::memory_order_relaxed); 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) if (size < 0)
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Negative size ({}) is passed to MemoryTracker. It is a bug.", size); 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; return;
/** Using memory_order_relaxed means that if allocations are done simultaneously, /** 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_hard_limit = hard_limit.load(std::memory_order_relaxed);
Int64 current_profiler_limit = profiler_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 /// And since total_memory_tracker is reset to the process resident
/// memory peridically (in AsynchronousMetrics::update()), any limit can be /// memory peridically (in AsynchronousMetrics::update()), any limit can be
/// capped to it, to avoid possible drift. /// 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(); Int64 total_amount = total_memory_tracker.get();
if (amount > total_amount) if (amount > total_amount)
@ -104,10 +111,8 @@ void MemoryTracker::alloc(Int64 size)
std::bernoulli_distribution fault(fault_probability); std::bernoulli_distribution fault(fault_probability);
if (unlikely(fault_probability && fault(thread_local_rng))) if (unlikely(fault_probability && fault(thread_local_rng)))
{ {
free(size);
/// Prevent recursion. Exception::ctor -> std::string -> new[] -> MemoryTracker::alloc /// Prevent recursion. Exception::ctor -> std::string -> new[] -> MemoryTracker::alloc
auto untrack_lock = blocker.cancel(); // NOLINT BlockerInThread untrack_lock;
ProfileEvents::increment(ProfileEvents::QueryMemoryLimitExceeded); ProfileEvents::increment(ProfileEvents::QueryMemoryLimitExceeded);
std::stringstream message; std::stringstream message;
@ -118,12 +123,13 @@ void MemoryTracker::alloc(Int64 size)
<< " (attempt to allocate chunk of " << size << " bytes)" << " (attempt to allocate chunk of " << size << " bytes)"
<< ", maximum: " << formatReadableSizeWithBinarySuffix(current_hard_limit); << ", maximum: " << formatReadableSizeWithBinarySuffix(current_hard_limit);
amount.fetch_sub(size, std::memory_order_relaxed);
throw DB::Exception(message.str(), DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED); throw DB::Exception(message.str(), DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED);
} }
if (unlikely(current_profiler_limit && will_be > current_profiler_limit)) 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); DB::TraceCollector::collect(DB::TraceType::Memory, StackTrace(), size);
setOrRaiseProfilerLimit((will_be + profiler_step - 1) / profiler_step * profiler_step); 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); std::bernoulli_distribution sample(sample_probability);
if (unlikely(sample_probability && sample(thread_local_rng))) if (unlikely(sample_probability && sample(thread_local_rng)))
{ {
auto no_track = blocker.cancel(); BlockerInThread untrack_lock;
DB::TraceCollector::collect(DB::TraceType::MemorySample, StackTrace(), size); DB::TraceCollector::collect(DB::TraceType::MemorySample, StackTrace(), size);
} }
if (unlikely(current_hard_limit && will_be > current_hard_limit)) if (unlikely(current_hard_limit && will_be > current_hard_limit))
{ {
free(size);
/// Prevent recursion. Exception::ctor -> std::string -> new[] -> MemoryTracker::alloc /// Prevent recursion. Exception::ctor -> std::string -> new[] -> MemoryTracker::alloc
auto no_track = blocker.cancel(); // NOLINT BlockerInThread untrack_lock;
ProfileEvents::increment(ProfileEvents::QueryMemoryLimitExceeded); ProfileEvents::increment(ProfileEvents::QueryMemoryLimitExceeded);
std::stringstream message; std::stringstream message;
@ -151,6 +155,7 @@ void MemoryTracker::alloc(Int64 size)
<< " (attempt to allocate chunk of " << size << " bytes)" << " (attempt to allocate chunk of " << size << " bytes)"
<< ", maximum: " << formatReadableSizeWithBinarySuffix(current_hard_limit); << ", maximum: " << formatReadableSizeWithBinarySuffix(current_hard_limit);
amount.fetch_sub(size, std::memory_order_relaxed);
throw DB::Exception(message.str(), DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED); 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) void MemoryTracker::free(Int64 size)
{ {
if (blocker.isCancelled()) if (BlockerInThread::isBlocked())
return; return;
std::bernoulli_distribution sample(sample_probability); std::bernoulli_distribution sample(sample_probability);
if (unlikely(sample_probability && sample(thread_local_rng))) if (unlikely(sample_probability && sample(thread_local_rng)))
{ {
auto no_track = blocker.cancel(); BlockerInThread untrack_lock;
DB::TraceCollector::collect(DB::TraceType::MemorySample, StackTrace(), -size); 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 <atomic>
#include <common/types.h> #include <common/types.h>
#include <Common/CurrentMetrics.h> #include <Common/CurrentMetrics.h>
#include <Common/SimpleActionBlocker.h>
#include <Common/VariableContext.h> #include <Common/VariableContext.h>
@ -131,8 +130,18 @@ public:
/// Prints info about peak memory consumption into log. /// Prints info about peak memory consumption into log.
void logPeakMemoryUsage() const; void logPeakMemoryUsage() const;
/// To be able to temporarily stop memory tracker /// To be able to temporarily stop memory tracking from current thread.
DB::SimpleActionBlocker blocker; 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; extern MemoryTracker total_memory_tracker;
@ -145,7 +154,3 @@ namespace CurrentMemoryTracker
void realloc(Int64 old_size, Int64 new_size); void realloc(Int64 old_size, Int64 new_size);
void free(Int64 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 ArrayA = typename ColVecA::Container;
using ArrayB = typename ColVecB::Container; using ArrayB = typename ColVecB::Container;
DecimalComparison(ColumnsWithTypeAndName & data, size_t result, const ColumnWithTypeAndName & col_left, const ColumnWithTypeAndName & col_right) static ColumnPtr apply(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)
{ {
if constexpr (_actual) if constexpr (_actual)
{ {
ColumnPtr c_res; ColumnPtr c_res;
Shift shift = getScales<A, B>(col_left.type, col_right.type); Shift shift = getScales<A, B>(col_left.type, col_right.type);
c_res = applyWithScale(col_left.column, col_right.column, shift); return applyWithScale(col_left.column, col_right.column, shift);
if (c_res)
data[result].column = std::move(c_res);
return true;
} }
return false; else
return nullptr;
} }
static bool compare(A a, B b, UInt32 scale_a, UInt32 scale_b) 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> template <typename FromType, typename ToType, typename Transform>
struct Transformer struct Transformer
{ {
Transformer(Transform transform_) explicit Transformer(Transform transform_)
: transform(std::move(transform_)) : transform(std::move(transform_))
{} {}
@ -116,29 +116,29 @@ template <typename FromDataType, typename ToDataType>
struct CustomWeekTransformImpl struct CustomWeekTransformImpl
{ {
template <typename Transform> 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)}; const auto op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>{std::move(transform)};
UInt8 week_mode = DEFAULT_WEEK_MODE; UInt8 week_mode = DEFAULT_WEEK_MODE;
if (arguments.size() > 1) 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>(); week_mode = week_mode_column->getValue<UInt8>();
} }
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;
if (const auto * sources = checkAndGetColumn<typename FromDataType::ColumnType>(source_col.get())) if (const auto * sources = checkAndGetColumn<typename FromDataType::ColumnType>(source_col.get()))
{ {
auto col_to = ToDataType::ColumnType::create(); auto col_to = ToDataType::ColumnType::create();
op.vector(sources->getData(), col_to->getData(), week_mode, time_zone); op.vector(sources->getData(), col_to->getData(), week_mode, time_zone);
columns[result].column = std::move(col_to); return col_to;
} }
else else
{ {
throw Exception( 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, + Transform::name,
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }

View File

@ -683,25 +683,25 @@ struct Transformer
template <typename FromDataType, typename ToDataType, typename Transform> template <typename FromDataType, typename ToDataType, typename Transform>
struct DateTimeTransformImpl 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>; 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())) 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()); auto * col_to = assert_cast<typename ToDataType::ColumnType *>(mutable_result_col.get());
Op::vector(sources->getData(), col_to->getData(), time_zone, transform); Op::vector(sources->getData(), col_to->getData(), time_zone, transform);
columns[result].column = std::move(mutable_result_col); return mutable_result_col;
} }
else 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, + " of first argument of function " + Transform::name,
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }

View File

@ -91,14 +91,14 @@ public:
return std::make_shared<DataTypeString>(); 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()); const ColumnString * input = checkAndGetColumn<ColumnString>(column_string.get());
if (!input) if (!input)
throw Exception( 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); ErrorCodes::ILLEGAL_COLUMN);
auto dst_column = ColumnString::create(); auto dst_column = ColumnString::create();
@ -111,9 +111,9 @@ public:
const ColumnString::Offsets & src_offsets = input->getOffsets(); const ColumnString::Offsets & src_offsets = input->getOffsets();
auto source = input->getChars().data(); const auto * source = input->getChars().data();
auto dst = dst_data.data(); auto * dst = dst_data.data();
auto dst_pos = dst; auto * dst_pos = dst;
size_t src_offset_prev = 0; size_t src_offset_prev = 0;
@ -141,7 +141,7 @@ public:
{ {
// during decoding character array can be partially polluted // during decoding character array can be partially polluted
// if fail, revert back and clean // 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)); outlen = _tb64d(reinterpret_cast<const uint8_t *>(source), srclen, reinterpret_cast<uint8_t *>(dst_pos));
if (!outlen) if (!outlen)
{ {
@ -166,7 +166,7 @@ public:
dst_data.resize(dst_pos - dst); 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. /// 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; ColumnsWithTypeAndName new_arguments = arguments;
if (WhichDataType(columns[new_arguments[1]].type).isAggregateFunction()) if (WhichDataType(new_arguments[1].type).isAggregateFunction())
std::swap(new_arguments[0], new_arguments[1]); std::swap(new_arguments[0], new_arguments[1]);
if (!isColumnConst(*columns[new_arguments[1]].column)) if (!isColumnConst(*new_arguments[1].column))
throw Exception{"Illegal column " + columns[new_arguments[1]].column->getName() throw Exception{"Illegal column " + new_arguments[1].column->getName()
+ " of argument of aggregation state multiply. Should be integer constant", ErrorCodes::ILLEGAL_COLUMN}; + " 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); bool agg_state_is_const = isColumnConst(agg_state_column);
const ColumnAggregateFunction & column = typeid_cast<const ColumnAggregateFunction &>( const ColumnAggregateFunction & column = typeid_cast<const ColumnAggregateFunction &>(
agg_state_is_const ? assert_cast<const ColumnConst &>(agg_state_column).getDataColumn() : agg_state_column); 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_to = column_to->getData();
auto & vec_from = column_from->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 // 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 // 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) 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 else
columns[result].column = std::move(column_to); return column_to;
} }
/// Merge two aggregation states together. /// 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 & lhs_column = *arguments[0].column;
const IColumn & rhs_column = *columns[arguments[1]].column; const IColumn & rhs_column = *arguments[1].column;
bool lhs_is_const = isColumnConst(lhs_column); bool lhs_is_const = isColumnConst(lhs_column);
bool rhs_is_const = isColumnConst(rhs_column); bool rhs_is_const = isColumnConst(rhs_column);
@ -707,37 +707,33 @@ class FunctionBinaryArithmetic : public IFunction
} }
if (lhs_is_const && rhs_is_const) 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 else
columns[result].column = std::move(column_to); return column_to;
} }
void executeDateTimeIntervalPlusMinus(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, ColumnPtr executeDateTimeIntervalPlusMinus(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
size_t result, size_t input_rows_count, const FunctionOverloadResolverPtr & function_builder) const size_t input_rows_count, const FunctionOverloadResolverPtr & function_builder) const
{ {
ColumnNumbers new_arguments = arguments; ColumnsWithTypeAndName new_arguments = arguments;
/// Interval argument must be second. /// 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]); std::swap(new_arguments[0], new_arguments[1]);
/// Change interval argument type to its representation /// Change interval argument type to its representation
ColumnsWithTypeAndName new_columns = columns; new_arguments[1].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>();
new_columns[new_arguments[1]].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>();
ColumnsWithTypeAndName new_arguments_with_type_and_name = auto function = function_builder->build(new_arguments);
{new_columns[new_arguments[0]], new_columns[new_arguments[1]]};
auto function = function_builder->build(new_arguments_with_type_and_name);
function->execute(new_columns, new_arguments, result, input_rows_count); return function->execute(new_arguments, result_type, input_rows_count);
columns[result].column = new_columns[result].column;
} }
public: public:
static constexpr auto name = Name::name; static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBinaryArithmetic>(context); } static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBinaryArithmetic>(context); }
FunctionBinaryArithmetic(const Context & context_) explicit FunctionBinaryArithmetic(const Context & context_)
: context(context_), : context(context_),
check_decimal_overflow(decimalCheckArithmeticOverflow(context)) check_decimal_overflow(decimalCheckArithmeticOverflow(context))
{} {}
@ -790,7 +786,7 @@ public:
new_arguments[1].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>(); new_arguments[1].type = std::make_shared<DataTypeNumber<DataTypeInterval::FieldType>>();
auto function = function_builder->build(new_arguments); auto function = function_builder->build(new_arguments);
return function->getReturnType(); return function->getResultType();
} }
DataTypePtr type_res; DataTypePtr type_res;
@ -851,20 +847,20 @@ public:
return type_res; 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>>; using OpImpl = FixedStringOperationImpl<Op<UInt8, UInt8>>;
auto col_left_raw = columns[arguments[0]].column.get(); const auto * col_left_raw = arguments[0].column.get();
auto col_right_raw = columns[arguments[1]].column.get(); const auto * col_right_raw = arguments[1].column.get();
if (auto col_left_const = checkAndGetColumnConst<ColumnFixedString>(col_left_raw)) 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()); const auto * col_left = checkAndGetColumn<ColumnFixedString>(col_left_const->getDataColumn());
auto col_right = checkAndGetColumn<ColumnFixedString>(col_right_const->getDataColumn()); const auto * col_right = checkAndGetColumn<ColumnFixedString>(col_right_const->getDataColumn());
if (col_left->getN() != col_right->getN()) if (col_left->getN() != col_right->getN())
return false; return nullptr;
auto col_res = ColumnFixedString::create(col_left->getN()); auto col_res = ColumnFixedString::create(col_left->getN());
auto & out_chars = col_res->getChars(); auto & out_chars = col_res->getChars();
out_chars.resize(col_left->getN()); out_chars.resize(col_left->getN());
@ -872,25 +868,24 @@ public:
col_right->getChars().data(), col_right->getChars().data(),
out_chars.data(), out_chars.data(),
out_chars.size()); out_chars.size());
columns[result].column = ColumnConst::create(std::move(col_res), col_left_raw->size()); return ColumnConst::create(std::move(col_res), col_left_raw->size());
return true;
} }
} }
bool is_left_column_const = checkAndGetColumnConst<ColumnFixedString>(col_left_raw) != nullptr; bool is_left_column_const = checkAndGetColumnConst<ColumnFixedString>(col_left_raw) != nullptr;
bool is_right_column_const = checkAndGetColumnConst<ColumnFixedString>(col_right_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>(checkAndGetColumnConst<ColumnFixedString>(col_left_raw)->getDataColumn())
: checkAndGetColumn<ColumnFixedString>(col_left_raw); : 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>(checkAndGetColumnConst<ColumnFixedString>(col_right_raw)->getDataColumn())
: checkAndGetColumn<ColumnFixedString>(col_right_raw); : checkAndGetColumn<ColumnFixedString>(col_right_raw);
if (col_left && col_right) if (col_left && col_right)
{ {
if (col_left->getN() != col_right->getN()) if (col_left->getN() != col_right->getN())
return false; return nullptr;
auto col_res = ColumnFixedString::create(col_left->getN()); auto col_res = ColumnFixedString::create(col_left->getN());
auto & out_chars = col_res->getChars(); auto & out_chars = col_res->getChars();
@ -922,14 +917,13 @@ public:
out_chars.size(), out_chars.size(),
col_left->getN()); col_left->getN());
} }
columns[result].column = std::move(col_res); return col_res;
return true;
} }
return false; return nullptr;
} }
template <typename A, typename B> 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 LeftDataType = std::decay_t<decltype(left)>;
using RightDataType = std::decay_t<decltype(right)>; using RightDataType = std::decay_t<decltype(right)>;
@ -944,8 +938,8 @@ public:
using ColVecT1 = std::conditional_t<IsDecimalNumber<T1>, ColumnDecimal<T1>, ColumnVector<T1>>; using ColVecT1 = std::conditional_t<IsDecimalNumber<T1>, ColumnDecimal<T1>, ColumnVector<T1>>;
using ColVecResult = std::conditional_t<IsDecimalNumber<ResultType>, ColumnDecimal<ResultType>, ColumnVector<ResultType>>; using ColVecResult = std::conditional_t<IsDecimalNumber<ResultType>, ColumnDecimal<ResultType>, ColumnVector<ResultType>>;
auto col_left_raw = columns[arguments[0]].column.get(); const auto * col_left_raw = arguments[0].column.get();
auto col_right_raw = columns[arguments[1]].column.get(); const auto * col_right_raw = arguments[1].column.get();
auto col_left_const = checkAndGetColumnConst<ColVecT0>(col_left_raw); auto col_left_const = checkAndGetColumnConst<ColVecT0>(col_left_raw);
auto col_right_const = checkAndGetColumnConst<ColVecT1>(col_right_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) : 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); 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())); col_left_const->size(), toField(res, type.getScale()));
return true;
} }
col_res = ColVecResult::create(0, type.getScale()); 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); OpImpl::template vectorConstant<dec_a, dec_b>(col_left->getData(), const_b, vec_res, scale_a, scale_b);
} }
else else
return false; return nullptr;
} }
else else
{ {
@ -1026,8 +1019,7 @@ public:
if (col_left_const && col_right_const) if (col_left_const && col_right_const)
{ {
auto res = OpImpl::constantConstant(col_left_const->template getValue<T0>(), col_right_const->template getValue<T1>()); 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 ResultDataType().createColumnConst(col_left_const->size(), toField(res));
return true;
} }
col_res = ColVecResult::create(); 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()); OpImpl::vectorConstant(col_left->getData().data(), col_right_const->template getValue<T1>(), vec_res.data(), vec_res.size());
} }
else else
return false; return nullptr;
} }
columns[result].column = std::move(col_res); return col_res;
return true;
} }
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 /// 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 executeAggregateMultiply(arguments, result_type, input_rows_count);
return;
} }
/// Special case - addition of two aggregate functions states /// 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 executeAggregateAddition(arguments, result_type, input_rows_count);
return;
} }
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval. /// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
if (auto function_builder 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 executeDateTimeIntervalPlusMinus(arguments, result_type, input_rows_count, function_builder);
return;
} }
const auto & left_argument = columns[arguments[0]]; const auto & left_argument = arguments[0];
const auto & right_argument = columns[arguments[1]]; const auto & right_argument = arguments[1];
auto * left_generic = left_argument.type.get(); const auto * left_generic = left_argument.type.get();
auto * right_generic = right_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) bool valid = castBothTypes(left_generic, right_generic, [&](const auto & left, const auto & right)
{ {
using LeftDataType = std::decay_t<decltype(left)>; using LeftDataType = std::decay_t<decltype(left)>;
@ -1093,10 +1082,10 @@ public:
if constexpr (!Op<DataTypeFixedString, DataTypeFixedString>::allow_fixed_string) if constexpr (!Op<DataTypeFixedString, DataTypeFixedString>::allow_fixed_string)
return false; return false;
else else
return executeFixedString(columns, arguments, result); return (res = executeFixedString(arguments)) != nullptr;
} }
else else
return executeNumeric(columns, arguments, result, left, right); return (res = executeNumeric(arguments, left, right)) != nullptr;
}); });
if (!valid) if (!valid)
@ -1109,6 +1098,8 @@ public:
left_argument.name, left_argument.type->getName(), left_argument.name, left_argument.type->getName(),
right_argument.name, right_argument.type->getName()); right_argument.name, right_argument.type->getName());
} }
return res;
} }
#if USE_EMBEDDED_COMPILER #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) if (left.column && isColumnConst(*left.column) && arguments.size() == 1)
{ {
ColumnsWithTypeAndName columns_with_constant ColumnsWithTypeAndName columns_with_constant
= {{left.column->cloneResized(input_rows_count), left.type, left.name}, = {{left.column->cloneResized(input_rows_count), left.type, left.name},
columns[arguments[0]], arguments[0]};
columns[result]};
Base::executeImpl(columns_with_constant, {0, 1}, 2, input_rows_count); return Base::executeImpl(columns_with_constant, result_type, input_rows_count);
columns[result] = columns_with_constant[2];
} }
else if (right.column && isColumnConst(*right.column) && arguments.size() == 1) else if (right.column && isColumnConst(*right.column) && arguments.size() == 1)
{ {
ColumnsWithTypeAndName columns_with_constant ColumnsWithTypeAndName columns_with_constant
= {columns[arguments[0]], = {arguments[0],
{right.column->cloneResized(input_rows_count), right.type, right.name}, {right.column->cloneResized(input_rows_count), right.type, right.name}};
columns[result]};
Base::executeImpl(columns_with_constant, {0, 1}, 2, input_rows_count); return Base::executeImpl(columns_with_constant, result_type, input_rows_count);
columns[result] = columns_with_constant[2];
} }
else else
Base::executeImpl(columns, arguments, result, input_rows_count); return Base::executeImpl(arguments, result_type, input_rows_count);
} }
bool hasInformationAboutMonotonicity() const override bool hasInformationAboutMonotonicity() const override
@ -1246,12 +1233,11 @@ public:
{ {
ColumnsWithTypeAndName columns_with_constant ColumnsWithTypeAndName columns_with_constant
= {{left.column->cloneResized(1), left.type, left.name}, = {{left.column->cloneResized(1), left.type, left.name},
{right.type->createColumnConst(1, point), right.type, right.name}, {right.type->createColumnConst(1, point), right.type, right.name}};
{nullptr, return_type, ""}};
Base::executeImpl(columns_with_constant, {0, 1}, 2, 1); auto col = Base::executeImpl(columns_with_constant, return_type, 1);
Field point_transformed; Field point_transformed;
columns_with_constant[2].column->get(0, point_transformed); col->get(0, point_transformed);
return point_transformed; return point_transformed;
}; };
transform(left_point); transform(left_point);
@ -1282,12 +1268,11 @@ public:
{ {
ColumnsWithTypeAndName columns_with_constant ColumnsWithTypeAndName columns_with_constant
= {{left.type->createColumnConst(1, point), left.type, left.name}, = {{left.type->createColumnConst(1, point), left.type, left.name},
{right.column->cloneResized(1), right.type, right.name}, {right.column->cloneResized(1), right.type, right.name}};
{nullptr, return_type, ""}};
Base::executeImpl(columns_with_constant, {0, 1}, 2, 1); auto col = Base::executeImpl(columns_with_constant, return_type, 1);
Field point_transformed; Field point_transformed;
columns_with_constant[2].column->get(0, point_transformed); col->get(0, point_transformed);
return point_transformed; return point_transformed;
}; };

View File

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

View File

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

View File

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

View File

@ -95,23 +95,23 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; } 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); WhichDataType which(from_type);
if (which.isDate()) 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()) 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()) else if (which.isDateTime64())
{ {
const auto scale = static_cast<const DataTypeDateTime64 *>(from_type)->getScale(); const auto scale = static_cast<const DataTypeDateTime64 *>(from_type)->getScale();
const TransformDateTime64<Transform> transformer(scale); 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 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); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
} }

View File

@ -34,9 +34,9 @@ public:
return std::make_shared<DataTypeString>(); 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(); input_rows_count, getFQDNOrHostName())->convertToFullColumnIfConst();
} }
}; };

View File

@ -7,7 +7,6 @@
#include <Columns/ColumnLowCardinality.h> #include <Columns/ColumnLowCardinality.h>
#include <Common/assert_cast.h> #include <Common/assert_cast.h>
#include <DataTypes/DataTypeNullable.h> #include <DataTypes/DataTypeNullable.h>
#include <DataTypes/DataTypeLowCardinality.h>
namespace DB 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; ColumnsWithTypeAndName res;
size_t num_columns = columns.size(); for (const auto & col : columns)
for (size_t i = 0; i < num_columns; ++i)
{ {
const auto & col = columns[i]; if (col.type->isNullable())
if (args.count(i) && col.type->isNullable())
{ {
const DataTypePtr & nested_type = static_cast<const DataTypeNullable &>(*col.type).getNestedType(); const DataTypePtr & nested_type = static_cast<const DataTypeNullable &>(*col.type).getNestedType();
@ -88,20 +83,6 @@ static ColumnsWithTypeAndName createBlockWithNestedColumnsImpl(const ColumnsWith
return res; 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, void validateArgumentType(const IFunction & func, const DataTypes & arguments,
size_t argument_index, bool (* validator_func)(const IDataType &), size_t argument_index, bool (* validator_func)(const IDataType &),
const char * expected_type_description) 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); Columns convertConstTupleToConstantElements(const ColumnConst & column);
/// Returns the copy of a given columns in which each column specified in /// Returns the copy of a given columns in which each column is replaced with its respective nested
/// the "arguments" parameter is replaced with its respective nested
/// column if it is nullable. /// column if it is nullable.
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args); ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns);
/// Similar function as above. Additionally transform the result type if needed.
ColumnsWithTypeAndName createBlockWithNestedColumns(const ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result);
/// Checks argument type at specified index with predicate. /// Checks argument type at specified index with predicate.
/// throws if there is no argument at specified index or if predicate returns false. /// 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> 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; ColumnsWithTypeAndName keys;
for (size_t i = 2; i < arguments.size(); ++i) for (size_t i = 2; i < arguments.size(); ++i)
{ {
auto key = columns[arguments[i]]; auto key = arguments[i];
keys.emplace_back(std::move(key)); keys.emplace_back(std::move(key));
} }
columns[result] = join->joinGet(keys, result_columns); return join->joinGet(keys, result_columns).column;
} }
template <bool or_null> 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}}); 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 useDefaultImplementationForLowCardinalityColumns() const override { return true; }
bool useDefaultImplementationForConstants() 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; } String getName() const override { return name; }
@ -54,9 +54,9 @@ public:
String getName() const override { return name; } String getName() const override { return name; }
const DataTypes & getArgumentTypes() const override { return argument_types; } 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: private:
TableLockHolder table_lock; TableLockHolder table_lock;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -154,9 +154,10 @@ public:
return result; 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)>; using DataType = std::decay_t<decltype(type)>;
@ -164,13 +165,13 @@ public:
{ {
if constexpr (allow_fixed_string) 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 col_res = ColumnFixedString::create(col->getN());
auto & vec_res = col_res->getChars(); auto & vec_res = col_res->getChars();
vec_res.resize(col->size() * col->getN()); vec_res.resize(col->size() * col->getN());
FixedStringUnaryOperationImpl<Op<UInt8>>::vector(col->getChars(), vec_res); FixedStringUnaryOperationImpl<Op<UInt8>>::vector(col->getChars(), vec_res);
columns[result].column = std::move(col_res); result_column = std::move(col_res);
return true; return true;
} }
} }
@ -180,13 +181,13 @@ public:
using T0 = typename DataType::FieldType; using T0 = typename DataType::FieldType;
if constexpr (allow_decimal) 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 col_res = ColumnDecimal<typename Op<T0>::ResultType>::create(0, type.getScale());
auto & vec_res = col_res->getData(); auto & vec_res = col_res->getData();
vec_res.resize(col->getData().size()); vec_res.resize(col->getData().size());
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res); UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
columns[result].column = std::move(col_res); result_column = std::move(col_res);
return true; return true;
} }
} }
@ -194,13 +195,13 @@ public:
else else
{ {
using T0 = typename DataType::FieldType; 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 col_res = ColumnVector<typename Op<T0>::ResultType>::create();
auto & vec_res = col_res->getData(); auto & vec_res = col_res->getData();
vec_res.resize(col->getData().size()); vec_res.resize(col->getData().size());
UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res); UnaryOperationImpl<T0, Op<T0>>::vector(col->getData(), vec_res);
columns[result].column = std::move(col_res); result_column = std::move(col_res);
return true; return true;
} }
} }
@ -209,6 +210,8 @@ public:
}); });
if (!valid) if (!valid)
throw Exception(getName() + "'s argument does not match the expected data type", ErrorCodes::LOGICAL_ERROR); throw Exception(getName() + "'s argument does not match the expected data type", ErrorCodes::LOGICAL_ERROR);
return result_column;
} }
#if USE_EMBEDDED_COMPILER #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 SourceColumnType = typename SourceDataType::ColumnType;
using ResultColumnType = typename ResultDataType::ColumnType; using ResultColumnType = typename ResultDataType::ColumnType;
const auto & src = columns[arguments[0]]; const auto & src = arguments[0];
auto & res = columns[result];
const auto & col = *src.column; const auto & col = *src.column;
const SourceColumnType * source_col_typed = checkAndGetColumn<SourceColumnType>(col); const SourceColumnType * source_col_typed = checkAndGetColumn<SourceColumnType>(col);
@ -80,16 +79,16 @@ public:
+ std::string(SourceDataType::family_name), + std::string(SourceDataType::family_name),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
res.column = res.type->createColumn(); auto res_column = result_type->createColumn();
if (input_rows_count == 0) 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()); result_data.reserve(source_col_typed->size());
const auto & source_data = source_col_typed->getData(); 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) if (scale_diff == 0)
{ {
static_assert(sizeof(typename SourceColumnType::Container::value_type) == sizeof(typename ResultColumnType::Container::value_type)); 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) for (const auto & v : source_data)
result_data.push_back(static_cast<Int64>(toDestValue(v) / scale_multiplier)); result_data.push_back(static_cast<Int64>(toDestValue(v) / scale_multiplier));
} }
return res_column;
} }
private: private:

View File

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

View File

@ -104,7 +104,7 @@ public:
if (arguments[0]->onlyNull()) if (arguments[0]->onlyNull())
return arguments[0]; 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) if (!array_type)
throw Exception( throw Exception(
"First argument for function " + getName() + " must be an array but it has type " + arguments[0]->getName() + ".", "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; } 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();
auto array_type = typeid_cast<const DataTypeArray *>(from_type); const auto * array_type = typeid_cast<const DataTypeArray *>(from_type);
auto nested_type = array_type->getNestedType(); const auto & nested_type = array_type->getNestedType();
DataTypes argument_types = {nested_type}; DataTypes argument_types = {nested_type};
WhichDataType which(nested_type); WhichDataType which(nested_type);
if (which.isUInt8()) if (which.isUInt8())
executeBitmapData<UInt8>(columns, argument_types, arguments, result); return executeBitmapData<UInt8>(argument_types, arguments);
else if (which.isUInt16()) else if (which.isUInt16())
executeBitmapData<UInt16>(columns, argument_types, arguments, result); return executeBitmapData<UInt16>(argument_types, arguments);
else if (which.isUInt32()) else if (which.isUInt32())
executeBitmapData<UInt32>(columns, argument_types, arguments, result); return executeBitmapData<UInt32>(argument_types, arguments);
else if (which.isUInt64()) else if (which.isUInt64())
executeBitmapData<UInt64>(columns, argument_types, arguments, result); return executeBitmapData<UInt64>(argument_types, arguments);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -146,11 +146,11 @@ public:
private: private:
template <typename T> 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 // input data
const ColumnArray * array = typeid_cast<const ColumnArray *>(columns[arguments[0]].column.get()); const ColumnArray * array = typeid_cast<const ColumnArray *>(arguments[0].column.get());
ColumnPtr mapped = array->getDataPtr(); const ColumnPtr & mapped = array->getDataPtr();
const ColumnArray::Offsets & offsets = array->getOffsets(); const ColumnArray::Offsets & offsets = array->getOffsets();
const ColumnVector<T> * column = checkAndGetColumn<ColumnVector<T>>(&*mapped); const ColumnVector<T> * column = checkAndGetColumn<ColumnVector<T>>(&*mapped);
const typename ColumnVector<T>::Container & input_data = column->getData(); const typename ColumnVector<T>::Container & input_data = column->getData();
@ -174,7 +174,7 @@ private:
bitmap_data.rbs.add(input_data[pos]); 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; } 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 // input data
const auto & return_type = columns[result].type; const auto & return_type = result_type;
auto res_ptr = return_type->createColumn(); auto res_ptr = return_type->createColumn();
ColumnArray & res = assert_cast<ColumnArray &>(*res_ptr); ColumnArray & res = assert_cast<ColumnArray &>(*res_ptr);
IColumn & res_data = res.getData(); IColumn & res_data = res.getData();
ColumnArray::Offsets & res_offsets = res.getOffsets(); 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) 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()) 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()) 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()) 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 else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "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: private:
@ -240,11 +240,11 @@ private:
template <typename T> template <typename T>
void executeIntType( 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
{ {
const ColumnAggregateFunction * column 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(); PaddedPODArray<T> & res_data = typeid_cast<ColumnVector<T> &>(res_data_col).getData();
ColumnArray::Offset res_offset = 0; 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() + ".", "First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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)) if (!(arg_type1))
throw Exception( throw Exception(
"Second argument for function " + getName() + " must be UInt32 but it has type " + arguments[1]->getName() + ".", "Second argument for function " + getName() + " must be UInt32 but it has type " + arguments[1]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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)) if (!(arg_type2))
throw Exception( throw Exception(
"Third argument for function " + getName() + " must be UInt32 but it has type " + arguments[2]->getName() + ".", "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; } 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, result, input_rows_count); return executeIntType<UInt8>(arguments, input_rows_count);
else if (which.isUInt16()) else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, result, input_rows_count); return executeIntType<UInt16>(arguments, input_rows_count);
else if (which.isUInt32()) else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, result, input_rows_count); return executeIntType<UInt32>(arguments, input_rows_count);
else if (which.isUInt64()) else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, result, input_rows_count); return executeIntType<UInt64>(arguments, input_rows_count);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -321,9 +321,7 @@ private:
using ToType = UInt64; using ToType = UInt64;
template <typename T> template <typename T>
void executeIntType( ColumnPtr executeIntType(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count)
const
{ {
const IColumn * column_ptrs[3]; const IColumn * column_ptrs[3];
bool is_column_const[3]; bool is_column_const[3];
@ -333,7 +331,7 @@ private:
for (size_t i = 0; i < 3; ++i) 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]); is_column_const[i] = isColumnConst(*column_ptrs[i]);
} }
if (is_column_const[0]) if (is_column_const[0])
@ -367,7 +365,7 @@ private:
= *reinterpret_cast<AggregateFunctionGroupBitmapData<T> *>(col_to->getData()[i]); = *reinterpret_cast<AggregateFunctionGroupBitmapData<T> *>(col_to->getData()[i]);
Impl::apply(bitmap_data_0, range_start, range_end, bitmap_data_2); 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; } 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, result, input_rows_count); return executeIntType<UInt8>(arguments, input_rows_count);
else if (which.isUInt16()) else if (which.isUInt16())
executeIntType<UInt16>(columns, arguments, result, input_rows_count); return executeIntType<UInt16>(arguments, input_rows_count);
else if (which.isUInt32()) else if (which.isUInt32())
executeIntType<UInt32>(columns, arguments, result, input_rows_count); return executeIntType<UInt32>(arguments, input_rows_count);
else if (which.isUInt64()) else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, result, input_rows_count); return executeIntType<UInt64>(arguments, input_rows_count);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -457,8 +455,7 @@ private:
using ToType = UInt64; using ToType = UInt64;
template <typename T> template <typename T>
void executeIntType( ColumnPtr executeIntType(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const
{ {
const IColumn * column_ptrs[3]; const IColumn * column_ptrs[3];
bool is_column_const[3]; bool is_column_const[3];
@ -468,7 +465,7 @@ private:
for (size_t i = 0; i < 3; ++i) 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]); is_column_const[i] = isColumnConst(*column_ptrs[i]);
} }
if (is_column_const[0]) if (is_column_const[0])
@ -485,7 +482,7 @@ private:
array = typeid_cast<const ColumnArray*>(typeid_cast<const ColumnConst*>(column_ptrs[1])->getDataColumnPtr().get()); array = typeid_cast<const ColumnArray*>(typeid_cast<const ColumnConst*>(column_ptrs[1])->getDataColumnPtr().get());
else 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 ColumnArray::Offsets & from_offsets = array->getOffsets();
const ColumnVector<UInt32>::Container & from_container = typeid_cast<const ColumnVector<UInt32> *>(&array->getData())->getData(); const ColumnVector<UInt32>::Container & from_container = typeid_cast<const ColumnVector<UInt32> *>(&array->getData())->getData();
@ -493,7 +490,7 @@ private:
if (is_column_const[2]) if (is_column_const[2])
array = typeid_cast<const ColumnArray*>(typeid_cast<const ColumnConst*>(column_ptrs[2])->getDataColumnPtr().get()); array = typeid_cast<const ColumnArray*>(typeid_cast<const ColumnConst*>(column_ptrs[2])->getDataColumnPtr().get());
else 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 ColumnArray::Offsets & to_offsets = array->getOffsets();
const ColumnVector<UInt32>::Container & to_container = typeid_cast<const ColumnVector<UInt32> *>(&array->getData())->getData(); 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.merge(bitmap_data_0.rbs);
bitmap_data_2.rbs.rb_replace(&from_container[from_start], &to_container[to_start], from_end - from_start); 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 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())) if (!(bitmap_type && bitmap_type->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception( throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".", "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; } 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); auto col_to = ColumnVector<ToType>::create(input_rows_count);
typename ColumnVector<ToType>::Container & vec_to = col_to->getData(); 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, vec_to); executeIntType<UInt8>(arguments, input_rows_count, vec_to);
else if (which.isUInt16()) 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()) 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()) else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, vec_to); executeIntType<UInt64>(arguments, input_rows_count, vec_to);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "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: private:
@ -596,10 +593,10 @@ private:
template <typename T> template <typename T>
void executeIntType( 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 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) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const AggregateFunctionGroupBitmapData<T> & bitmap_data const AggregateFunctionGroupBitmapData<T> & bitmap_data
@ -722,12 +719,12 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override 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())) if (!(bitmap_type0 && bitmap_type0->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception( throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".", "First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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)) if (!(arg_type1))
throw Exception( throw Exception(
"Second argument for function " + getName() + " must be UInt32 but it has type " + arguments[1]->getName() + ".", "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; } 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); auto col_to = ColumnVector<UInt8>::create(input_rows_count);
typename ColumnVector<UInt8>::Container & vec_to = col_to->getData(); 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, vec_to); executeIntType<UInt8>(arguments, input_rows_count, vec_to);
else if (which.isUInt16()) 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()) 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()) else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, vec_to); executeIntType<UInt64>(arguments, input_rows_count, vec_to);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "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: private:
template <typename T> template <typename T>
void executeIntType( 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]; const IColumn * column_ptrs[2];
bool is_column_const[2]; bool is_column_const[2];
@ -773,7 +770,7 @@ private:
for (size_t i = 0; i < 2; ++i) 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]); is_column_const[i] = isColumnConst(*column_ptrs[i]);
} }
if (is_column_const[0]) if (is_column_const[0])
@ -812,13 +809,13 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override 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())) if (!(bitmap_type0 && bitmap_type0->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception( throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".", "First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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())) if (!(bitmap_type1 && bitmap_type1->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception( throw Exception(
"Second argument for function " + getName() + " must be a bitmap but it has type " + arguments[1]->getName() + ".", "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; } 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); auto col_to = ColumnVector<ToType>::create(input_rows_count);
typename ColumnVector<ToType>::Container & vec_to = col_to->getData(); 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) if (which.isUInt8())
executeIntType<UInt8>(columns, arguments, input_rows_count, vec_to); executeIntType<UInt8>(arguments, input_rows_count, vec_to);
else if (which.isUInt16()) 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()) 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()) else if (which.isUInt64())
executeIntType<UInt64>(columns, arguments, input_rows_count, vec_to); executeIntType<UInt64>(arguments, input_rows_count, vec_to);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "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: private:
template <typename T> template <typename T>
void executeIntType( 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]; const ColumnAggregateFunction * column_ptrs[2];
bool is_column_const[2]; bool is_column_const[2];
for (size_t i = 0; i < 2; ++i) 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()); column_ptrs[i] = typeid_cast<const ColumnAggregateFunction*>(argument_column_const->getDataColumnPtr().get());
is_column_const[i] = true; is_column_const[i] = true;
} }
else 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; is_column_const[i] = false;
} }
} }
@ -947,13 +944,13 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override 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())) if (!(bitmap_type0 && bitmap_type0->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception( throw Exception(
"First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".", "First argument for function " + getName() + " must be a bitmap but it has type " + arguments[0]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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())) if (!(bitmap_type1 && bitmap_type1->getFunctionName() == AggregateFunctionGroupBitmapData<UInt32>::name()))
throw Exception( throw Exception(
"Second argument for function " + getName() + " must be a bitmap but it has type " + arguments[1]->getName() + ".", "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; } 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); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
WhichDataType which(aggr_type->getArgumentsDataTypes()[0]); WhichDataType which(aggr_type->getArgumentsDataTypes()[0]);
if (which.isUInt8()) if (which.isUInt8())
executeBitmapData<UInt8>(columns, arguments, result, input_rows_count); return executeBitmapData<UInt8>(arguments, input_rows_count);
else if (which.isUInt16()) else if (which.isUInt16())
executeBitmapData<UInt16>(columns, arguments, result, input_rows_count); return executeBitmapData<UInt16>(arguments, input_rows_count);
else if (which.isUInt32()) else if (which.isUInt32())
executeBitmapData<UInt32>(columns, arguments, result, input_rows_count); return executeBitmapData<UInt32>(arguments, input_rows_count);
else if (which.isUInt64()) else if (which.isUInt64())
executeBitmapData<UInt64>(columns, arguments, result, input_rows_count); return executeBitmapData<UInt64>(arguments, input_rows_count);
else else
throw Exception( throw Exception(
"Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); "Unexpected type " + from_type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
@ -990,20 +987,20 @@ public:
private: private:
template <typename T> 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]; const ColumnAggregateFunction * column_ptrs[2];
bool is_column_const[2]; bool is_column_const[2];
for (size_t i = 0; i < 2; ++i) 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()); column_ptrs[i] = typeid_cast<const ColumnAggregateFunction *>(argument_column_const->getDataColumnPtr().get());
is_column_const[i] = true; is_column_const[i] = true;
} }
else 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; is_column_const[i] = false;
} }
} }
@ -1026,7 +1023,7 @@ private:
= *reinterpret_cast<const AggregateFunctionGroupBitmapData<T> *>(data_ptr_1); = *reinterpret_cast<const AggregateFunctionGroupBitmapData<T> *>(data_ptr_1);
Impl<T>::apply(bitmap_data_1, bitmap_data_2); 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 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) if (!ptr || ptr->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + arguments[0]->getName() + throw Exception("Illegal type " + arguments[0]->getName() +
" of argument of function " + getName() + " of argument of function " + getName() +
@ -88,12 +88,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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; 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) if (col_in->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + col_type_name.type->getName() + throw Exception("Illegal type " + col_type_name.type->getName() +
@ -112,8 +112,8 @@ public:
vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1)); vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1));
offsets_res.resize(size); offsets_res.resize(size);
auto begin = reinterpret_cast<char *>(vec_res.data()); auto * begin = reinterpret_cast<char *>(vec_res.data());
auto pos = begin; auto * pos = begin;
for (size_t offset = 0, i = 0; offset < vec_in.size(); offset += IPV6_BINARY_LENGTH, ++i) 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); vec_res.resize(pos - begin);
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -145,7 +145,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override 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) if (!ptr || ptr->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + arguments[0]->getName() + throw Exception("Illegal type " + arguments[0]->getName() +
" of argument 1 of function " + getName() + " of argument 1 of function " + getName() +
@ -168,17 +168,17 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; } 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 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_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; 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) if (col_in->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + col_type_name.type->getName() + throw Exception("Illegal type " + col_type_name.type->getName() +
@ -187,7 +187,7 @@ public:
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")", ", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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) if (!ipv6_zeroed_tail_bytes)
throw Exception("Illegal type " + col_ipv6_zeroed_tail_bytes_type.type->getName() + throw Exception("Illegal type " + col_ipv6_zeroed_tail_bytes_type.type->getName() +
" of argument 2 of function " + getName(), " of argument 2 of function " + getName(),
@ -199,7 +199,7 @@ public:
" of function " + getName(), " of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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) if (!ipv4_zeroed_tail_bytes)
throw Exception("Illegal type " + col_ipv4_zeroed_tail_bytes_type.type->getName() + throw Exception("Illegal type " + col_ipv4_zeroed_tail_bytes_type.type->getName() +
" of argument 3 of function " + getName(), " of argument 3 of function " + getName(),
@ -221,12 +221,12 @@ public:
vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1)); vec_res.resize(size * (IPV6_MAX_TEXT_LENGTH + 1));
offsets_res.resize(size); offsets_res.resize(size);
auto begin = reinterpret_cast<char *>(vec_res.data()); auto * begin = reinterpret_cast<char *>(vec_res.data());
auto pos = begin; auto * pos = begin;
for (size_t offset = 0, i = 0; offset < vec_in.size(); offset += IPV6_BINARY_LENGTH, ++i) 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; 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); cutAddress(reinterpret_cast<const unsigned char *>(address), pos, zeroed_tail_bytes_count);
offsets_res[i] = pos - begin; offsets_res[i] = pos - begin;
@ -234,22 +234,22 @@ public:
vec_res.resize(pos - begin); vec_res.resize(pos - begin);
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
private: private:
bool isIPv4Mapped(const UInt8 * address) const static bool isIPv4Mapped(const UInt8 * address)
{ {
return (unalignedLoad<UInt64>(address) == 0) && return (unalignedLoad<UInt64>(address) == 0) &&
((unalignedLoad<UInt64>(address + 8) & 0x00000000FFFFFFFFull) == 0x00000000FFFF0000ull); ((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); formatIPv6(address, dst, zeroed_tail_bytes_count);
} }
@ -277,11 +277,11 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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); auto col_res = ColumnFixedString::create(IPV6_BINARY_LENGTH);
@ -301,10 +301,10 @@ public:
src_offset = offsets_src[i]; src_offset = offsets_src[i];
} }
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -339,9 +339,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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())) if (const ColumnUInt32 * col = typeid_cast<const ColumnUInt32 *>(column.get()))
{ {
@ -365,10 +365,10 @@ public:
vec_res.resize(pos - begin); vec_res.resize(pos - begin);
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -407,9 +407,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{ {
@ -428,10 +428,10 @@ public:
prev_offset = offsets_src[i]; prev_offset = offsets_src[i];
} }
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -460,12 +460,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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; 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); 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) 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]); mapIPv4ToIPv6(vec_in[i], &vec_res[out_offset]);
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
private: private:
void mapIPv4ToIPv6(UInt32 in, UInt8 * buf) const static void mapIPv4ToIPv6(UInt32 in, UInt8 * buf)
{ {
unalignedStore<UInt64>(buf, 0); unalignedStore<UInt64>(buf, 0);
unalignedStore<UInt64>(buf + 8, 0x00000000FFFF0000ull | (static_cast<UInt64>(ntohl(in)) << 32)); unalignedStore<UInt64>(buf + 8, 0x00000000FFFF0000ull | (static_cast<UInt64>(ntohl(in)) << 32));
@ -578,9 +578,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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())) if (const ColumnUInt64 * col = typeid_cast<const ColumnUInt64 *>(column.get()))
{ {
@ -602,10 +602,10 @@ public:
offsets_res[i] = current_offset; offsets_res[i] = current_offset;
} }
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -688,9 +688,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{ {
@ -716,10 +716,10 @@ public:
prev_offset = current_offset; prev_offset = current_offset;
} }
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -743,7 +743,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override 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) if (!ptr || ptr->getN() != uuid_bytes_length)
throw Exception("Illegal type " + arguments[0]->getName() + throw Exception("Illegal type " + arguments[0]->getName() +
" of argument of function " + getName() + " of argument of function " + getName() +
@ -755,12 +755,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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; 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) if (col_in->getN() != uuid_bytes_length)
throw Exception("Illegal type " + col_type_name.type->getName() + throw Exception("Illegal type " + col_type_name.type->getName() +
@ -792,10 +792,10 @@ public:
offsets_res[i] = dst_offset; offsets_res[i] = dst_offset;
} }
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -844,7 +844,7 @@ public:
/// String or FixedString(36) /// String or FixedString(36)
if (!isString(arguments[0])) 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) if (!ptr || ptr->getN() != uuid_text_length)
throw Exception("Illegal type " + arguments[0]->getName() + throw Exception("Illegal type " + arguments[0]->getName() +
" of argument of function " + getName() + " of argument of function " + getName() +
@ -857,12 +857,12 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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; 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 & vec_in = col_in->getChars();
const auto & offsets_in = col_in->getOffsets(); const auto & offsets_in = col_in->getOffsets();
@ -891,9 +891,9 @@ public:
src_offset += string_size; 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) if (col_in_fixed->getN() != uuid_text_length)
throw Exception("Illegal type " + col_type_name.type->getName() + throw Exception("Illegal type " + col_type_name.type->getName() +
@ -920,10 +920,10 @@ public:
dst_offset += uuid_bytes_length; dst_offset += uuid_bytes_length;
} }
columns[result].column = std::move(col_res); return col_res;
} }
else 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); + " 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) while (pos < end)
{ {
@ -1095,7 +1095,7 @@ public:
++out; ++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); 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); const ColumnFixedString * col_fstr_in = checkAndGetColumn<ColumnFixedString>(col);
@ -1187,10 +1187,10 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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(); const IColumn * column = arguments[0].column.get();
ColumnPtr & res_column = columns[result].column; ColumnPtr res_column;
if (tryExecuteUInt<UInt8>(column, res_column) || if (tryExecuteUInt<UInt8>(column, res_column) ||
tryExecuteUInt<UInt16>(column, res_column) || tryExecuteUInt<UInt16>(column, res_column) ||
@ -1203,9 +1203,9 @@ public:
tryExecuteDecimal<Decimal32>(column, res_column) || tryExecuteDecimal<Decimal32>(column, res_column) ||
tryExecuteDecimal<Decimal64>(column, res_column) || tryExecuteDecimal<Decimal64>(column, res_column) ||
tryExecuteDecimal<Decimal128>(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(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -1235,7 +1235,7 @@ public:
return std::make_shared<DataTypeString>(); 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) if ((end - pos) & 1)
{ {
@ -1255,9 +1255,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{ {
@ -1290,11 +1290,11 @@ public:
out_vec.resize(pos - begin); out_vec.resize(pos - begin);
columns[result].column = std::move(col_res); return col_res;
} }
else else
{ {
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -1335,7 +1335,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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(); auto col_str = ColumnString::create();
ColumnString::Chars & out_vec = col_str->getChars(); ColumnString::Chars & out_vec = col_str->getChars();
@ -1355,7 +1355,7 @@ public:
for (size_t idx = 0; idx < arguments.size(); ++idx) for (size_t idx = 0; idx < arguments.size(); ++idx)
{ {
//partial const column //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(); const IColumn * column = columns_holder[idx].get();
if (!(executeNumber<UInt8>(*column, out_vec, idx, input_rows_count, size_per_row) 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<Float32>(*column, out_vec, idx, input_rows_count, size_per_row)
|| executeNumber<Float64>(*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}; + " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
} }
} }
columns[result].column = std::move(col_str); return col_str;
} }
private: 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(); const IColumn * in_column = arguments[0].column.get();
ColumnPtr & out_column = columns[result].column; ColumnPtr out_column;
if (tryExecute<UInt8>(in_column, out_column) || if (tryExecute<UInt8>(in_column, out_column) ||
tryExecute<UInt16>(in_column, out_column) || tryExecute<UInt16>(in_column, out_column) ||
@ -1474,9 +1474,9 @@ public:
tryExecute<Int16>(in_column, out_column) || tryExecute<Int16>(in_column, out_column) ||
tryExecute<Int32>(in_column, out_column) || tryExecute<Int32>(in_column, out_column) ||
tryExecute<Int64>(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(), + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -1506,7 +1506,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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); 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); 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(); const IColumn * column = arguments[0].column.get();
ColumnPtr & res_column = columns[result].column; ColumnPtr res_column;
if (tryExecuteFixedString(column, res_column) || tryExecuteString(column, 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(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -1648,7 +1648,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override 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) if (!first_argument || first_argument->getN() != IPV6_BINARY_LENGTH)
throw Exception("Illegal type " + arguments[0]->getName() + throw Exception("Illegal type " + arguments[0]->getName() +
" of first argument of function " + getName() + " of first argument of function " + getName() +
@ -1659,7 +1659,7 @@ public:
if (!isUInt8(second_argument)) if (!isUInt8(second_argument))
throw Exception{"Illegal type " + second_argument->getName() throw Exception{"Illegal type " + second_argument->getName()
+ " of second argument of function " + 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"); DataTypePtr element = DataTypeFactory::instance().get("IPv6");
return std::make_shared<DataTypeTuple>(DataTypes{element, element}); return std::make_shared<DataTypeTuple>(DataTypes{element, element});
@ -1668,38 +1668,38 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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 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) if (!col_ip_in && !col_const_ip_in)
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
if (col_ip_in->getN() != IPV6_BINARY_LENGTH) if ((col_const_ip_in && col_const_ip_in->getValue<String>().size() != IPV6_BINARY_LENGTH) ||
throw Exception("Illegal type " + col_type_name_ip.type->getName() + (col_ip_in && col_ip_in->getN() != IPV6_BINARY_LENGTH))
" of column " + col_ip_in->getName() + throw Exception("Illegal type " + col_type_name_ip.type->getName() +
" argument of function " + getName() + " of column " + column_ip->getName() +
", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")", " argument of function " + getName() +
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); ", 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 ColumnPtr & column_cidr = col_type_name_cidr.column;
const auto col_const_cidr_in = checkAndGetColumnConst<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()); const auto * col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
if (!col_const_cidr_in && !col_cidr_in) 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(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
const auto & vec_in = col_ip_in->getChars();
auto col_res_lower_range = ColumnFixedString::create(IPV6_BINARY_LENGTH); auto col_res_lower_range = ColumnFixedString::create(IPV6_BINARY_LENGTH);
auto col_res_upper_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; 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) for (size_t offset = 0; offset < input_rows_count; ++offset)
{ {
const size_t offset_ipv6 = offset * IPV6_BINARY_LENGTH; 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 UInt8 cidr = col_const_cidr_in
? col_const_cidr_in->getValue<UInt8>() ? col_const_cidr_in->getValue<UInt8>()
: col_cidr_in->getData()[offset]; : col_cidr_in->getData()[offset];
cidr = std::min(cidr, max_cidr_mask); 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)) if (!isUInt8(second_argument))
throw Exception{"Illegal type " + second_argument->getName() throw Exception{"Illegal type " + second_argument->getName()
+ " of second argument of function " + 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"); DataTypePtr element = DataTypeFactory::instance().get("IPv4");
return std::make_shared<DataTypeTuple>(DataTypes{element, element}); return std::make_shared<DataTypeTuple>(DataTypes{element, element});
@ -1772,30 +1782,29 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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 ColumnPtr & column_ip = col_type_name_ip.column;
const auto col_ip_in = checkAndGetColumn<ColumnUInt32>(column_ip.get()); const auto * col_const_ip_in = checkAndGetColumnConst<ColumnUInt32>(column_ip.get());
if (!col_ip_in) const auto * col_ip_in = checkAndGetColumn<ColumnUInt32>(column_ip.get());
throw Exception("Illegal column " + columns[arguments[0]].column->getName() if (!col_const_ip_in && !col_ip_in)
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); 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 ColumnPtr & column_cidr = col_type_name_cidr.column;
const auto col_const_cidr_in = checkAndGetColumnConst<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()); const auto * col_cidr_in = checkAndGetColumn<ColumnUInt8>(column_cidr.get());
if (!col_const_cidr_in && !col_cidr_in) 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(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
const auto & vec_in = col_ip_in->getData();
auto col_res_lower_range = ColumnUInt32::create(); auto col_res_lower_range = ColumnUInt32::create();
auto col_res_upper_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) 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 UInt8 cidr = col_const_cidr_in
? col_const_cidr_in->getValue<UInt8>() ? col_const_cidr_in->getValue<UInt8>()
: col_cidr_in->getData()[i]; : 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 constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionComparison>(context); } static FunctionPtr create(const Context & context) { return std::make_shared<FunctionComparison>(context); }
FunctionComparison(const Context & context_) explicit FunctionComparison(const Context & context_)
: context(context_), : context(context_),
check_decimal_overflow(decimalCheckComparisonOverflow(context)) check_decimal_overflow(decimalCheckComparisonOverflow(context))
{} {}
@ -571,7 +571,7 @@ private:
bool check_decimal_overflow = true; bool check_decimal_overflow = true;
template <typename T0, typename T1> 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)) if (const ColumnVector<T1> * col_right = checkAndGetColumn<ColumnVector<T1>>(col_right_untyped))
{ {
@ -581,8 +581,7 @@ private:
vec_res.resize(col_left->getData().size()); vec_res.resize(col_left->getData().size());
NumComparisonImpl<T0, T1, Op<T0, T1>>::vectorVector(col_left->getData(), col_right->getData(), vec_res); NumComparisonImpl<T0, T1, Op<T0, T1>>::vectorVector(col_left->getData(), col_right->getData(), vec_res);
columns[result].column = std::move(col_res); return col_res;
return true;
} }
else if (auto col_right_const = checkAndGetColumnConst<ColumnVector<T1>>(col_right_untyped)) else if (auto col_right_const = checkAndGetColumnConst<ColumnVector<T1>>(col_right_untyped))
{ {
@ -592,15 +591,14 @@ private:
vec_res.resize(col_left->size()); vec_res.resize(col_left->size());
NumComparisonImpl<T0, T1, Op<T0, T1>>::vectorConstant(col_left->getData(), col_right_const->template getValue<T1>(), vec_res); 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 col_res;
return true;
} }
return false; return nullptr;
} }
template <typename T0, typename T1> 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)) if (const ColumnVector<T1> * col_right = checkAndGetColumn<ColumnVector<T1>>(col_right_untyped))
{ {
@ -610,41 +608,40 @@ private:
vec_res.resize(col_left->size()); vec_res.resize(col_left->size());
NumComparisonImpl<T0, T1, Op<T0, T1>>::constantVector(col_left->template getValue<T0>(), col_right->getData(), vec_res); 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 col_res;
return true;
} }
else if (auto col_right_const = checkAndGetColumnConst<ColumnVector<T1>>(col_right_untyped)) else if (auto col_right_const = checkAndGetColumnConst<ColumnVector<T1>>(col_right_untyped))
{ {
UInt8 res = 0; UInt8 res = 0;
NumComparisonImpl<T0, T1, Op<T0, T1>>::constantConstant(col_left->template getValue<T0>(), col_right_const->template getValue<T1>(), res); 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 DataTypeUInt8().createColumnConst(col_left->size(), toField(res));
return true;
} }
return false; return nullptr;
} }
template <typename T0> 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 (const ColumnVector<T0> * col_left = checkAndGetColumn<ColumnVector<T0>>(col_left_untyped))
{ {
if ( executeNumRightType<T0, UInt8>(columns, result, col_left, col_right_untyped) if ( (res = executeNumRightType<T0, UInt8>(col_left, col_right_untyped))
|| executeNumRightType<T0, UInt16>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, UInt16>(col_left, col_right_untyped))
|| executeNumRightType<T0, UInt32>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, UInt32>(col_left, col_right_untyped))
|| executeNumRightType<T0, UInt64>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, UInt64>(col_left, col_right_untyped))
|| executeNumRightType<T0, UInt128>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, UInt128>(col_left, col_right_untyped))
|| executeNumRightType<T0, UInt256>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, UInt256>(col_left, col_right_untyped))
|| executeNumRightType<T0, Int8>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Int8>(col_left, col_right_untyped))
|| executeNumRightType<T0, Int16>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Int16>(col_left, col_right_untyped))
|| executeNumRightType<T0, Int32>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Int32>(col_left, col_right_untyped))
|| executeNumRightType<T0, Int64>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Int64>(col_left, col_right_untyped))
|| executeNumRightType<T0, Int128>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Int128>(col_left, col_right_untyped))
|| executeNumRightType<T0, Int256>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Int256>(col_left, col_right_untyped))
|| executeNumRightType<T0, Float32>(columns, result, col_left, col_right_untyped) || (res = executeNumRightType<T0, Float32>(col_left, col_right_untyped))
|| executeNumRightType<T0, Float64>(columns, result, col_left, col_right_untyped)) || (res = executeNumRightType<T0, Float64>(col_left, col_right_untyped)))
return true; return res;
else else
throw Exception("Illegal column " + col_right_untyped->getName() throw Exception("Illegal column " + col_right_untyped->getName()
+ " of second argument of function " + getName(), + " of second argument of function " + getName(),
@ -652,34 +649,35 @@ private:
} }
else if (auto col_left_const = checkAndGetColumnConst<ColumnVector<T0>>(col_left_untyped)) else if (auto col_left_const = checkAndGetColumnConst<ColumnVector<T0>>(col_left_untyped))
{ {
if ( executeNumConstRightType<T0, UInt8>(columns, result, col_left_const, col_right_untyped) if ( (res = executeNumConstRightType<T0, UInt8>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, UInt16>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, UInt16>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, UInt32>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, UInt32>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, UInt64>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, UInt64>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, UInt128>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, UInt128>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, UInt256>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, UInt256>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Int8>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Int8>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Int16>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Int16>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Int32>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Int32>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Int64>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Int64>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Int128>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Int128>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Int256>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Int256>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Float32>(columns, result, col_left_const, col_right_untyped) || (res = executeNumConstRightType<T0, Float32>(col_left_const, col_right_untyped))
|| executeNumConstRightType<T0, Float64>(columns, result, col_left_const, col_right_untyped)) || (res = executeNumConstRightType<T0, Float64>(col_left_const, col_right_untyped)))
return true; return res;
else else
throw Exception("Illegal column " + col_right_untyped->getName() throw Exception("Illegal column " + col_right_untyped->getName()
+ " of second argument of function " + getName(), + " of second argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); 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 left_number = col_left.type->getTypeId();
TypeIndex right_number = col_right.type->getTypeId(); TypeIndex right_number = col_right.type->getTypeId();
ColumnPtr res;
auto call = [&](const auto & types) -> bool auto call = [&](const auto & types) -> bool
{ {
@ -688,18 +686,19 @@ private:
using RightDataType = typename Types::RightType; using RightDataType = typename Types::RightType;
if (check_decimal_overflow) 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 else
DecimalComparison<LeftDataType, RightDataType, Op, false>(columns, result, col_left, col_right); return (res = DecimalComparison<LeftDataType, RightDataType, Op, false>::apply(col_left, col_right)) != nullptr;
return true;
}; };
if (!callOnBasicTypes<true, false, true, true>(left_number, right_number, call)) 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(), throw Exception("Wrong call for " + getName() + " with " + col_left.type->getName() + " and " + col_right.type->getName(),
ErrorCodes::LOGICAL_ERROR); 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 * c0_string = checkAndGetColumn<ColumnString>(c0);
const ColumnString * c1_string = checkAndGetColumn<ColumnString>(c1); const ColumnString * c1_string = checkAndGetColumn<ColumnString>(c1);
@ -710,7 +709,7 @@ private:
const ColumnConst * c1_const = checkAndGetColumnConstStringOrFixedString(c1); const ColumnConst * c1_const = checkAndGetColumnConstStringOrFixedString(c1);
if (!((c0_string || c0_fixed_string || c0_const) && (c1_string || c1_fixed_string || c1_const))) 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 * c0_const_chars = nullptr;
const ColumnString::Chars * c1_const_chars = nullptr; const ColumnString::Chars * c1_const_chars = nullptr;
@ -759,12 +758,11 @@ private:
if (c0_const && c1_const) 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) if (!res)
return false; return nullptr;
columns[result].column = ColumnConst::create(columns[result].column, c0_const->size()); return ColumnConst::create(res, c0_const->size());
return true;
} }
else else
{ {
@ -818,13 +816,12 @@ private:
+ " of arguments of function " + getName(), + " of arguments of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
columns[result].column = std::move(c_res); return c_res;
return true;
} }
} }
bool executeWithConstString( ColumnPtr executeWithConstString(
ColumnsWithTypeAndName & columns, size_t result, const IColumn * col_left_untyped, const IColumn * col_right_untyped, 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 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. /// 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); const ColumnConst * right_const = checkAndGetColumnConstStringOrFixedString(col_right_untyped);
if (!left_const && !right_const) if (!left_const && !right_const)
return false; return nullptr;
const IDataType * type_string = left_const ? left_type.get() : right_type.get(); const IDataType * type_string = left_const ? left_type.get() : right_type.get();
const DataTypePtr & type_to_compare = !left_const ? left_type : right_type; 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 not possible to convert, comparison with =, <, >, <=, >= yields to false and comparison with != yields to true.
if (converted.isNull()) 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 else
{ {
auto column_converted = type_to_compare->createColumnConst(input_rows_count, converted); 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_left_untyped->getPtr(), type_to_compare, "" },
{ !left_const ? column_converted : col_right_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); return executeImpl(tmp_columns, result_type, input_rows_count);
columns[result].column = std::move(tmp_columns_columns[2].column);
} }
return true;
} }
void executeTuple(ColumnsWithTypeAndName & columns, size_t result, const ColumnWithTypeAndName & c0, const ColumnWithTypeAndName & c1, ColumnPtr executeTuple(
size_t input_rows_count) const 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: /** We will lexicographically compare the tuples. This is done as follows:
* x == y : x1 == y1 && x2 == y2 ... * x == y : x1 == y1 && x2 == y2 ...
@ -892,12 +885,8 @@ private:
if (tuple_size != typeid_cast<const DataTypeTuple &>(*c1.type).getElements().size()) if (tuple_size != typeid_cast<const DataTypeTuple &>(*c1.type).getElements().size())
throw Exception("Cannot compare tuples of different sizes.", ErrorCodes::BAD_ARGUMENTS); throw Exception("Cannot compare tuples of different sizes.", ErrorCodes::BAD_ARGUMENTS);
auto & res = columns[result]; if (result_type->onlyNull())
if (res.type->onlyNull()) return result_type->createColumnConstWithDefaultValue(input_rows_count);
{
res.column = res.type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
ColumnsWithTypeAndName x(tuple_size); ColumnsWithTypeAndName x(tuple_size);
ColumnsWithTypeAndName y(tuple_size); ColumnsWithTypeAndName y(tuple_size);
@ -927,18 +916,16 @@ private:
y[i].column = y_columns[i]; 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, const ColumnsWithTypeAndName & y, size_t tuple_size,
size_t input_rows_count) const; size_t input_rows_count) const;
void executeTupleEqualityImpl( ColumnPtr executeTupleEqualityImpl(
std::shared_ptr<IFunctionOverloadResolver> func_compare, std::shared_ptr<IFunctionOverloadResolver> func_compare,
std::shared_ptr<IFunctionOverloadResolver> func_convolution, std::shared_ptr<IFunctionOverloadResolver> func_convolution,
ColumnsWithTypeAndName & columns,
size_t result,
const ColumnsWithTypeAndName & x, const ColumnsWithTypeAndName & x,
const ColumnsWithTypeAndName & y, const ColumnsWithTypeAndName & y,
size_t tuple_size, size_t tuple_size,
@ -947,84 +934,70 @@ private:
if (0 == tuple_size) if (0 == tuple_size)
throw Exception("Comparison of zero-sized tuples is not implemented.", ErrorCodes::NOT_IMPLEMENTED); 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) for (size_t i = 0; i < tuple_size; ++i)
{ {
tmp_columns.emplace_back(x[i]); tmp_columns[0] = x[i];
tmp_columns.emplace_back(y[i]); tmp_columns[1] = y[i];
auto impl = func_compare->build({x[i], y[i]}); auto impl = func_compare->build(tmp_columns);
convolution_types[i].type = impl->getReturnType(); convolution_columns[i].type = impl->getResultType();
/// Comparison of the elements. /// Comparison of the elements.
tmp_columns.emplace_back(ColumnWithTypeAndName{ nullptr, impl->getReturnType(), "" }); convolution_columns[i].column = impl->execute(tmp_columns, impl->getResultType(), input_rows_count);
impl->execute(tmp_columns, {i * 3, i * 3 + 1}, i * 3 + 2, input_rows_count);
} }
if (tuple_size == 1) if (tuple_size == 1)
{ {
/// Do not call AND for single-element tuple. /// Do not call AND for single-element tuple.
columns[result].column = tmp_columns[2].column; return convolution_columns[0].column;
return;
} }
/// Logical convolution. /// Logical convolution.
auto impl = func_convolution->build(convolution_columns);
ColumnNumbers convolution_args(tuple_size); return impl->execute(convolution_columns, impl->getResultType(), input_rows_count);
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;
} }
void executeTupleLessGreaterImpl( ColumnPtr executeTupleLessGreaterImpl(
std::shared_ptr<IFunctionOverloadResolver> func_compare_head, std::shared_ptr<IFunctionOverloadResolver> func_compare_head,
std::shared_ptr<IFunctionOverloadResolver> func_compare_tail, std::shared_ptr<IFunctionOverloadResolver> func_compare_tail,
std::shared_ptr<IFunctionOverloadResolver> func_and, std::shared_ptr<IFunctionOverloadResolver> func_and,
std::shared_ptr<IFunctionOverloadResolver> func_or, std::shared_ptr<IFunctionOverloadResolver> func_or,
std::shared_ptr<IFunctionOverloadResolver> func_equals, std::shared_ptr<IFunctionOverloadResolver> func_equals,
ColumnsWithTypeAndName & columns,
size_t result,
const ColumnsWithTypeAndName & x, const ColumnsWithTypeAndName & x,
const ColumnsWithTypeAndName & y, const ColumnsWithTypeAndName & y,
size_t tuple_size, size_t tuple_size,
size_t input_rows_count) const 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. /// 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]) /// (x[i], y[i], x[i] < y[i], x[i] == y[i])
for (size_t i = 0; i < tuple_size; ++i) for (size_t i = 0; i < tuple_size; ++i)
{ {
tmp_columns.emplace_back(x[i]); tmp_columns[0] = x[i];
tmp_columns.emplace_back(y[i]); tmp_columns[1] = y[i];
tmp_columns.emplace_back(ColumnWithTypeAndName()); // pos == i * 4 + 2
if (i + 1 != tuple_size) if (i + 1 != tuple_size)
{ {
auto impl_head = func_compare_head->build({x[i], y[i]}); auto impl_head = func_compare_head->build(tmp_columns);
tmp_columns[i * 4 + 2].type = impl_head->getReturnType(); less_columns[i].type = impl_head->getResultType();
impl_head->execute(tmp_columns, {i * 4, i * 4 + 1}, i * 4 + 2, input_rows_count); 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(tmp_columns);
equal_columns[i].type = impl_equals->getResultType();
auto impl_equals = func_equals->build({x[i], y[i]}); equal_columns[i].column = impl_equals->execute(tmp_columns, equal_columns[i].type, input_rows_count);
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);
} }
else else
{ {
auto impl_tail = func_compare_tail->build({x[i], y[i]}); auto impl_tail = func_compare_tail->build(tmp_columns);
tmp_columns[i * 4 + 2].type = impl_tail->getReturnType(); less_columns[i].type = impl_tail->getResultType();
impl_tail->execute(tmp_columns, {i * 4, i * 4 + 1}, i * 4 + 2, input_rows_count); 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) /// for (int i = tuple_size - 2; i >= 0; --i)
/// res = (res && `x == y`[i]) || `x < y`[i]; /// res = (res && `x == y`[i]) || `x < y`[i];
size_t i = tuple_size - 1; size_t i = tuple_size - 1;
tmp_columns[0] = less_columns[i];
while (i > 0) while (i > 0)
{ {
--i; --i;
size_t and_lhs_pos = tmp_columns.size() - 1; // res tmp_columns[1] = equal_columns[i];
size_t and_rhs_pos = i * 4 + 3; // `x == y`[i] auto func_and_adaptor = func_and->build(tmp_columns);
tmp_columns.emplace_back(ColumnWithTypeAndName());
ColumnsWithTypeAndName and_args = {{ nullptr, tmp_columns[and_lhs_pos].type, "" }, tmp_columns[0].column = func_and_adaptor->execute(tmp_columns, func_and_adaptor->getResultType(), input_rows_count);
{ nullptr, tmp_columns[and_rhs_pos].type, "" }}; tmp_columns[0].type = func_and_adaptor->getResultType();
auto func_and_adaptor = func_and->build(and_args); tmp_columns[1] = less_columns[i];
tmp_columns[tmp_columns.size() - 1].type = func_and_adaptor->getReturnType(); auto func_or_adaptor = func_or->build(tmp_columns);
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[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 c0_const = isColumnConst(*c0);
bool c1_const = isColumnConst(*c1); bool c1_const = isColumnConst(*c1);
@ -1075,7 +1038,7 @@ private:
{ {
UInt8 res = 0; UInt8 res = 0;
GenericComparisonImpl<Op<int, int>>::constantConstant(*c0, *c1, res); 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 else
{ {
@ -1090,18 +1053,18 @@ private:
else else
GenericComparisonImpl<Op<int, int>>::vectorVector(*c0, *c1, vec_res); 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}); DataTypePtr common_type = getLeastSupertype({c0.type, c1.type});
ColumnPtr c0_converted = castColumn(c0, common_type); ColumnPtr c0_converted = castColumn(c0, common_type);
ColumnPtr c1_converted = castColumn(c1, 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: public:
@ -1157,7 +1120,7 @@ public:
{ {
ColumnsWithTypeAndName args = {{nullptr, left_tuple->getElements()[i], ""}, ColumnsWithTypeAndName args = {{nullptr, left_tuple->getElements()[i], ""},
{nullptr, right_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_nullable = has_nullable || element_type->isNullable();
has_null = has_null || element_type->onlyNull(); has_null = has_null || element_type->onlyNull();
} }
@ -1173,10 +1136,10 @@ public:
return std::make_shared<DataTypeUInt8>(); 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_left = arguments[0];
const auto & col_with_type_and_name_right = columns[arguments[1]]; 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_left_untyped = col_with_type_and_name_left.column.get();
const IColumn * col_right_untyped = col_with_type_and_name_right.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>::less_or_equals
|| IsOperation<Op>::greater_or_equals) || IsOperation<Op>::greater_or_equals)
{ {
columns[result].column = DataTypeUInt8().createColumnConst(input_rows_count, 1u); return DataTypeUInt8().createColumnConst(input_rows_count, 1u);
return;
} }
else else
{ {
columns[result].column = DataTypeUInt8().createColumnConst(input_rows_count, 0u); return DataTypeUInt8().createColumnConst(input_rows_count, 0u);
return;
} }
} }
@ -1216,39 +1177,44 @@ public:
bool date_and_datetime = (which_left.idx != which_right.idx) && bool date_and_datetime = (which_left.idx != which_right.idx) &&
which_left.isDateOrDateTime() && which_right.isDateOrDateTime(); which_left.isDateOrDateTime() && which_right.isDateOrDateTime();
ColumnPtr res;
if (left_is_num && right_is_num && !date_and_datetime) if (left_is_num && right_is_num && !date_and_datetime)
{ {
if (!(executeNumLeftType<UInt8>(columns, result, col_left_untyped, col_right_untyped) if (!((res = executeNumLeftType<UInt8>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<UInt16>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<UInt16>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<UInt32>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<UInt32>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<UInt64>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<UInt64>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<UInt128>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<UInt128>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<UInt256>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<UInt256>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Int8>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Int8>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Int16>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Int16>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Int32>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Int32>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Int64>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Int64>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Int128>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Int128>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Int256>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Int256>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Float32>(columns, result, col_left_untyped, col_right_untyped) || (res = executeNumLeftType<Float32>(col_left_untyped, col_right_untyped))
|| executeNumLeftType<Float64>(columns, result, col_left_untyped, col_right_untyped))) || (res = executeNumLeftType<Float64>(col_left_untyped, col_right_untyped))))
throw Exception("Illegal column " + col_left_untyped->getName() throw Exception("Illegal column " + col_left_untyped->getName()
+ " of first argument of function " + getName(), + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
return res;
} }
else if (checkAndGetDataType<DataTypeTuple>(left_type.get()) else if (checkAndGetDataType<DataTypeTuple>(left_type.get())
&& checkAndGetDataType<DataTypeTuple>(right_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( else if ((res = executeWithConstString(
columns, result, col_left_untyped, col_right_untyped, result_type, col_left_untyped, col_right_untyped,
left_type, right_type, left_type, right_type,
input_rows_count)) input_rows_count)))
{ {
return res;
} }
else if (isColumnedAsDecimal(left_type) || isColumnedAsDecimal(right_type)) 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(), throw Exception("No operation " + getName() + " between " + left_type->getName() + " and " + right_type->getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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)) 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 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}; 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)) if (isColumnConst(*arguments[1].column))
executeConstBuckets(columns, arguments, result); return executeConstBuckets(arguments);
else else
throw Exception( throw Exception(
"The second argument of function " + getName() + " (number of buckets) must be constant", ErrorCodes::BAD_ARGUMENTS); "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); 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; BucketsType num_buckets;
if (buckets_field.getType() == Field::Types::Int64) 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(), throw Exception("Illegal type " + String(buckets_field.getTypeName()) + " of the second argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
const auto & hash_col = columns[arguments[0]].column; const auto & hash_col = arguments[0].column;
const IDataType * hash_type = columns[arguments[0]].type.get(); const IDataType * hash_type = arguments[0].type.get();
auto res_col = ColumnVector<ResultType>::create(); auto res_col = ColumnVector<ResultType>::create();
WhichDataType which(hash_type); WhichDataType which(hash_type);
@ -132,7 +132,7 @@ private:
throw Exception("Illegal type " + hash_type->getName() + " of the first argument of function " + getName(), throw Exception("Illegal type " + hash_type->getName() + " of the first argument of function " + getName(),
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
columns[result].column = std::move(res_col); return res_col;
} }
template <typename CurrentHashType> 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; } 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". /// The dictionary key that defines the "point of view".
std::string dict_key; std::string dict_key;
if (arguments.size() == 2) 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) 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 + " of second ('point of view') argument of function " + name
+ ". Must be constant string.", + ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
@ -203,7 +203,7 @@ public:
const typename DictGetter::Dst & dict = DictGetter::get(*owned_dict, dict_key); 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(); auto col_to = ColumnVector<T>::create();
@ -215,10 +215,10 @@ public:
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(vec_from[i], dict); vec_to[i] = Transform::apply(vec_from[i], dict);
columns[result].column = std::move(col_to); return col_to;
} }
else else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + name, + " of first argument of function " + name,
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -279,17 +279,17 @@ public:
bool isDeterministic() const override { return false; } 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". /// The dictionary key that defines the "point of view".
std::string dict_key; std::string dict_key;
if (arguments.size() == 3) 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) 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 + " of third ('point of view') argument of function " + name
+ ". Must be constant string.", + ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
@ -299,10 +299,10 @@ public:
const typename DictGetter::Dst & dict = DictGetter::get(*owned_dict, dict_key); 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_vec1 = checkAndGetColumn<ColumnVector<T>>(arguments[0].column.get());
const ColumnVector<T> * col_vec2 = checkAndGetColumn<ColumnVector<T>>(columns[arguments[1]].column.get()); const ColumnVector<T> * col_vec2 = checkAndGetColumn<ColumnVector<T>>(arguments[1].column.get());
const ColumnConst * col_const1 = checkAndGetColumnConst<ColumnVector<T>>(columns[arguments[0]].column.get()); const ColumnConst * col_const1 = checkAndGetColumnConst<ColumnVector<T>>(arguments[0].column.get());
const ColumnConst * col_const2 = checkAndGetColumnConst<ColumnVector<T>>(columns[arguments[1]].column.get()); const ColumnConst * col_const2 = checkAndGetColumnConst<ColumnVector<T>>(arguments[1].column.get());
if (col_vec1 && col_vec2) if (col_vec1 && col_vec2)
{ {
@ -317,7 +317,7 @@ public:
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(vec_from1[i], vec_from2[i], dict); 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) else if (col_vec1 && col_const2)
{ {
@ -332,7 +332,7 @@ public:
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(vec_from1[i], const_from2, dict); 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) else if (col_const1 && col_vec2)
{ {
@ -347,16 +347,16 @@ public:
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
vec_to[i] = Transform::apply(const_from1, vec_from2[i], dict); 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) 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))); toField(Transform::apply(col_const1->template getValue<T>(), col_const2->template getValue<T>(), dict)));
} }
else else
throw Exception("Illegal columns " + columns[arguments[0]].column->getName() throw Exception("Illegal columns " + arguments[0].column->getName()
+ " and " + columns[arguments[1]].column->getName() + " and " + arguments[1].column->getName()
+ " of arguments of function " + name, + " of arguments of function " + name,
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -415,17 +415,17 @@ public:
bool isDeterministic() const override { return false; } 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". /// The dictionary key that defines the "point of view".
std::string dict_key; std::string dict_key;
if (arguments.size() == 2) 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) 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 + " of second ('point of view') argument of function " + name
+ ". Must be constant string.", + ". Must be constant string.",
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
@ -435,7 +435,7 @@ public:
const typename DictGetter::Dst & dict = DictGetter::get(*owned_dict, dict_key); 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_values = ColumnVector<T>::create();
auto col_offsets = ColumnArray::ColumnOffsets::create(); auto col_offsets = ColumnArray::ColumnOffsets::create();
@ -459,10 +459,10 @@ public:
res_offsets[i] = res_values.size(); 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 else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + name, + " of first argument of function " + name,
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -620,24 +620,24 @@ public:
bool isDeterministic() const override { return false; } 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; RegionsNames::Language language = RegionsNames::Language::ru;
/// If the result language is specified /// If the result language is specified
if (arguments.size() == 2) 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>()); language = RegionsNames::getLanguageEnum(col_language->getValue<String>());
else 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(), + " of the second argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
const RegionsNames & dict = *owned_dict; 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(); auto col_to = ColumnString::create();
@ -649,10 +649,10 @@ public:
col_to->insertDataWithTerminatingZero(name_ref.data, name_ref.size + 1); col_to->insertDataWithTerminatingZero(name_ref.data, name_ref.size + 1);
} }
columns[result].column = std::move(col_to); return col_to;
} }
else 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(), + " of the first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); 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; 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) if (!name_col)
throw Exception("First argument of function " + getName() + " must be a constant string", throw Exception("First argument of function " + getName() + " must be a constant string",
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
@ -85,7 +85,7 @@ void FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & columns, const
column_ptrs.reserve(arguments.size()); column_ptrs.reserve(arguments.size());
for (auto arg : ext::range(1, 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()); column_ptrs.push_back(column.get());
if (auto full_column = column->convertToFullColumnIfConst()) if (auto full_column = column->convertToFullColumnIfConst())
{ {
@ -130,7 +130,7 @@ void FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & columns, const
res = ColumnNullable::create(res, null_map); res = ColumnNullable::create(res, null_map);
} }
columns[result].column = res; return res;
} }
void registerFunctionsExternalModels(FunctionFactory & factory) void registerFunctionsExternalModels(FunctionFactory & factory)

View File

@ -32,7 +32,7 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override; 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: private:
const ExternalModelsLoader & models_loader; const ExternalModelsLoader & models_loader;

View File

@ -543,9 +543,9 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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); auto col_to = ColumnFixedString::create(Impl::length);
@ -566,10 +566,10 @@ public:
current_offset = offsets[i]; current_offset = offsets[i];
} }
columns[result].column = std::move(col_to); return col_to;
} }
else if ( 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); auto col_to = ColumnFixedString::create(Impl::length);
const typename ColumnFixedString::Chars & data = col_from_fix->getChars(); const typename ColumnFixedString::Chars & data = col_from_fix->getChars();
@ -582,10 +582,10 @@ public:
Impl::apply( Impl::apply(
reinterpret_cast<const char *>(&data[i * length]), length, reinterpret_cast<uint8_t *>(&chars_to[i * Impl::length])); 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 else
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName(), + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -604,11 +604,11 @@ private:
using ToType = typename Impl::ReturnType; using ToType = typename Impl::ReturnType;
template <typename FromType> 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>>; 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(); auto col_to = ColumnVector<ToType>::create();
@ -620,10 +620,10 @@ private:
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
vec_to[i] = Impl::apply(vec_from[i]); vec_to[i] = Impl::apply(vec_from[i]);
columns[result].column = std::move(col_to); return col_to;
} }
else 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, + " of first argument of function " + Name::name,
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }
@ -647,25 +647,37 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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); WhichDataType which(from_type);
if (which.isUInt8()) executeType<UInt8>(columns, arguments, result); if (which.isUInt8())
else if (which.isUInt16()) executeType<UInt16>(columns, arguments, result); return executeType<UInt8>(arguments);
else if (which.isUInt32()) executeType<UInt32>(columns, arguments, result); else if (which.isUInt16())
else if (which.isUInt64()) executeType<UInt64>(columns, arguments, result); return executeType<UInt16>(arguments);
else if (which.isInt8()) executeType<Int8>(columns, arguments, result); else if (which.isUInt32())
else if (which.isInt16()) executeType<Int16>(columns, arguments, result); return executeType<UInt32>(arguments);
else if (which.isInt32()) executeType<Int32>(columns, arguments, result); else if (which.isUInt64())
else if (which.isInt64()) executeType<Int64>(columns, arguments, result); return executeType<UInt64>(arguments);
else if (which.isDate()) executeType<UInt16>(columns, arguments, result); else if (which.isInt8())
else if (which.isDateTime()) executeType<UInt32>(columns, arguments, result); return executeType<Int8>(arguments);
else if (which.isDecimal32()) executeType<Decimal32>(columns, arguments, result); else if (which.isInt16())
else if (which.isDecimal64()) executeType<Decimal64>(columns, arguments, result); 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 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); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
} }
}; };
@ -689,9 +701,9 @@ public:
#endif #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) static FunctionPtr create(const Context & context)
@ -886,7 +898,7 @@ private:
} }
else if (const ColumnConst * col_from_const = checkAndGetColumnConstStringOrFixedString(column)) 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 ToType hash = Impl::apply(value.data(), value.size());
const size_t size = vec_to.size(); const size_t size = vec_to.size();
@ -1041,7 +1053,7 @@ public:
return std::make_shared<DataTypeNumber<ToType>>(); 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; size_t rows = input_rows_count;
auto col_to = ColumnVector<ToType>::create(rows); auto col_to = ColumnVector<ToType>::create(rows);
@ -1057,13 +1069,10 @@ public:
/// The function supports arbitrary number of arguments of arbitrary types. /// The function supports arbitrary number of arguments of arbitrary types.
bool is_first_argument = true; bool is_first_argument = true;
for (size_t i = 0; i < arguments.size(); ++i) for (const auto & col : arguments)
{
const ColumnWithTypeAndName & col = columns[arguments[i]];
executeForArgument(col.type.get(), col.column.get(), vec_to, is_first_argument); 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 #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) 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) 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 /// 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 " + 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}; 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()) if (!WhichDataType(first_arg).isString())
throw Exception{"Illegal type " + first_arg->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; 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; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; } 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(); const auto arg_count = arguments.size();
if (arg_count == 1) if (arg_count == 1)
executeSingleArg(columns, arguments, result); return executeSingleArg(arguments);
else if (arg_count == 2) else if (arg_count == 2)
executeTwoArgs(columns, arguments, result); return executeTwoArgs(arguments);
else else
throw Exception{"got into IFunction::execute with unexpected number of arguments", ErrorCodes::LOGICAL_ERROR}; throw Exception{"got into IFunction::execute with unexpected number of arguments", ErrorCodes::LOGICAL_ERROR};
} }
private: 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(); const auto size = col_from->size();
auto col_to = ColumnUInt64::create(size); auto col_to = ColumnUInt64::create(size);
@ -1245,23 +1254,23 @@ private:
current_offset = offsets[i]; current_offset = offsets[i];
} }
columns[result].column = std::move(col_to); return col_to;
} }
else 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}; " 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)) if (!isColumnConst(*level_col))
throw Exception{"Second argument of function " + getName() + " must be an integral constant", ErrorCodes::ILLEGAL_COLUMN}; throw Exception{"Second argument of function " + getName() + " must be an integral constant", ErrorCodes::ILLEGAL_COLUMN};
const auto level = level_col->get64(0); const auto level = level_col->get64(0);
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(); const auto size = col_from->size();
auto col_to = ColumnUInt64::create(size); auto col_to = ColumnUInt64::create(size);
@ -1281,10 +1290,10 @@ private:
current_offset = offsets[i]; current_offset = offsets[i];
} }
columns[result].column = std::move(col_to); return col_to;
} }
else 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}; " 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; std::vector<Move> moves;
moves.reserve(num_index_arguments); moves.reserve(num_index_arguments);
for (const auto i : ext::range(first_index_argument, first_index_argument + 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)) if (!isString(column.type) && !isInteger(column.type))
throw Exception{"The argument " + std::to_string(i + 1) + " of function " + String(function_name) 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(), + " 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 class Executor
{ {
public: 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); 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}; 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)) 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(), 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}; ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
const ColumnPtr & arg_json = first_column.column; const ColumnPtr & arg_json = first_column.column;
auto col_json_const = typeid_cast<const ColumnConst *>(arg_json.get()); const auto * col_json_const = typeid_cast<const ColumnConst *>(arg_json.get());
auto col_json_string const auto * col_json_string
= typeid_cast<const ColumnString *>(col_json_const ? col_json_const->getDataColumnPtr().get() : arg_json.get()); = typeid_cast<const ColumnString *>(col_json_const ? col_json_const->getDataColumnPtr().get() : arg_json.get());
if (!col_json_string) if (!col_json_string)
@ -79,8 +79,8 @@ public:
const ColumnString::Chars & chars = col_json_string->getChars(); const ColumnString::Chars & chars = col_json_string->getChars();
const ColumnString::Offsets & offsets = col_json_string->getOffsets(); const ColumnString::Offsets & offsets = col_json_string->getOffsets();
size_t num_index_arguments = Impl<JSONParser>::getNumberOfIndexArguments(columns, arguments); size_t num_index_arguments = Impl<JSONParser>::getNumberOfIndexArguments(arguments);
std::vector<Move> moves = prepareMoves(Name::name, columns, arguments, 1, num_index_arguments); std::vector<Move> moves = prepareMoves(Name::name, arguments, 1, num_index_arguments);
/// Preallocate memory in parser if necessary. /// Preallocate memory in parser if necessary.
JSONParser parser; JSONParser parser;
@ -94,8 +94,8 @@ public:
Impl<JSONParser> impl; Impl<JSONParser> impl;
/// prepare() does Impl-specific preparation before handling each row. /// 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) if constexpr (has_member_function_prepare<void (Impl<JSONParser>::*)(const char *, const ColumnsWithTypeAndName &, const DataTypePtr &)>::value)
impl.prepare(Name::name, columns, arguments, result_pos); impl.prepare(Name::name, arguments, result_type);
using Element = typename JSONParser::Element; using Element = typename JSONParser::Element;
@ -121,7 +121,7 @@ public:
/// Perform moves. /// Perform moves.
Element element; Element element;
std::string_view last_key; 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) if (moves_ok)
added_to_column = impl.insertResultToColumn(*to, element, last_key); added_to_column = impl.insertResultToColumn(*to, element, last_key);
@ -131,7 +131,7 @@ public:
if (!added_to_column) if (!added_to_column)
to->insertDefault(); to->insertDefault();
} }
columns[result_pos].column = std::move(to); return to;
} }
}; };
@ -166,11 +166,11 @@ private:
String key; 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. /// Performs moves of types MoveType::Index and MoveType::ConstIndex.
template <typename JSONParser> 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, const typename JSONParser::Element & document, const std::vector<Move> & moves,
typename JSONParser::Element & element, std::string_view & last_key) typename JSONParser::Element & element, std::string_view & last_key)
{ {
@ -196,14 +196,14 @@ private:
} }
case MoveType::Index: 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)) if (!moveToElementByIndex<JSONParser>(res_element, index, key))
return false; return false;
break; break;
} }
case MoveType::Key: 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)) if (!moveToElementByKey<JSONParser>(res_element, key))
return false; return false;
break; break;
@ -286,21 +286,18 @@ public:
return Impl<DummyJSONParser>::getReturnType(Name::name, arguments); 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. /// Choose JSONParser.
#if USE_SIMDJSON #if USE_SIMDJSON
if (context.getSettingsRef().allow_simdjson) if (context.getSettingsRef().allow_simdjson)
{ return FunctionJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(arguments, result_type, input_rows_count);
FunctionJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(columns, arguments, result_pos, input_rows_count);
return;
}
#endif #endif
#if USE_RAPIDJSON #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 #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 #endif
} }
@ -334,7 +331,7 @@ public:
static DataTypePtr getReturnType(const char *, const ColumnsWithTypeAndName &) { return std::make_shared<DataTypeUInt8>(); } 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 &) static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view &)
{ {
@ -362,7 +359,7 @@ public:
return std::make_shared<DataTypeUInt8>(); 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 &) static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view &)
{ {
@ -386,7 +383,7 @@ public:
return std::make_shared<DataTypeUInt64>(); 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 &) static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{ {
@ -416,7 +413,7 @@ public:
return std::make_shared<DataTypeString>(); 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) 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); 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 &) static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{ {
@ -492,7 +489,7 @@ public:
return std::make_shared<DataTypeNumber<NumberType>>(); 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 &) static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{ {
@ -557,7 +554,7 @@ public:
return std::make_shared<DataTypeUInt8>(); 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 &) static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{ {
@ -582,7 +579,7 @@ public:
return std::make_shared<DataTypeString>(); 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 &) 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>()); 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 &) bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
@ -950,11 +947,10 @@ public:
return std::make_unique<DataTypeArray>(tuple_type); 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 tuple_type = typeid_cast<const DataTypeArray *>(result_type.get())->getNestedType();
const auto value_type = typeid_cast<const DataTypeTuple *>(tuple_type.get())->getElements()[1]; const auto value_type = typeid_cast<const DataTypeTuple *>(tuple_type.get())->getElements()[1];
extract_tree = JSONExtractTree<JSONParser>::build(function_name, value_type); extract_tree = JSONExtractTree<JSONParser>::build(function_name, value_type);
@ -1002,7 +998,7 @@ public:
return std::make_shared<DataTypeString>(); 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 &) 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>()); 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 &) static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{ {
@ -1138,7 +1134,7 @@ public:
return std::make_unique<DataTypeArray>(tuple_type); 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 &) 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> 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. /// Combine all constant columns into a single constant value.
UInt8 const_3v_value = 0; 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 the constant value uniquely determines the result, return it.
if (has_consts && (arguments.empty() || Op::isSaturatedValueTernary(const_3v_value))) if (has_consts && (arguments.empty() || Op::isSaturatedValueTernary(const_3v_value)))
{ {
result_info.column = ColumnConst::create( return ColumnConst::create(
buildColumnFromTernaryData(UInt8Container({const_3v_value}), result_info.type->isNullable()), buildColumnFromTernaryData(UInt8Container({const_3v_value}), result_type->isNullable()),
input_rows_count input_rows_count
); );
return;
} }
const auto result_column = has_consts ? 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); 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 /// Types of all of the arguments are guaranteed to be non-nullable here
template <class Op> 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. /// Combine all constant columns into a single constant value.
UInt8 const_val = 0; UInt8 const_val = 0;
@ -429,8 +428,7 @@ static void basicExecuteImpl(ColumnRawPtrs arguments, ColumnWithTypeAndName & re
{ {
if (!arguments.empty()) if (!arguments.empty())
const_val = Op::apply(const_val, 0); const_val = Op::apply(const_val, 0);
result_info.column = DataTypeUInt8().createColumnConst(input_rows_count, toField(const_val)); return DataTypeUInt8().createColumnConst(input_rows_count, toField(const_val));
return;
} }
/// If the constant value is a neutral element, let's forget about it. /// 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 else
FastApplierImpl<Op>::apply(*arguments[0], *arguments[1], col_res->getData()); FastApplierImpl<Op>::apply(*arguments[0], *arguments[1], col_res->getData());
result_info.column = std::move(col_res); return col_res;
return;
} }
/// Convert all columns to UInt8 /// 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); 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> template <typename Impl, typename Name>
void FunctionAnyArityLogical<Impl, Name>::executeImpl( ColumnPtr FunctionAnyArityLogical<Impl, Name>::executeImpl(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result_index, size_t input_rows_count) const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{ {
ColumnRawPtrs args_in; ColumnRawPtrs args_in;
for (const auto arg_index : arguments) for (const auto & arg_index : arguments)
args_in.push_back(columns[arg_index].column.get()); args_in.push_back(arg_index.column.get());
auto & result_info = columns[result_index]; if (result_type->isNullable())
if (result_info.type->isNullable()) return executeForTernaryLogicImpl<Impl>(std::move(args_in), result_type, input_rows_count);
executeForTernaryLogicImpl<Impl>(std::move(args_in), result_info, input_rows_count);
else 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> 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(); auto col_res = ColumnUInt8::create();
@ -564,29 +560,31 @@ bool functionUnaryExecuteType(ColumnsWithTypeAndName & columns, const ColumnNumb
vec_res.resize(col->getData().size()); vec_res.resize(col->getData().size());
UnaryOperationImpl<T, Impl<T>>::vector(col->getData(), vec_res); UnaryOperationImpl<T, Impl<T>>::vector(col->getData(), vec_res);
columns[result].column = std::move(col_res); return col_res;
return true;
} }
return false; return nullptr;
} }
template <template <typename> class Impl, typename Name> 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) ColumnPtr res;
|| functionUnaryExecuteType<Impl, UInt16>(columns, arguments, result) if (!((res = functionUnaryExecuteType<Impl, UInt8>(arguments))
|| functionUnaryExecuteType<Impl, UInt32>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, UInt16>(arguments))
|| functionUnaryExecuteType<Impl, UInt64>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, UInt32>(arguments))
|| functionUnaryExecuteType<Impl, Int8>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, UInt64>(arguments))
|| functionUnaryExecuteType<Impl, Int16>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, Int8>(arguments))
|| functionUnaryExecuteType<Impl, Int32>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, Int16>(arguments))
|| functionUnaryExecuteType<Impl, Int64>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, Int32>(arguments))
|| functionUnaryExecuteType<Impl, Float32>(columns, arguments, result) || (res = functionUnaryExecuteType<Impl, Int64>(arguments))
|| functionUnaryExecuteType<Impl, Float64>(columns, arguments, result))) || (res = functionUnaryExecuteType<Impl, Float32>(arguments))
throw Exception("Illegal column " + columns[arguments[0]].column->getName() || (res = functionUnaryExecuteType<Impl, Float64>(arguments))))
throw Exception("Illegal column " + arguments[0].column->getName()
+ " of argument of function " + getName(), + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); 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. /// 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; 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 #if USE_EMBEDDED_COMPILER
bool isCompilableImpl(const DataTypes &) const override { return useDefaultImplementationForNulls(); } bool isCompilableImpl(const DataTypes &) const override { return useDefaultImplementationForNulls(); }
@ -217,7 +217,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } 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 #if USE_EMBEDDED_COMPILER
bool isCompilableImpl(const DataTypes &) const override { return true; } bool isCompilableImpl(const DataTypes &) const override { return true; }

View File

@ -35,19 +35,19 @@ public:
String getName() const override { return "FunctionExpression"; } 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; DB::Block expr_columns;
for (size_t i = 0; i < arguments.size(); ++i) 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. /// Replace column name with value from argument_names.
expr_columns.insert({argument.column, argument.type, signature->argument_names[i]}); expr_columns.insert({argument.column, argument.type, signature->argument_names[i]});
} }
expression_actions->execute(expr_columns); 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; } bool useDefaultImplementationForNulls() const override { return false; }
@ -79,9 +79,9 @@ public:
bool isDeterministicInScopeOfQuery() const override { return true; } bool isDeterministicInScopeOfQuery() const override { return true; }
const DataTypes & getArgumentTypes() const override { return argument_types; } 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); return std::make_unique<ExecutableFunctionExpression>(expression_actions, signature);
} }
@ -119,11 +119,8 @@ public:
bool useDefaultImplementationForNulls() const override { return false; } bool useDefaultImplementationForNulls() const override { return false; }
bool useDefaultImplementationForLowCardinalityColumns() 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; Names names;
DataTypes types; DataTypes types;
@ -139,13 +136,10 @@ public:
types.push_back(lambda_argument.type); 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, auto function = std::make_unique<FunctionExpression>(expression_actions, types, names,
capture->return_type, capture->return_name); capture->return_type, capture->return_name);
auto function_adaptor = std::make_shared<FunctionBaseAdaptor>(std::move(function)); 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: private:
@ -177,9 +171,9 @@ public:
bool isDeterministicInScopeOfQuery() const override { return true; } bool isDeterministicInScopeOfQuery() const override { return true; }
const DataTypes & getArgumentTypes() const override { return capture->captured_types; } 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); return std::make_unique<ExecutableFunctionCapture>(expression_actions, capture);
} }

View File

@ -66,15 +66,15 @@ public:
return Impl::getReturnType(); 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; 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 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; const ColumnConst * col_const_num = nullptr;
UInt32 edit_distance = 0; UInt32 edit_distance = 0;
@ -86,17 +86,17 @@ public:
edit_distance = col_const_num->getValue<UInt32>(); edit_distance = col_const_num->getValue<UInt32>();
else else
throw Exception( 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", + ". The number is not const or does not fit in UInt32",
ErrorCodes::ILLEGAL_COLUMN); 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()); const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arr_ptr.get());
if (!col_const_arr) if (!col_const_arr)
throw Exception( 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); ErrorCodes::ILLEGAL_COLUMN);
Array src_arr = col_const_arr->getValue<Array>(); Array src_arr = col_const_arr->getValue<Array>();
@ -124,12 +124,12 @@ public:
Impl::vectorConstant( Impl::vectorConstant(
col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res, offsets_res, edit_distance); col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res, offsets_res, edit_distance);
else 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) 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 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>()); 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; 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 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()); const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arr_ptr.get());
if (!col_const_arr) if (!col_const_arr)
throw Exception( 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); ErrorCodes::ILLEGAL_COLUMN);
Array src_arr = col_const_arr->getValue<Array>(); Array src_arr = col_const_arr->getValue<Array>();
@ -114,7 +114,7 @@ public:
if (col_haystack_vector) if (col_haystack_vector)
Impl::vectorConstant(col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res); Impl::vectorConstant(col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res);
else 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 refs_size = refs.size();
size_t accum = 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) for (size_t i = 0; i < column_haystack_size; ++i, accum += refs_size)
offsets_res[i] = accum; 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(); 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; 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 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()); const ColumnConst * col_const_arr = checkAndGetColumnConst<ColumnArray>(arr_ptr.get());
if (!col_const_arr) if (!col_const_arr)
throw Exception( 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); ErrorCodes::ILLEGAL_COLUMN);
Array src_arr = col_const_arr->getValue<Array>(); Array src_arr = col_const_arr->getValue<Array>();
@ -115,12 +115,12 @@ public:
if (col_haystack_vector) if (col_haystack_vector)
Impl::vectorConstant(col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res, offsets_res); Impl::vectorConstant(col_haystack_vector->getChars(), col_haystack_vector->getOffsets(), refs, vec_res, offsets_res);
else 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) 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 else
columns[result].column = std::move(col_res); return col_res;
} }
}; };

View File

@ -74,7 +74,7 @@ public:
return std::make_shared<DataTypeNumber<ToType>>(); 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(); auto col_to = ColumnVector<ToType>::create();
typename ColumnVector<ToType>::Container & vec_to = col_to->getData(); typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
@ -83,7 +83,7 @@ public:
vec_to.resize(size); vec_to.resize(size);
RandImpl::execute(reinterpret_cast<char *>(vec_to.data()), vec_to.size() * sizeof(ToType)); 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 #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) static FunctionPtr create(const Context & context)

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@ public:
/// Get the main function name. /// Get the main function name.
virtual String getName() const = 0; 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; virtual void createLowCardinalityResultCache(size_t cache_size) = 0;
}; };
@ -67,16 +67,16 @@ public:
virtual String getName() const = 0; virtual String getName() const = 0;
virtual const DataTypes & getArgumentTypes() 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. /// Do preparations and return executable.
/// sample_columns should contain data types of arguments and values of constants, if relevant. /// 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 /// 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 #if USE_EMBEDDED_COMPILER
@ -111,7 +111,7 @@ public:
* There is no need to implement function if it has zero arguments. * There is no need to implement function if it has zero arguments.
* Must return ColumnConst with single row or nullptr. * 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. /** Function is called "injective" if it returns different result for different values of arguments.
* Example: hex, negate, tuple... * Example: hex, negate, tuple...
@ -226,9 +226,9 @@ public:
using FunctionOverloadResolverPtr = std::shared_ptr<IFunctionOverloadResolver>; 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. * 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(); } 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; void createLowCardinalityResultCache(size_t cache_size) override;
@ -24,14 +24,14 @@ private:
/// Cache is created by function createLowCardinalityResultCache() /// Cache is created by function createLowCardinalityResultCache()
ExecutableFunctionLowCardinalityResultCachePtr low_cardinality_result_cache; ExecutableFunctionLowCardinalityResultCachePtr low_cardinality_result_cache;
bool defaultImplementationForConstantArguments( ColumnPtr defaultImplementationForConstantArguments(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run); ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run);
bool defaultImplementationForNulls( ColumnPtr defaultImplementationForNulls(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run); ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run);
void executeWithoutLowCardinalityColumns( ColumnPtr executeWithoutLowCardinalityColumns(
ColumnsWithTypeAndName & columns, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run); ColumnsWithTypeAndName & args, const DataTypePtr & result_type, size_t input_rows_count, bool dry_run);
}; };
class FunctionBaseAdaptor final : public IFunctionBase class FunctionBaseAdaptor final : public IFunctionBase
@ -42,12 +42,11 @@ public:
String getName() const final { return impl->getName(); } String getName() const final { return impl->getName(); }
const DataTypes & getArgumentTypes() const final { return impl->getArgumentTypes(); } 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(arguments));
return std::make_shared<ExecutableFunctionAdaptor>(impl->prepare(columns, arguments, result));
} }
#if USE_EMBEDDED_COMPILER #if USE_EMBEDDED_COMPILER
@ -64,9 +63,9 @@ public:
bool isStateful() const final { return impl->isStateful(); } bool isStateful() const final { return impl->isStateful(); }
bool isSuitableForConstantFolding() const final { return impl->isSuitableForConstantFolding(); } 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); } 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(); } String getName() const override { return function->getName(); }
protected: 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 useDefaultImplementationForNulls() const final { return function->useDefaultImplementationForNulls(); }
bool useDefaultImplementationForConstants() const final { return function->useDefaultImplementationForConstants(); } bool useDefaultImplementationForConstants() const final { return function->useDefaultImplementationForConstants(); }
@ -169,31 +168,31 @@ private:
class DefaultFunction final : public IFunctionBaseImpl class DefaultFunction final : public IFunctionBaseImpl
{ {
public: public:
DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, DataTypePtr return_type_) DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, DataTypePtr result_type_)
: function(std::move(function_)), arguments(std::move(arguments_)), return_type(std::move(return_type_)) {} : function(std::move(function_)), arguments(std::move(arguments_)), result_type(std::move(result_type_)) {}
String getName() const override { return function->getName(); } String getName() const override { return function->getName(); }
const DataTypes & getArgumentTypes() const override { return arguments; } 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 #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 #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); return std::make_unique<DefaultExecutable>(function);
} }
bool isSuitableForConstantFolding() const override { return function->isSuitableForConstantFolding(); } 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(); } bool isStateful() const override { return function->isStateful(); }
@ -214,7 +213,7 @@ public:
private: private:
std::shared_ptr<IFunction> function; std::shared_ptr<IFunction> function;
DataTypes arguments; DataTypes arguments;
DataTypePtr return_type; DataTypePtr result_type;
}; };
class DefaultOverloadResolver : public IFunctionOverloadResolverImpl class DefaultOverloadResolver : public IFunctionOverloadResolverImpl
@ -244,12 +243,12 @@ public:
bool useDefaultImplementationForLowCardinalityColumns() const override { return function->useDefaultImplementationForLowCardinalityColumns(); } bool useDefaultImplementationForLowCardinalityColumns() const override { return function->useDefaultImplementationForLowCardinalityColumns(); }
bool canBeExecutedOnLowCardinalityDictionary() const override { return function->canBeExecutedOnLowCardinalityDictionary(); } 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()); DataTypes data_types(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i) for (size_t i = 0; i < arguments.size(); ++i)
data_types[i] = arguments[i].type; 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); } void getLambdaArgumentTypes(DataTypes & arguments) const override { function->getLambdaArgumentTypes(arguments); }

View File

@ -35,10 +35,10 @@ public:
virtual String getName() const = 0; virtual String getName() const = 0;
virtual void execute(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) = 0; virtual ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) = 0;
virtual void executeDryRun(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) 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: /** 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 String getName() const = 0;
virtual const DataTypes & getArgumentTypes() 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 #if USE_EMBEDDED_COMPILER
@ -105,7 +105,7 @@ public:
virtual bool isStateful() const { return false; } virtual bool isStateful() const { return false; }
virtual bool isSuitableForConstantFolding() const { return true; } 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 isInjective(const ColumnsWithTypeAndName & /*sample_columns*/) const { return false; }
virtual bool isDeterministic() const { return true; } virtual bool isDeterministic() const { return true; }
@ -130,7 +130,7 @@ public:
virtual String getName() const = 0; 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 virtual DataTypePtr getReturnType(const DataTypes & /*arguments*/) const
{ {
@ -197,10 +197,10 @@ public:
virtual String getName() const = 0; virtual String getName() const = 0;
virtual void executeImpl(ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const = 0; virtual ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, 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 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: /** 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) /// Properties from IFunctionBase (see IFunction.h)
virtual bool isSuitableForConstantFolding() const { return true; } 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 isInjective(const ColumnsWithTypeAndName & /*sample_columns*/) const { return false; }
virtual bool isDeterministic() const { return true; } virtual bool isDeterministic() const { return true; }
virtual bool isDeterministicInScopeOfQuery() const { return true; } virtual bool isDeterministicInScopeOfQuery() const { return true; }

View File

@ -46,20 +46,15 @@ private:
return getLeastSupertype(types); 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(); size_t num_arguments = arguments.size();
if (1 == num_arguments) if (1 == num_arguments)
{ return arguments[0].column;
columns[result].column = columns[arguments[0]].column;
return;
}
auto result_type = columns[result].type;
Columns converted_columns(num_arguments); Columns converted_columns(num_arguments);
for (size_t arg = 0; arg < num_arguments; ++arg) 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(); auto result_column = result_type->createColumn();
result_column->reserve(input_rows_count); result_column->reserve(input_rows_count);
@ -86,7 +81,7 @@ private:
result_column->insertFrom(*converted_columns[best_arg], row_num); 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 * If FunctionInterface is IFunction, then "executeImpl" method of the implementation will be called
* and "execute" otherwise. * 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()) if (implementations.empty())
throw Exception("There are no available implementations for function " "TODO(dakovalkov): add name", 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. /// Statistics shouldn't rely on small columnss.
bool considerable = (input_rows_count > 1000); bool considerable = (input_rows_count > 1000);
ColumnPtr res;
size_t id = statistics.select(considerable); size_t id = statistics.select(considerable);
Stopwatch watch; Stopwatch watch;
if constexpr (std::is_same_v<FunctionInterface, IFunction>) 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 else
implementations[id]->execute(columns, arguments, result, input_rows_count); res = implementations[id]->execute(arguments, result_type, input_rows_count);
watch.stop(); watch.stop();
@ -228,6 +229,8 @@ public:
// TODO(dakovalkov): Calculate something more informative than rows count. // TODO(dakovalkov): Calculate something more informative than rows count.
statistics.complete(id, watch.elapsedSeconds(), input_rows_count); statistics.complete(id, watch.elapsedSeconds(), input_rows_count);
} }
return res;
} }
/* Register new implementation for function. /* Register new implementation for function.

View File

@ -29,7 +29,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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 /// Returns the position of the argument that is the column of rows
static size_t getStringsArgumentPosition() static size_t getStringsArgumentPosition()

View File

@ -28,7 +28,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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 /// Returns the position of the argument that is the column of rows
static size_t getStringsArgumentPosition() static size_t getStringsArgumentPosition()

View File

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

View File

@ -28,7 +28,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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 /// Returns the position of the argument that is the column of rows
static size_t getStringsArgumentPosition() 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; UInt16 default_port = 0;
if (arguments.size() == 2) 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) if (!port_column)
throw Exception("Second argument for function " + getName() + " must be constant UInt16", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); throw Exception("Second argument for function " + getName() + " must be constant UInt16", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
default_port = port_column->getValue<UInt16>(); 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())) if (const ColumnString * url_strs = checkAndGetColumn<ColumnString>(url_column.get()))
{ {
auto col_res = ColumnVector<UInt16>::create(); auto col_res = ColumnVector<UInt16>::create();
@ -67,11 +67,11 @@ struct FunctionPort : public IFunction
vec_res.resize(url_column->size()); vec_res.resize(url_column->size());
vector(default_port, url_strs->getChars(), url_strs->getOffsets(), vec_res); vector(default_port, url_strs->getChars(), url_strs->getOffsets(), vec_res);
columns[result].column = std::move(col_res); return col_res;
} }
else else
throw Exception( 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); ErrorCodes::ILLEGAL_COLUMN);
} }

View File

@ -216,20 +216,17 @@ public:
return true; 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) if (input_rows_count == 0)
{ return ColumnString::create();
columns[result].column = ColumnString::create();
return;
}
PODArray<Float64> xs, ys; PODArray<Float64> xs, ys;
PODArray<String> variant_names; PODArray<String> variant_names;
String dist; String dist;
bool higher_is_better; 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 = col_dist->getDataAt(0).data;
dist = Poco::toLower(dist); dist = Poco::toLower(dist);
@ -239,16 +236,13 @@ public:
else else
throw Exception("First argument for function " + getName() + " must be Constant string", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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); higher_is_better = col_higher_is_better->getBool(0);
else else
throw Exception("Second argument for function " + getName() + " must be Constatnt boolean", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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>(); Array src_arr = col_const_arr->getValue<Array>();
for (size_t i = 0; i < src_arr.size(); ++i) 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 &>()); 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)) 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); 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)) if (!toFloat64(col_const_arr, ys))
throw Exception("Fifth Argument for function " + getName() + " must be Array of constant Numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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()) 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()); 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(); auto dst = ColumnString::create();
std::string result_str = convertToJson(variant_names, variants); std::string result_str = convertToJson(variant_names, variants);
dst->insertData(result_str.c_str(), result_str.length()); 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; 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()); const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get());
if (!column_concrete) if (!column_concrete)
@ -89,7 +89,7 @@ public:
result_column->insertData(res_str.data, res_str.size); result_column->insertData(res_str.data, res_str.size);
} }
columns[result].column = std::move(result_column); return result_column;
} }
private: private:

View File

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

View File

@ -57,7 +57,7 @@ public:
/// For argument-lambda expressions, it defines the types of arguments of these expressions. /// For argument-lambda expressions, it defines the types of arguments of these expressions.
void getLambdaArgumentTypes(DataTypes & arguments) const override void getLambdaArgumentTypes(DataTypes & arguments) const override
{ {
if (arguments.size() < 1) if (arguments.empty())
throw Exception("Function " + getName() + " needs at least one argument; passed " throw Exception("Function " + getName() + " needs at least one argument; passed "
+ toString(arguments.size()) + ".", + toString(arguments.size()) + ".",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
@ -96,7 +96,7 @@ public:
if (arguments.size() == 1) 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) if (!array_type)
throw Exception("The only argument for function " + getName() + " must be array. Found " 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.", throw Exception("Function " + getName() + " needs one array argument.",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); 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) if (!data_type_function)
throw Exception("First argument for function " + getName() + " must be a 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 " throw Exception("Expression for function " + getName() + " must return UInt8, found "
+ return_type->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + 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()); 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) 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()); const auto * column_array = checkAndGetColumn<ColumnArray>(column_array_ptr.get());
if (!column_array) if (!column_array)
@ -151,11 +151,11 @@ public:
column_array = assert_cast<const ColumnArray *>(column_array_ptr.get()); 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 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) if (!column_with_type_and_name.column)
throw Exception("First argument for function " + getName() + " must be a function.", 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) 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; ColumnPtr column_array_ptr = array_with_type_and_name.column;
const auto * column_array = checkAndGetColumn<ColumnArray>(column_array_ptr.get()); const auto * column_array = checkAndGetColumn<ColumnArray>(column_array_ptr.get());
@ -229,7 +229,7 @@ public:
if (lambda_result->lowCardinality()) if (lambda_result->lowCardinality())
lambda_result = lambda_result->convertToFullColumnIfLowCardinality(); 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)); 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(); size_t num_elements = arguments.size();
if (num_elements == 0) if (num_elements == 0)
{
/// We should return constant empty array. /// We should return constant empty array.
columns[result].column = columns[result].type->createColumnConstWithDefaultValue(input_rows_count); return result_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
const DataTypePtr & return_type = columns[result].type; const DataTypePtr & elem_type = static_cast<const DataTypeArray &>(*result_type).getNestedType();
const DataTypePtr & elem_type = static_cast<const DataTypeArray &>(*return_type).getNestedType();
/** If part of columns have not same type as common type of all elements of array, /** If part of columns have not same type as common type of all elements of array,
* then convert them to common type. * then convert them to common type.
@ -55,7 +51,7 @@ public:
for (size_t i = 0; i < num_elements; ++i) 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; ColumnPtr preprocessed_column = arg.column;
@ -87,7 +83,7 @@ public:
out_offsets[i] = current_offset; out_offsets[i] = current_offset;
} }
columns[result].column = std::move(out); return out;
} }
private: private:

View File

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

View File

@ -55,7 +55,7 @@ public:
return std::make_shared<DataTypeArray>(nested_type); 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: private:
/// Initially allocate a piece of memory for 512 elements. NOTE: This is just a guess. /// 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 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(); auto res_ptr = return_type->createColumn();
ColumnArray & res = assert_cast<ColumnArray &>(*res_ptr); 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))) || executeString(*inner_col, offsets, res_data, res_offsets, nullable_col)))
executeHashed(*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> template <typename T>

View File

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

View File

@ -45,9 +45,9 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeUInt32>()); 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(); const ColumnArray::Offsets & offsets = array->getOffsets();
@ -63,11 +63,11 @@ public:
prev_off = off; prev_off = off;
} }
columns[result].column = ColumnArray::create(std::move(res_nested), array->getOffsetsPtr()); return ColumnArray::create(std::move(res_nested), array->getOffsetsPtr());
} }
else else
{ {
throw Exception("Illegal column " + columns[arguments[0]].column->getName() throw Exception("Illegal column " + arguments[0].column->getName()
+ " of first argument of function " + getName(), + " of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); ErrorCodes::ILLEGAL_COLUMN);
} }

View File

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

View File

@ -116,7 +116,7 @@ public:
return type; 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: private:
/// Initially allocate a piece of memory for 64 elements. NOTE: This is just a guess. /// 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> template <typename Derived>
void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl( ColumnPtr FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
ColumnsWithTypeAndName & columns, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{ {
size_t num_arguments = arguments.size(); size_t num_arguments = arguments.size();
ColumnRawPtrs data_columns; ColumnRawPtrs data_columns;
@ -158,12 +158,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
Columns array_holders; Columns array_holders;
ColumnPtr offsets_column; ColumnPtr offsets_column;
ColumnsWithTypeAndName args; const ArraysDepths arrays_depths = getArraysDepths(arguments);
for (size_t i = 0; i < arguments.size(); ++i)
args.emplace_back(columns[arguments[i]]);
const ArraysDepths arrays_depths = getArraysDepths(args);
/// If the column is Array - return it. If the const Array - materialize it, keep ownership and return. /// 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 * auto get_array_column = [&](const auto & column) -> const DB::ColumnArray *
@ -186,7 +181,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
size_t array_num = 0; size_t array_num = 0;
for (size_t i = 0; i < num_arguments; ++i) 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) if (!array)
continue; continue;
@ -258,7 +253,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
for (ssize_t depth = arrays_depths.max_array_depth - 1; depth >= 0; --depth) 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]); 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); 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, /** 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. * 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] 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) 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); ErrorCodes::ILLEGAL_COLUMN);
const IColumn::Offsets & src_offsets = src_col->getOffsets(); 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(); prev_data = &next_col->getData();
} }
columns[result].column = ColumnArray::create( return ColumnArray::create(
prev_data->getPtr(), prev_data->getPtr(),
result_offsets_column ? std::move(result_offsets_column) : src_col->getOffsetsPtr()); 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 are vectors of Fields, which may represent the NULL value),
* they do not require any preprocessing. * 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)). * The columns here have two general cases, either being Array(T) or Const(Array(T)).
@ -411,11 +411,11 @@ public:
if (col_array) if (col_array)
nullable = checkAndGetColumn<ColumnNullable>(col_array->getData()); 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); const ColumnNullable * arg_nullable = checkAndGetColumn<ColumnNullable>(*arg_column);
if (!nullable && !arg_nullable) if (!nullable && !arg_nullable)
executeOnNonNullable(columns, arguments, result); return executeOnNonNullable(arguments, result_type);
else else
{ {
/** /**
@ -424,7 +424,7 @@ public:
* {0, 1, 2, 3, 4} * {0, 1, 2, 3, 4}
* {data (array) argument, "value" argument, data null map, "value" null map, function result}. * {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) if (nullable)
{ {
@ -436,7 +436,7 @@ public:
data.type = std::make_shared<DataTypeArray>( data.type = std::make_shared<DataTypeArray>(
static_cast<const DataTypeNullable &>( static_cast<const DataTypeNullable &>(
*static_cast<const DataTypeArray &>( *static_cast<const DataTypeArray &>(
*columns[arguments[0]].type *arguments[0].type
).getNestedType() ).getNestedType()
).getNestedType()); ).getNestedType());
@ -448,7 +448,7 @@ public:
else else
{ {
auto & data = source_columns[0]; auto & data = source_columns[0];
data = columns[arguments[0]]; data = arguments[0];
} }
if (arg_nullable) if (arg_nullable)
@ -457,7 +457,7 @@ public:
arg.column = arg_nullable->getNestedColumnPtr(); arg.column = arg_nullable->getNestedColumnPtr();
arg.type = arg.type =
static_cast<const DataTypeNullable &>( static_cast<const DataTypeNullable &>(
*columns[arguments[1]].type *arguments[1].type
).getNestedType(); ).getNestedType();
auto & null_map = source_columns[3]; auto & null_map = source_columns[3];
@ -467,16 +467,11 @@ public:
else else
{ {
auto & arg = source_columns[1]; auto & arg = source_columns[1];
arg = columns[arguments[1]]; arg = arguments[1];
} }
/// Now perform the function. /// Now perform the function.
executeOnNonNullable(source_columns, {0, 1, 2, 3}, 4); return executeOnNonNullable(source_columns, result_type);
/// 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);
} }
} }
@ -492,12 +487,11 @@ private:
const IColumn& left; const IColumn& left;
const IColumn& right; const IColumn& right;
const ColumnArray::Offsets& offsets; const ColumnArray::Offsets& offsets;
ColumnsWithTypeAndName & columns; ColumnPtr result_column;
size_t result_pos;
NullMaps maps; NullMaps maps;
ResultColumnPtr result { ResultColumnType::create() }; 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) 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 #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 (checkAndGetColumn<ColumnLowCardinality>(&left_arr->getData()))
{ {
if (executeLowCardinality(columns, arguments, result)) if (auto res = executeLowCardinality(arguments))
return; return res;
throw Exception( throw Exception(
"Illegal internal type of first argument of function " + getName(), "Illegal internal type of first argument of function " + getName(),
@ -599,13 +593,16 @@ private:
} }
} }
if (!(executeIntegral<INTEGRAL_TPL_PACK>(columns, arguments, result) ColumnPtr res;
|| executeConst(columns, arguments, result) if (!((res = executeIntegral<INTEGRAL_TPL_PACK>(arguments))
|| executeString(columns, arguments, result) || (res = executeConst(arguments, result_type))
|| executeGeneric(columns, arguments, result))) || (res = executeString(arguments))
|| (res = executeGeneric(arguments))))
throw Exception( throw Exception(
"Illegal internal type of first argument of function " + getName(), "Illegal internal type of first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); 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 {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. * @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) if (arguments.size() < 3)
return {nullptr, nullptr}; return {nullptr, nullptr};
@ -627,10 +624,10 @@ private:
const NullMap * null_map_data = nullptr; const NullMap * null_map_data = nullptr;
const NullMap * null_map_item = 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(); 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(); null_map_item = &assert_cast<const ColumnUInt8 &>(*item_map).getData();
return {null_map_data, null_map_item}; return {null_map_data, null_map_item};
@ -642,26 +639,28 @@ private:
* (s1, s1, s2, ...), (s2, s1, s2, ...), (s3, s1, s2, ...) * (s1, s1, s2, ...), (s2, s1, s2, ...), (s3, s1, s2, ...)
*/ */
template <class ...Integral> 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) 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(); const IColumn& right = *right_converted_ptr.get();
ExecutionData data = { ExecutionData data = {
left->getData(), left->getData(),
right, right,
left->getOffsets(), left->getOffsets(),
columns, nullptr,
result_pos, getNullMaps(arguments)
getNullMaps(columns, arguments)
}; };
return executeIntegral<Integral...>(data); if (executeIntegral<Integral...>(data))
return data.result_column;
return nullptr;
} }
template <class ...Integral> template <class ...Integral>
@ -733,22 +732,21 @@ private:
* *
* Tips and tricks tried can be found at https://github.com/ClickHouse/ClickHouse/pull/12550 . * 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>( const ColumnArray * const col_array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
columns[arguments[0]].column.get());
if (!col_array) if (!col_array)
return false; return nullptr;
const ColumnLowCardinality * const col_lc = checkAndGetColumn<ColumnLowCardinality>(&col_array->getData()); const ColumnLowCardinality * const col_lc = checkAndGetColumn<ColumnLowCardinality>(&col_array->getData());
if (!col_lc) 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)) 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)); // inner types do not match (like A and Nullable(B) or A and Const(B));
&& different_inner_types; && different_inner_types;
const DataTypeArray * const array_type = checkAndGetDataType<DataTypeArray>( const DataTypeArray * const array_type = checkAndGetDataType<DataTypeArray>(arguments[0].type.get());
columns[arguments[0]].type.get());
const DataTypePtr target_type_ptr = recursiveRemoveLowCardinality(array_type->getNestedType()); const DataTypePtr target_type_ptr = recursiveRemoveLowCardinality(array_type->getNestedType());
const ColumnPtr col_arg_cloned = use_cloned_arg 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(); : col_arg_const->getPtr();
const StringRef elem = col_arg_cloned->getDataAt(0); const StringRef elem = col_arg_cloned->getDataAt(0);
@ -788,8 +785,7 @@ private:
data.resize_fill(offsets_size); data.resize_fill(offsets_size);
columns[result].column = std::move(col_result); return col_result;
return true;
} }
} }
@ -801,8 +797,7 @@ private:
null_map_data, null_map_data,
null_map_item); null_map_item);
columns[result].column = std::move(col_result); return col_result;
return true;
} }
else if (col_lc->nestedIsNullable()) // LC(Nullable(T)) and U else if (col_lc->nestedIsNullable()) // LC(Nullable(T)) and U
{ {
@ -827,19 +822,20 @@ private:
ExecutionData data = { ExecutionData data = {
left_ptr, right_ptr, left_ptr, right_ptr,
col_array->getOffsets(), col_array->getOffsets(),
columns, result, nullptr,
{null_map_left_casted, null_map_right_casted}}; {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 else // LC(T) and U, T not Nullable
{ {
if (col_arg.isNullable()) if (col_arg.isNullable())
return false; return nullptr;
if (const auto* const arg_lc = checkAndGetColumn<ColumnLowCardinality>(&col_arg); if (const auto* const arg_lc = checkAndGetColumn<ColumnLowCardinality>(&col_arg);
arg_lc && arg_lc->isNullable()) arg_lc && arg_lc->isNullable())
return false; return nullptr;
// LC(T) and U (possibly LC(V)) // LC(T) and U (possibly LC(V))
@ -848,11 +844,14 @@ private:
ExecutionData data = { ExecutionData data = {
*left_casted.get(), *right_casted.get(), col_array->getOffsets(), *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) static bool dispatchConvertedLCColumns(ExecutionData& data)
@ -875,28 +874,31 @@ private:
#undef INTEGRAL_TPL_PACK #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) if (!array)
return false; return nullptr;
const ColumnString * left = checkAndGetColumn<ColumnString>(&array->getData()); const ColumnString * left = checkAndGetColumn<ColumnString>(&array->getData());
if (!left) 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(); const IColumn & right = *right_ptr.get();
ExecutionData data = { ExecutionData data = {
*left, right, array->getOffsets(), *left, right, array->getOffsets(),
columns, result_pos, getNullMaps(columns, arguments), nullptr, getNullMaps(arguments),
std::move(ResultColumnType::create()) std::move(ResultColumnType::create())
}; };
return executeStringImpl(data); if (executeStringImpl(data))
return data.result_column;
return nullptr;
} }
static bool executeStringImpl(ExecutionData& data) static bool executeStringImpl(ExecutionData& data)
@ -961,17 +963,16 @@ private:
return true; 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>( const ColumnConst * col_array = checkAndGetColumnConst<ColumnArray>(arguments[0].column.get());
columns[arguments[0]].column.get());
if (!col_array) if (!col_array)
return false; return nullptr;
Array arr = col_array->getValue<Array>(); 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(); const IColumn * item_arg = right_ptr.get();
if (isColumnConst(*item_arg)) if (isColumnConst(*item_arg))
@ -990,8 +991,7 @@ private:
break; break;
} }
columns[result].column = columns[result].type->createColumnConst( return result_type->createColumnConst(item_arg->size(), static_cast<ResultType>(current));
item_arg->size(), static_cast<ResultType>(current));
} }
else else
{ {
@ -999,7 +999,7 @@ private:
const NullMap * null_map = nullptr; const NullMap * null_map = nullptr;
if (arguments.size() > 2) 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(); null_map = &assert_cast<const ColumnUInt8 &>(*col).getData();
const size_t size = item_arg->size(); 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) if (!col)
return false; return nullptr;
const IColumn & col_nested = col->getData(); 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(); const IColumn & item_arg = *right_ptr.get();
auto col_res = ResultColumnType::create(); 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()) if (item_arg.onlyNull())
Impl::Null<ConcreteAction>::process( Impl::Null<ConcreteAction>::process(
@ -1077,8 +1075,7 @@ private:
null_map_data, null_map_data,
null_map_item); null_map_item);
columns[result].column = std::move(col_res); return col_res;
return true;
} }
}; };
} }

View File

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

View File

@ -54,7 +54,7 @@ public:
return arr->getNestedType(); 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); throw Exception("Function " + getName() + " must not be executed directly.", ErrorCodes::FUNCTION_IS_SPECIAL);
} }

View File

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

View File

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

View File

@ -49,7 +49,7 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override; 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: private:
/// lazy initialization in getReturnTypeImpl /// 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; IAggregateFunction & agg_func = *aggregate_function;
std::unique_ptr<Arena> arena = std::make_unique<Arena>(); 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) 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; const ColumnArray::Offsets * offsets_i = nullptr;
if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(col)) 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(); 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; IColumn & res_col = *result_holder;
/// AggregateFunction's states should be inserted into column using specific way /// 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()) if (!res_col_aggregate_function && agg_func.isState())
throw Exception("State function " + agg_func.getName() + " inserts results into non-state column " 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); PODArray<AggregateDataPtr> places(input_rows_count);
for (size_t i = 0; i < input_rows_count; ++i) 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()); agg_func.insertResultInto(places[i], res_col, arena.get());
else else
res_col_aggregate_function->insertFrom(places[i]); 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; 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: private:
/// lazy initialization in getReturnTypeImpl /// 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; IAggregateFunction & agg_func = *aggregate_function;
std::unique_ptr<Arena> arena = std::make_unique<Arena>(); std::unique_ptr<Arena> arena = std::make_unique<Arena>();
@ -133,7 +133,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
/// Handling ranges /// 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 IColumn * ranges_col_tuple = nullptr;
const ColumnArray::Offsets * ranges_offsets = nullptr; const ColumnArray::Offsets * ranges_offsets = nullptr;
if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(ranges_col_array)) 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) 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; const ColumnArray::Offsets * offsets_i = nullptr;
if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(col)) if (const ColumnArray * arr = checkAndGetColumn<ColumnArray>(col))
@ -192,7 +192,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
/// Handling results /// Handling results
MutableColumnPtr result_holder = columns[result].type->createColumn(); MutableColumnPtr result_holder = result_type->createColumn();
ColumnArray * result_arr = static_cast<ColumnArray *>(result_holder.get()); ColumnArray * result_arr = static_cast<ColumnArray *>(result_holder.get());
IColumn & result_data = result_arr->getData(); IColumn & result_data = result_arr->getData();
@ -203,7 +203,7 @@ void FunctionArrayReduceInRanges::executeImpl(ColumnsWithTypeAndName & columns,
if (!res_col_aggregate_function && agg_func.isState()) if (!res_col_aggregate_function && agg_func.isState())
throw Exception("State function " + agg_func.getName() + " inserts results into non-state column " 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 /// 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]})); 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()) if (return_type->onlyNull())
{ return return_type->createColumnConstWithDefaultValue(input_rows_count);
columns[result].column = return_type->createColumnConstWithDefaultValue(input_rows_count);
return;
}
auto result_column = return_type->createColumn(); auto result_column = return_type->createColumn();
auto array_column = columns[arguments[0]].column; auto array_column = arguments[0].column;
auto size_column = columns[arguments[1]].column; auto size_column = arguments[1].column;
if (!columns[arguments[0]].type->equals(*return_type)) if (!arguments[0].type->equals(*return_type))
array_column = castColumn(columns[arguments[0]], return_type); array_column = castColumn(arguments[0], return_type);
const DataTypePtr & return_nested_type = typeid_cast<const DataTypeArray &>(*return_type).getNestedType(); const DataTypePtr & return_nested_type = typeid_cast<const DataTypeArray &>(*return_type).getNestedType();
size_t size = array_column->size(); size_t size = array_column->size();
@ -87,9 +82,9 @@ public:
ColumnPtr appended_column; ColumnPtr appended_column;
if (arguments.size() == 3) if (arguments.size() == 3)
{ {
appended_column = columns[arguments[2]].column; appended_column = arguments[2].column;
if (!columns[arguments[2]].type->equals(*return_nested_type)) if (!arguments[2].type->equals(*return_nested_type))
appended_column = castColumn(columns[arguments[2]], return_nested_type); appended_column = castColumn(arguments[2], return_nested_type);
} }
else else
appended_column = return_nested_type->createColumnConstWithDefaultValue(size); appended_column = return_nested_type->createColumnConstWithDefaultValue(size);
@ -127,7 +122,7 @@ public:
else else
GatherUtils::resizeDynamicSize(*array_source, *value_source, *sink, *size_column); 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; } bool useDefaultImplementationForConstants() const override { return true; }

View File

@ -41,7 +41,7 @@ public:
return arguments[0]; 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: private:
template <typename T> 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) 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); ErrorCodes::ILLEGAL_COLUMN);
auto res_ptr = array->cloneEmpty(); 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(), + " of null map of the first argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN); 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>; using ResultColumnType = ColumnVector<typename Method::ResultType>;
template <typename T> 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) ColumnPtr res;
|| executeNumberNumber<T, UInt16>(columns, arguments, result) if ( (res = executeNumberNumber<T, UInt8>(arguments))
|| executeNumberNumber<T, UInt32>(columns, arguments, result) || (res = executeNumberNumber<T, UInt16>(arguments))
|| executeNumberNumber<T, UInt64>(columns, arguments, result) || (res = executeNumberNumber<T, UInt32>(arguments))
|| executeNumberNumber<T, Int8>(columns, arguments, result) || (res = executeNumberNumber<T, UInt64>(arguments))
|| executeNumberNumber<T, Int16>(columns, arguments, result) || (res = executeNumberNumber<T, Int8>(arguments))
|| executeNumberNumber<T, Int32>(columns, arguments, result) || (res = executeNumberNumber<T, Int16>(arguments))
|| executeNumberNumber<T, Int64>(columns, arguments, result) || (res = executeNumberNumber<T, Int32>(arguments))
|| executeNumberNumber<T, Float32>(columns, arguments, result) || (res = executeNumberNumber<T, Int64>(arguments))
|| executeNumberNumber<T, Float64>(columns, arguments, result); || (res = executeNumberNumber<T, Float32>(arguments))
|| (res = executeNumberNumber<T, Float64>(arguments)))
return res;
return nullptr;
} }
template <typename T, typename U> 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 col1 = arguments[0].column->convertToFullColumnIfConst();
ColumnPtr col2 = columns[arguments[1]].column->convertToFullColumnIfConst(); ColumnPtr col2 = arguments[1].column->convertToFullColumnIfConst();
if (!col1 || !col2) if (!col1 || !col2)
return false; return nullptr;
const ColumnArray * col_array1 = checkAndGetColumn<ColumnArray>(col1.get()); const ColumnArray * col_array1 = checkAndGetColumn<ColumnArray>(col1.get());
const ColumnArray * col_array2 = checkAndGetColumn<ColumnArray>(col2.get()); const ColumnArray * col_array2 = checkAndGetColumn<ColumnArray>(col2.get());
if (!col_array1 || !col_array2) if (!col_array1 || !col_array2)
return false; return nullptr;
if (!col_array1->hasEqualOffsets(*col_array2)) if (!col_array1->hasEqualOffsets(*col_array2))
throw Exception("Array arguments for function " + getName() + " must have equal sizes", ErrorCodes::BAD_ARGUMENTS); 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<T> * col_nested1 = checkAndGetColumn<ColumnVector<T>>(col_array1->getData());
const ColumnVector<U> * col_nested2 = checkAndGetColumn<ColumnVector<U>>(col_array2->getData()); const ColumnVector<U> * col_nested2 = checkAndGetColumn<ColumnVector<U>>(col_array2->getData());
if (!col_nested1 || !col_nested2) if (!col_nested1 || !col_nested2)
return false; return nullptr;
auto col_res = ResultColumnType::create(); auto col_res = ResultColumnType::create();
@ -75,8 +79,7 @@ private:
col_array1->getOffsets(), col_array1->getOffsets(),
col_res->getData()); col_res->getData());
columns[result].column = std::move(col_res); return col_res;
return true;
} }
template <typename T, typename U> template <typename T, typename U>
@ -112,7 +115,7 @@ public:
if (!array_type) if (!array_type)
throw Exception("All arguments for function " + getName() + " must be an array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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)) if (!isNativeNumber(nested_type) && !isEnum(nested_type))
throw Exception( throw Exception(
getName() + " cannot process values of type " + nested_type->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); 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]); 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) ColumnPtr res;
|| executeNumber<UInt16>(columns, arguments, result) if (!((res = executeNumber<UInt8>(arguments))
|| executeNumber<UInt32>(columns, arguments, result) || (res = executeNumber<UInt16>(arguments))
|| executeNumber<UInt64>(columns, arguments, result) || (res = executeNumber<UInt32>(arguments))
|| executeNumber<Int8>(columns, arguments, result) || (res = executeNumber<UInt64>(arguments))
|| executeNumber<Int16>(columns, arguments, result) || (res = executeNumber<Int8>(arguments))
|| executeNumber<Int32>(columns, arguments, result) || (res = executeNumber<Int16>(arguments))
|| executeNumber<Int64>(columns, arguments, result) || (res = executeNumber<Int32>(arguments))
|| executeNumber<Float32>(columns, arguments, result) || (res = executeNumber<Int64>(arguments))
|| executeNumber<Float64>(columns, arguments, result))) || (res = executeNumber<Float32>(arguments))
throw Exception{"Illegal column " + columns[arguments[0]].column->getName() + " of first argument of function " || (res = executeNumber<Float64>(arguments))))
throw Exception{"Illegal column " + arguments[0].column->getName() + " of first argument of function "
+ getName(), + getName(),
ErrorCodes::ILLEGAL_COLUMN}; ErrorCodes::ILLEGAL_COLUMN};
return res;
} }
}; };

View File

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

View File

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

View File

@ -47,10 +47,10 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
bool useDefaultImplementationForNulls() const override { return false; } 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_num = arguments[0].column.get();
const auto * col_value = columns[arguments[1]].column.get(); const auto * col_value = arguments[1].column.get();
auto offsets_col = ColumnArray::ColumnOffsets::create(); auto offsets_col = ColumnArray::ColumnOffsets::create();
ColumnArray::Offsets & offsets = offsets_col->getData(); ColumnArray::Offsets & offsets = offsets_col->getData();
@ -72,7 +72,7 @@ public:
offsets.push_back(offset); 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)); 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(); size_t num_arguments = arguments.size();
@ -65,7 +65,7 @@ public:
for (size_t i = 0; i < num_arguments; ++i) 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. /// 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()); const ColumnArray * column_array = checkAndGetColumn<ColumnArray>(holder.get());
@ -86,7 +86,7 @@ public:
tuple_columns[i] = column_array->getDataPtr(); 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()); 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>()); 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; using UnderlyingColumnType = typename TypeToColumnType<typename DataType::FieldType>::ColumnType;
columns[result].column = ColumnArray::create( return ColumnArray::create(
UnderlyingColumnType::create(), UnderlyingColumnType::create(),
ColumnArray::ColumnOffsets::create(input_rows_count, 0)); ColumnArray::ColumnOffsets::create(input_rows_count, 0));
} }

View File

@ -45,7 +45,7 @@ public:
return arguments[0]; 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 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()) 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, input_rows_count,
Array{nested_type->getDefault()}); Array{nested_type->getDefault()});
} }
else else
columns[result].column = columns[arguments[0]].column; return arguments[0].column;
return true;
} }
else else
return false; return nullptr;
} }
template <typename T, bool nullable> 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)) if (auto res = FunctionEmptyArrayToSingleImpl::executeConst(arguments, result_type, input_rows_count))
return; return res;
const ColumnArray * array = checkAndGetColumn<ColumnArray>(columns[arguments[0]].column.get()); const ColumnArray * array = checkAndGetColumn<ColumnArray>(arguments[0].column.get());
if (!array) 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); ErrorCodes::ILLEGAL_COLUMN);
MutableColumnPtr res_ptr = array->cloneEmpty(); MutableColumnPtr res_ptr = array->cloneEmpty();
@ -414,7 +412,7 @@ void FunctionEmptyArrayToSingle::executeImpl(ColumnsWithTypeAndName & columns, c
else else
FunctionEmptyArrayToSingleImpl::executeDispatch<false>(*inner_col, src_offsets, *inner_res_col, res_offsets, src_null_map, res_null_map); 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>(); 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 rows = input_rows_count;
size_t num_args = arguments.size(); size_t num_args = arguments.size();
DataTypePtr common_type = nullptr; DataTypePtr common_type = nullptr;
auto commonType = [&common_type, &columns, &arguments]() auto commonType = [&common_type, &arguments]()
{ {
if (common_type == nullptr) if (common_type == nullptr)
{ {
DataTypes data_types; DataTypes data_types;
data_types.reserve(arguments.size()); data_types.reserve(arguments.size());
for (const auto & argument : arguments) for (const auto & argument : arguments)
data_types.push_back(columns[argument].type); data_types.push_back(argument.type);
common_type = getLeastSupertype(data_types); common_type = getLeastSupertype(data_types);
} }
@ -74,10 +74,10 @@ public:
for (size_t i = 0; i < num_args; ++i) 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; 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(); const auto & nested_type = argument_type->getNestedType();
/// Converts Array(Nothing) or Array(Nullable(Nothing) to common type. Example: hasAll([Null, 1], [Null]) -> 1 /// 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; 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; is_const = true;
argument_column = argument_column_const->getDataColumnPtr(); 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)); sources.emplace_back(GatherUtils::createArraySource(*argument_column_array, is_const, rows));
else else
throw Exception{"Arguments for function " + getName() + " must be arrays.", ErrorCodes::LOGICAL_ERROR}; throw Exception{"Arguments for function " + getName() + " must be arrays.", ErrorCodes::LOGICAL_ERROR};
} }
auto result_column = ColumnUInt8::create(rows); 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); 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; } bool useDefaultImplementationForConstants() const override { return true; }

View File

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

View File

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