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> template <typename A>
struct BitNotFuncImpl struct BitWrapperFuncImpl
{ {
using ResultType = UInt8; using ResultType = UInt8;
static inline ResultType NO_SANITIZE_UNDEFINED apply(A a) 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 #if USE_EMBEDDED_COMPILER
@ -21,10 +21,10 @@ namespace DB
#endif #endif
}; };
struct NameBitNotFunc { static constexpr auto name = "__bitNotFunc"; }; struct NameBitWrapperFunc { static constexpr auto name = "__bitWrapperFunc"; };
using FunctionBitNotFunc = FunctionUnaryArithmetic<BitNotFuncImpl, NameBitNotFunc, true>; using FunctionBitWrapperFunc = FunctionUnaryArithmetic<BitWrapperFuncImpl, NameBitWrapperFunc, true>;
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitNotFunc> template <> struct FunctionUnaryArithmeticMonotonicity<NameBitWrapperFunc>
{ {
static bool has() { return false; } static bool has() { return false; }
static IFunction::Monotonicity get(const Field &, const Field &) 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 registerFunctionRoundDuration(FunctionFactory & factory);
void registerFunctionRoundAge(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 registerFunctionBitSwapLastTwo(FunctionFactory & factory);
void registerFunctionsArithmetic(FunctionFactory & factory) void registerFunctionsArithmetic(FunctionFactory & factory)
@ -69,7 +71,9 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
registerFunctionRoundAge(factory); registerFunctionRoundAge(factory);
/// Not for external use. /// Not for external use.
registerFunctionBitNotFunc(factory); registerFunctionBitBoolMaskOr(factory);
registerFunctionBitBoolMaskAnd(factory);
registerFunctionBitWrapperFunc(factory);
registerFunctionBitSwapLastTwo(factory); registerFunctionBitSwapLastTwo(factory);
} }

View File

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

View File

@ -3,4 +3,22 @@
12 5 4.7 6.50 cba b 2014-06-11 12 5 4.7 6.50 cba b 2014-06-11
13 5 4.7 6.50 cba b 2015-01-01 13 5 4.7 6.50 cba b 2015-01-01
"rows_read": 4, "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, "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"
$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 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 # 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"
$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 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;" $CLICKHOUSE_CLIENT --query="DROP TABLE set_idx;"