mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-17 21:24:28 +00:00
re-unioned the *NumImpl
This commit is contained in:
parent
2f589c6856
commit
0021f67664
@ -95,24 +95,12 @@ private:
|
|||||||
|
|
||||||
using NullMap = PaddedPODArray<UInt8>;
|
using NullMap = PaddedPODArray<UInt8>;
|
||||||
|
|
||||||
static inline bool hasNull(const NullMap & null_map, size_t i) { return null_map[i]; }
|
static inline bool hasNull(const NullMap * const null_map, size_t i) { return (*null_map)[i]; }
|
||||||
|
|
||||||
static inline void setResult(
|
template <size_t Case, class Data, class Target>
|
||||||
ResultArr& result, const ArrOffsets& offsets,
|
static void process(
|
||||||
ResultType current, ArrOffset& current_offset, size_t i)
|
const Data & data, const ArrOffsets & offsets, const Target & target, ResultArr & result,
|
||||||
{
|
const NullMap * const null_map_data, const NullMap * const null_map_item)
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
|
||||||
result[i] = current;
|
|
||||||
else
|
|
||||||
if (current != 0) /// do not override the value if it was not found as we invoke this function
|
|
||||||
result[i] = current; /// multiple times.
|
|
||||||
|
|
||||||
current_offset = offsets[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Both function arguments are ordinary.
|
|
||||||
template <class Data, class Target>
|
|
||||||
static void vectorCase1(const Data & data, const ArrOffsets & offsets, const Target & target, ResultArr & result)
|
|
||||||
{
|
{
|
||||||
const size_t size = offsets.size();
|
const size_t size = offsets.size();
|
||||||
|
|
||||||
@ -128,164 +116,71 @@ private:
|
|||||||
|
|
||||||
for (size_t j = 0; j < array_size; ++j)
|
for (size_t j = 0; j < array_size; ++j)
|
||||||
{
|
{
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
if constexpr (Case == 2) /// Right arg is Nullable
|
||||||
|
if (hasNull(null_map_item, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if constexpr (Case == 3) /// Left arg is an array of Nullables
|
||||||
|
if (hasNull(null_map_data, current_offset + j))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if constexpr (Case == 4)
|
||||||
{
|
{
|
||||||
if (!compare(data[current_offset + j], target, i))
|
const bool right_is_null = hasNull(null_map_data, current_offset + j);
|
||||||
continue;
|
const bool left_is_null = hasNull(null_map_item, i);
|
||||||
}
|
|
||||||
else
|
if (right_is_null != left_is_null)
|
||||||
if (data.compareAt(current_offset + j, ResColumnIsConst ? 0 : i , target, 1))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ConcreteAction::apply(j, current))
|
if (!right_is_null)
|
||||||
break;
|
{
|
||||||
}
|
if constexpr (InvokedNotFromLCSpec)
|
||||||
|
{
|
||||||
setResult(result, offsets, current, current_offset, i);
|
if (!compare(data[current_offset + j], target, i))
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (0 != data.compareAt(current_offset + j, ResColumnIsConst ? 0 : i , target, 1))
|
||||||
/// The 2nd function argument is nullable.
|
continue;
|
||||||
template <class Data, class Target>
|
}
|
||||||
static void vectorCase2(const Data & data, const ArrOffsets & offsets, const Target & target_value,
|
|
||||||
ResultArr & result, const NullMap & null_map_item)
|
|
||||||
{
|
|
||||||
const size_t size = offsets.size();
|
|
||||||
|
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
|
||||||
result.resize(size);
|
|
||||||
|
|
||||||
ArrOffset current_offset = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
const size_t array_size = offsets[i] - current_offset;
|
|
||||||
ResultType current = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < array_size; ++j)
|
|
||||||
{
|
|
||||||
if (hasNull(null_map_item, i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
|
||||||
{
|
|
||||||
if (!compare(data[current_offset + j], target_value, i))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (data.compareAt(current_offset + j, ResColumnIsConst ? 0 : i , target_value, 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!ConcreteAction::apply(j, current))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
setResult(result, offsets, current, current_offset, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The 1st function argument is a non-constant array of nullable values.
|
|
||||||
template <class Data, class Target>
|
|
||||||
static void vectorCase3(const Data & data, const ArrOffsets & offsets, const Target & target_value,
|
|
||||||
ResultArr & result, const NullMap & null_map_data)
|
|
||||||
{
|
|
||||||
const size_t size = offsets.size();
|
|
||||||
|
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
|
||||||
result.resize(size);
|
|
||||||
|
|
||||||
ArrOffset current_offset = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
const size_t array_size = offsets[i] - current_offset;
|
|
||||||
ResultType current = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < array_size; ++j)
|
|
||||||
{
|
|
||||||
if (null_map_data[current_offset + j])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
|
||||||
{
|
|
||||||
if (!compare(data[current_offset + j], target_value, i))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (data.compareAt(current_offset + j, ResColumnIsConst ? 0 : i , target_value, 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!ConcreteAction::apply(j, current))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
setResult(result, offsets, current, current_offset, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The 1st function argument is a non-constant array of nullable values.
|
|
||||||
/// The 2nd function argument is nullable.
|
|
||||||
template <class Data, class Target>
|
|
||||||
static void vectorCase4(const Data & data, const ArrOffsets & offsets, const Target & value,
|
|
||||||
ResultArr & result, const NullMap & null_map_data, const NullMap & null_map_item)
|
|
||||||
{
|
|
||||||
const size_t size = offsets.size();
|
|
||||||
|
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
|
||||||
result.resize(size);
|
|
||||||
|
|
||||||
ArrOffset current_offset = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
const size_t array_size = offsets[i] - current_offset;
|
|
||||||
ResultType current = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < array_size; ++j)
|
|
||||||
{
|
|
||||||
bool hit = false;
|
|
||||||
|
|
||||||
if (null_map_data[current_offset + j])
|
|
||||||
{
|
|
||||||
if (hasNull(null_map_item, i))
|
|
||||||
hit = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if constexpr (InvokedNotFromLCSpec)
|
if constexpr (InvokedNotFromLCSpec)
|
||||||
{
|
{
|
||||||
if (!compare(data[current_offset + j], value, i))
|
if (!compare(data[current_offset + j], target, i))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else if (0 != data.compareAt(current_offset + j, ResColumnIsConst ? 0 : i , target, 1))
|
||||||
if (data.compareAt(current_offset + j, ResColumnIsConst ? 0 : i , value, 1))
|
continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
hit = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hit && !ConcreteAction::apply(j, current))
|
if (!ConcreteAction::apply(j, current))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setResult(result, offsets, current, current_offset, i);
|
if constexpr (InvokedNotFromLCSpec)
|
||||||
|
result[i] = current;
|
||||||
|
else
|
||||||
|
if (current != 0) /// do not override the value if it was not found as we invoke this function
|
||||||
|
result[i] = current; /// multiple times.
|
||||||
|
|
||||||
|
current_offset = offsets[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <class Data, class ScalarOrVector>
|
template <class Data, class Target>
|
||||||
static void vector(const Data & data, const ArrOffsets & offsets, const ScalarOrVector & value,
|
static void vector(const Data & data, const ArrOffsets & offsets, const Target & value,
|
||||||
ResultArr & result, const NullMap * null_map_data, const NullMap * null_map_item)
|
ResultArr & result, const NullMap * const null_map_data, const NullMap * const null_map_item)
|
||||||
{
|
{
|
||||||
/// Processing is split into 4 cases.
|
|
||||||
if (!null_map_data && !null_map_item)
|
if (!null_map_data && !null_map_item)
|
||||||
vectorCase1(data, offsets, value, result);
|
process<1>(data, offsets, value, result, null_map_data, null_map_item);
|
||||||
else if (!null_map_data && null_map_item)
|
else if (!null_map_data && null_map_item)
|
||||||
vectorCase2(data, offsets, value, result, *null_map_item);
|
process<2>(data, offsets, value, result, null_map_data, null_map_item);
|
||||||
else if (null_map_data && !null_map_item)
|
else if (null_map_data && !null_map_item)
|
||||||
vectorCase3(data, offsets, value, result, *null_map_data);
|
process<3>(data, offsets, value, result, null_map_data, null_map_item);
|
||||||
else
|
else
|
||||||
vectorCase4(data, offsets, value, result, *null_map_data, *null_map_item);
|
process<4>(data, offsets, value, result, null_map_data, null_map_item);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -308,6 +203,7 @@ struct ArrayIndexNumNullImpl
|
|||||||
result.resize(size);
|
result.resize(size);
|
||||||
|
|
||||||
ColumnArray::Offset current_offset = 0;
|
ColumnArray::Offset current_offset = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
size_t array_size = offsets[i] - current_offset;
|
size_t array_size = offsets[i] - current_offset;
|
||||||
@ -657,12 +553,12 @@ struct ArrayIndexGenericNullImpl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool allowNested(const DataTypePtr & left, const DataTypePtr & right)
|
static inline bool allowNested(const DataTypePtr & left, const DataTypePtr & right)
|
||||||
{
|
{
|
||||||
return ((isNativeNumber(left) || isEnum(left)) && isNativeNumber(right)) || left->equals(*right);
|
return ((isNativeNumber(left) || isEnum(left)) && isNativeNumber(right)) || left->equals(*right);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool allowArguments(const DataTypePtr & array_inner_type, const DataTypePtr & arg)
|
static inline bool allowArguments(const DataTypePtr & array_inner_type, const DataTypePtr & arg)
|
||||||
{
|
{
|
||||||
if (allowNested(array_inner_type, arg))
|
if (allowNested(array_inner_type, arg))
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user