fixed index condition

This commit is contained in:
Nikita Vasilev 2019-08-02 22:21:55 +03:00
parent b242c6ec79
commit bfa9a2c86f
7 changed files with 126 additions and 14 deletions

View File

@ -0,0 +1,40 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionBinaryArithmetic.h>
#include <DataTypes/NumberTraits.h>
namespace DB
{
template <typename A, typename B>
struct BitBoolMaskAndImpl
{
using ResultType = UInt8;
template <typename Result = ResultType>
static inline Result apply(A left, B right)
{
return static_cast<ResultType>(
((static_cast<ResultType>(left) & static_cast<ResultType>(right)) & 1)
| ((((static_cast<ResultType>(left) >> 1) | (static_cast<ResultType>(right) >> 1)) & 1) << 1));
}
#if USE_EMBEDDED_COMPILER
static constexpr bool compilable = false;
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
{
if (!left->getType()->isIntegerTy() && !right->getType()->isIntegerTy())
throw Exception("__bitBoolMaskAnd expected an integral type", ErrorCodes::LOGICAL_ERROR);
}
#endif
};
struct NameBitBoolMaskAnd { static constexpr auto name = "__bitBoolMaskAnd"; };
using FunctionBitBoolMaskAnd = FunctionBinaryArithmetic<BitBoolMaskAndImpl, NameBitBoolMaskAnd>;
void registerFunctionBitBoolMaskAnd(FunctionFactory & factory)
{
factory.registerFunction<FunctionBitBoolMaskAnd>();
}
}

View File

@ -0,0 +1,40 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionBinaryArithmetic.h>
#include <DataTypes/NumberTraits.h>
namespace DB
{
template <typename A, typename B>
struct BitBoolMaskOrImpl
{
using ResultType = UInt8;
template <typename Result = ResultType>
static inline Result apply(A left, B right)
{
return static_cast<ResultType>(
((static_cast<ResultType>(left) & 1) | (static_cast<ResultType>(right) & 1))
| ((((static_cast<ResultType>(left) >> 1) & (static_cast<ResultType>(right) >> 1)) & 1) << 1));
}
#if USE_EMBEDDED_COMPILER
static constexpr bool compilable = false;
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool)
{
if (!left->getType()->isIntegerTy() && !right->getType()->isIntegerTy())
throw Exception("__bitBoolMaskOr expected an integral type", ErrorCodes::LOGICAL_ERROR);
}
#endif
};
struct NameBitBoolMaskOr { static constexpr auto name = "__bitBoolMaskOr"; };
using FunctionBitBoolMaskOr = FunctionBinaryArithmetic<BitBoolMaskOrImpl, NameBitBoolMaskOr>;
void registerFunctionBitBoolMaskOr(FunctionFactory & factory)
{
factory.registerFunction<FunctionBitBoolMaskOr>();
}
}

View File

@ -6,13 +6,13 @@ namespace DB
{
template <typename A>
struct BitNotFuncImpl
struct BitWrapperFuncImpl
{
using ResultType = UInt8;
static inline ResultType NO_SANITIZE_UNDEFINED apply(A a)
{
return a == 0 ? static_cast<ResultType>(0b10) : static_cast<ResultType >(0b1);
return a == static_cast<UInt8>(0) ? static_cast<ResultType>(0b10) : static_cast<ResultType >(0b1);
}
#if USE_EMBEDDED_COMPILER
@ -21,10 +21,10 @@ namespace DB
#endif
};
struct NameBitNotFunc { static constexpr auto name = "__bitNotFunc"; };
using FunctionBitNotFunc = FunctionUnaryArithmetic<BitNotFuncImpl, NameBitNotFunc, true>;
struct NameBitWrapperFunc { static constexpr auto name = "__bitWrapperFunc"; };
using FunctionBitWrapperFunc = FunctionUnaryArithmetic<BitWrapperFuncImpl, NameBitWrapperFunc, true>;
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitNotFunc>
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitWrapperFunc>
{
static bool has() { return false; }
static IFunction::Monotonicity get(const Field &, const Field &)
@ -33,9 +33,9 @@ namespace DB
}
};
void registerFunctionBitNotFunc(FunctionFactory & factory)
void registerFunctionBitWrapperFunc(FunctionFactory & factory)
{
factory.registerFunction<FunctionBitNotFunc>();
factory.registerFunction<FunctionBitWrapperFunc>();
}
}

View File

@ -33,7 +33,9 @@ void registerFunctionRoundToExp2(FunctionFactory & factory);
void registerFunctionRoundDuration(FunctionFactory & factory);
void registerFunctionRoundAge(FunctionFactory & factory);
void registerFunctionBitNotFunc(FunctionFactory & factory);
void registerFunctionBitBoolMaskOr(FunctionFactory & factory);
void registerFunctionBitBoolMaskAnd(FunctionFactory & factory);
void registerFunctionBitWrapperFunc(FunctionFactory & factory);
void registerFunctionBitSwapLastTwo(FunctionFactory & factory);
void registerFunctionsArithmetic(FunctionFactory & factory)
@ -69,7 +71,9 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
registerFunctionRoundAge(factory);
/// Not for external use.
registerFunctionBitNotFunc(factory);
registerFunctionBitBoolMaskOr(factory);
registerFunctionBitBoolMaskAnd(factory);
registerFunctionBitWrapperFunc(factory);
registerFunctionBitSwapLastTwo(factory);
}

View File

@ -306,7 +306,10 @@ void MergeTreeIndexConditionSet::traverseAST(ASTPtr & node) const
}
if (atomFromAST(node))
node = makeASTFunction("__bitNotFunc", node);
{
if (node->as<ASTIdentifier>() || node->as<ASTFunction>())
node = makeASTFunction("__bitWrapperFunc", node);
}
else
node = std::make_shared<ASTLiteral>(UNKNOWN_FIELD);
}
@ -366,12 +369,12 @@ bool MergeTreeIndexConditionSet::operatorFromAST(ASTPtr & node) const
ASTPtr new_func;
if (args.size() > 1)
new_func = makeASTFunction(
"bitAnd",
"__bitBoolMaskAnd",
node,
last_arg);
else
new_func = makeASTFunction(
"bitAnd",
"__bitBoolMaskAnd",
args.back(),
last_arg);
@ -385,12 +388,12 @@ bool MergeTreeIndexConditionSet::operatorFromAST(ASTPtr & node) const
ASTPtr new_func;
if (args.size() > 1)
new_func = makeASTFunction(
"bitOr",
"__bitBoolMaskOr",
node,
last_arg);
else
new_func = makeASTFunction(
"bitOr",
"__bitBoolMaskOr",
args.back(),
last_arg);

View File

@ -3,4 +3,22 @@
12 5 4.7 6.50 cba b 2014-06-11
13 5 4.7 6.50 cba b 2015-01-01
"rows_read": 4,
2 2 4.5 2.50 abc a 2014-01-01
6 2 4.5 2.50 abc a 2014-02-11
7 5 6.9 1.57 bac c 2014-04-11
8 2 4.5 2.50 abc a 2014-05-11
9 5 6.9 1.57 bac c 2014-07-11
5 5 6.9 1.57 bac c 2014-11-11
4 2 4.5 2.50 abc a 2016-01-01
3 5 6.9 1.57 bac c 2017-01-01
"rows_read": 8,
"rows_read": 2,
2 2 4.5 2.50 abc a 2014-01-01
6 2 4.5 2.50 abc a 2014-02-11
7 5 6.9 1.57 bac c 2014-04-11
8 2 4.5 2.50 abc a 2014-05-11
9 5 6.9 1.57 bac c 2014-07-11
5 5 6.9 1.57 bac c 2014-11-11
4 2 4.5 2.50 abc a 2016-01-01
3 5 6.9 1.57 bac c 2017-01-01
"rows_read": 8,

View File

@ -43,8 +43,15 @@ $CLICKHOUSE_CLIENT --query="INSERT INTO set_idx VALUES
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba') ORDER BY dt"
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba') ORDER BY dt FORMAT JSON" | grep "rows_read"
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE NOT (i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba')) ORDER BY dt"
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE NOT (i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba')) ORDER BY dt FORMAT JSON" | grep "rows_read"
# select with hole made by primary key
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR u64 > 10) AND s != 'cba' ORDER BY dt"
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR u64 > 10) AND s != 'cba' ORDER BY dt FORMAT JSON" | grep "rows_read"
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR NOT u64 > 10) AND NOT (s = 'cba') ORDER BY dt"
$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR NOT u64 > 10) AND NOT (s = 'cba') ORDER BY dt FORMAT JSON" | grep "rows_read"
$CLICKHOUSE_CLIENT --query="DROP TABLE set_idx;"