Some fixes, more tests

This commit is contained in:
Pavel Kruglov 2021-05-17 19:06:46 +03:00
parent 0662df8b76
commit 7ff11aff2d
8 changed files with 35 additions and 59 deletions

View File

@ -102,46 +102,20 @@ void expandOffsetsByMask(PaddedPODArray<UInt64> & offsets, const PaddedPODArray<
throw Exception("Not enough bytes in mask", ErrorCodes::LOGICAL_ERROR);
}
template <typename ValueType>
bool tryExpandMaskColumnByMask(const ColumnPtr & column, const PaddedPODArray<UInt8> & mask, bool reverse, UInt8 default_value_for_expanding_mask)
{
if (const auto * col = checkAndGetColumn<ColumnVector<ValueType>>(*column))
{
expandDataByMask<ValueType>(const_cast<ColumnVector<ValueType> *>(col)->getData(), mask, reverse, default_value_for_expanding_mask);
return true;
}
return false;
}
void expandMaskColumnByMask(const ColumnPtr & column, const PaddedPODArray<UInt8>& mask, bool reverse, UInt8 default_value_for_expanding_mask)
{
if (const auto * col = checkAndGetColumn<ColumnNullable>(column.get()))
{
expandMaskColumnByMask(col->getNullMapColumnPtr(), mask, reverse, 0);
expandMaskColumnByMask(col->getNestedColumnPtr(), mask, reverse, default_value_for_expanding_mask);
return;
}
if (!tryExpandMaskColumnByMask<Int8>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<Int16>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<Int32>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<Int64>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<UInt8>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<UInt16>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<UInt32>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<UInt64>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<Float32>(column, mask, reverse, default_value_for_expanding_mask) &&
!tryExpandMaskColumnByMask<Float64>(column, mask, reverse, default_value_for_expanding_mask))
throw Exception("Cannot convert column " + column.get()->getName() + " to mask", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
void expandColumnByMask(const ColumnPtr & column, const PaddedPODArray<UInt8>& mask, bool reverse)
{
column->assumeMutable()->expand(mask, reverse);
}
void getMaskFromColumn(const ColumnPtr & column, PaddedPODArray<UInt8> & res, bool reverse, const PaddedPODArray<UInt8> * null_bytemap, UInt8 null_value)
void getMaskFromColumn(
const ColumnPtr & column,
PaddedPODArray<UInt8> & res,
bool reverse,
const PaddedPODArray<UInt8> * expanding_mask,
UInt8 default_value,
bool expanding_mask_reverse,
const PaddedPODArray<UInt8> * null_bytemap,
UInt8 null_value)
{
if (const auto * col = checkAndGetColumn<ColumnNothing>(*column))
{
@ -152,7 +126,7 @@ void getMaskFromColumn(const ColumnPtr & column, PaddedPODArray<UInt8> & res, bo
if (const auto * col = checkAndGetColumn<ColumnNullable>(*column))
{
const PaddedPODArray<UInt8> & null_map = checkAndGetColumn<ColumnUInt8>(*col->getNullMapColumnPtr())->getData();
return getMaskFromColumn(col->getNestedColumnPtr(), res, reverse, &null_map, null_value);
return getMaskFromColumn(col->getNestedColumnPtr(), res, reverse, expanding_mask, default_value, expanding_mask_reverse, &null_map, null_value);
}
try
@ -162,7 +136,9 @@ void getMaskFromColumn(const ColumnPtr & column, PaddedPODArray<UInt8> & res, bo
for (size_t i = 0; i != column->size(); ++i)
{
if (null_bytemap && (*null_bytemap)[i])
if (expanding_mask && (!(*expanding_mask)[i] ^ expanding_mask_reverse))
res[i] = reverse ? !default_value : default_value;
else if (null_bytemap && (*null_bytemap)[i])
res[i] = reverse ? !null_value : null_value;
else
res[i] = reverse ? !column->getBool(i): column->getBool(i);
@ -194,7 +170,7 @@ void disjunctionMasks(PaddedPODArray<UInt8> & mask1, const PaddedPODArray<UInt8>
binaryMasksOperationImpl(mask1, mask2, [](const auto & lhs, const auto & rhs){ return lhs | rhs; });
}
void maskedExecute(ColumnWithTypeAndName & column, const PaddedPODArray<UInt8> & mask, bool reverse, const UInt8 * default_value_for_expanding_mask)
void maskedExecute(ColumnWithTypeAndName & column, const PaddedPODArray<UInt8> & mask, bool reverse)
{
const auto * column_function = checkAndGetColumn<ColumnFunction>(*column.column);
if (!column_function || !column_function->isShortCircuitArgument())
@ -202,13 +178,6 @@ void maskedExecute(ColumnWithTypeAndName & column, const PaddedPODArray<UInt8> &
auto filtered = column_function->filter(mask, -1, reverse);
auto result = typeid_cast<const ColumnFunction *>(filtered.get())->reduce();
if (default_value_for_expanding_mask)
{
result.column = result.column->convertToFullColumnIfLowCardinality();
result.column = result.column->convertToFullColumnIfConst();
expandMaskColumnByMask(result.column, mask, reverse, *default_value_for_expanding_mask);
}
else
expandColumnByMask(result.column, mask, reverse);
column = std::move(result);
}

View File

@ -7,19 +7,26 @@
namespace DB
{
template <typename T>
void expandDataByMask(PaddedPODArray<T> & data, const PaddedPODArray<UInt8> & mask, bool reverse, T default_value);
void expandOffsetsByMask(PaddedPODArray<UInt64> & offsets, const PaddedPODArray<UInt8> & mask, bool reverse);
void getMaskFromColumn(const ColumnPtr & column, PaddedPODArray<UInt8> & res, bool reverse = false, const PaddedPODArray<UInt8> * null_bytemap = nullptr, UInt8 null_value = 1);
void getMaskFromColumn(
const ColumnPtr & column,
PaddedPODArray<UInt8> & res,
bool reverse = false,
const PaddedPODArray<UInt8> * expanding_mask = nullptr,
UInt8 default_value = 1,
bool expanding_mask_reverse = false,
const PaddedPODArray<UInt8> * null_bytemap = nullptr,
UInt8 null_value = 1);
void conjunctionMasks(PaddedPODArray<UInt8> & mask1, const PaddedPODArray<UInt8> & mask2);
void disjunctionMasks(PaddedPODArray<UInt8> & mask1, const PaddedPODArray<UInt8> & mask2);
void maskedExecute(ColumnWithTypeAndName & column, const PaddedPODArray<UInt8> & mask, bool reverse = false, const UInt8 * default_value_for_expanding_mask = nullptr);
void maskedExecute(ColumnWithTypeAndName & column, const PaddedPODArray<UInt8> & mask, bool reverse = false);
void executeColumnIfNeeded(ColumnWithTypeAndName & column);

View File

@ -21,7 +21,7 @@ namespace ErrorCodes
}
template <typename Impl, typename Name, typename ResultType>
template <typename Impl, typename Name, typename ResultType, bool is_suitable_for_short_circuit_arguments_execution = false>
class FunctionStringOrArrayToT : public IFunction
{
public:

View File

@ -524,10 +524,12 @@ void FunctionAnyArityLogical<Impl, Name>::executeShortCircuitArguments(ColumnsWi
executeColumnIfNeeded(arguments[0]);
IColumn::Filter mask;
IColumn::Filter * expanding_mask = nullptr;
for (int i = 1; i <= last_short_circuit_argument_index; ++i)
{
getMaskFromColumn(arguments[i - 1].column, mask, reverse, nullptr, null_value);
maskedExecute(arguments[i], mask, false, &value_for_mask_expanding);
getMaskFromColumn(arguments[i - 1].column, mask, reverse, expanding_mask, value_for_mask_expanding, false, nullptr, null_value);
maskedExecute(arguments[i], mask, false);
expanding_mask = &mask;
}
}

View File

@ -51,7 +51,7 @@ struct NameLength
static constexpr auto name = "length";
};
using FunctionLength = FunctionStringOrArrayToT<LengthImpl, NameLength, UInt64>;
using FunctionLength = FunctionStringOrArrayToT<LengthImpl, NameLength, UInt64, false>;
void registerFunctionLength(FunctionFactory & factory)
{

View File

@ -13,7 +13,7 @@ struct NameEmpty
{
static constexpr auto name = "empty";
};
using FunctionEmpty = FunctionStringOrArrayToT<EmptyImpl<false>, NameEmpty, UInt8>;
using FunctionEmpty = FunctionStringOrArrayToT<EmptyImpl<false>, NameEmpty, UInt8, false>;
}

View File

@ -119,11 +119,10 @@ public:
IColumn::Filter current_mask;
IColumn::Filter mask_disjunctions = IColumn::Filter(arguments[0].column->size(), 0);
UInt8 default_value_for_mask_expanding = 0;
int i = 1;
while (i <= last_short_circuit_argument_index)
{
getMaskFromColumn(arguments[i - 1].column, current_mask);
getMaskFromColumn(arguments[i - 1].column, current_mask, false, &mask_disjunctions, 0, true);
maskedExecute(arguments[i], current_mask);
++i;
@ -131,8 +130,7 @@ public:
break;
disjunctionMasks(mask_disjunctions, current_mask);
UInt8 * default_value_ptr = i + 1 == int(arguments.size()) ? nullptr: &default_value_for_mask_expanding;
maskedExecute(arguments[i], mask_disjunctions, true, default_value_ptr);
maskedExecute(arguments[i], mask_disjunctions, true);
++i;
}
}

View File

@ -13,7 +13,7 @@ struct NameNotEmpty
{
static constexpr auto name = "notEmpty";
};
using FunctionNotEmpty = FunctionStringOrArrayToT<EmptyImpl<true>, NameNotEmpty, UInt8>;
using FunctionNotEmpty = FunctionStringOrArrayToT<EmptyImpl<true>, NameNotEmpty, UInt8, false>;
}