__bitSwapLastTwo

This commit is contained in:
Nikita Vasilev 2019-01-30 22:40:01 +03:00
parent 0492ed780f
commit 476f33f9a3
3 changed files with 57 additions and 19 deletions

View File

@ -0,0 +1,51 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionUnaryArithmetic.h>
#include <DataTypes/NumberTraits.h>
namespace DB
{
template <typename A>
struct BitSwapLastTwoImpl
{
using ResultType = UInt8;
static inline ResultType apply(A a)
{
return static_cast<ResultType>(
((static_cast<ResultType>(a) & 1) << 1) | ((static_cast<ResultType>(a) >> 1) & 1));
}
#if USE_EMBEDDED_COMPILER
static constexpr bool compilable = true;
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * arg, bool)
{
if (!arg->getType()->isIntegerTy())
throw Exception("__bitSwapLastTwo expected an integral type", ErrorCodes::LOGICAL_ERROR);
return b.CreateOr(
b.CreateShl(b.CreateAnd(arg, 1), 1),
b.CreateAnd(b.CreateLShr(arg, 1), 1)
);
}
#endif
};
struct NameBitSwapLastTwo { static constexpr auto name = "__bitSwapLastTwo"; };
using FunctionBitSwapLastTwo = FunctionUnaryArithmetic<BitSwapLastTwoImpl, NameBitSwapLastTwo, true>;
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitSwapLastTwo>
{
static bool has() { return false; }
static IFunction::Monotonicity get(const Field &, const Field &)
{
return {};
}
};
void registerFunctionBitSwapLastTwo(FunctionFactory & factory)
{
factory.registerFunction<FunctionBitSwapLastTwo>();
}
}

View File

@ -33,6 +33,8 @@ void registerFunctionRoundToExp2(FunctionFactory & factory);
void registerFunctionRoundDuration(FunctionFactory & factory); void registerFunctionRoundDuration(FunctionFactory & factory);
void registerFunctionRoundAge(FunctionFactory & factory); void registerFunctionRoundAge(FunctionFactory & factory);
void registerFunctionBitSwapLastTwo(FunctionFactory & factory);
void registerFunctionsArithmetic(FunctionFactory & factory) void registerFunctionsArithmetic(FunctionFactory & factory)
{ {
registerFunctionPlus(factory); registerFunctionPlus(factory);
@ -64,6 +66,9 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
registerFunctionRoundToExp2(factory); registerFunctionRoundToExp2(factory);
registerFunctionRoundDuration(factory); registerFunctionRoundDuration(factory);
registerFunctionRoundAge(factory); registerFunctionRoundAge(factory);
/// Not for external use.
registerFunctionBitSwapLastTwo(factory);
} }
} }

View File

@ -274,25 +274,7 @@ bool UniqueCondition::operatorFromAST(ASTPtr & node) const
if (args.size() != 1) if (args.size() != 1)
return false; return false;
const auto one = std::make_shared<ASTLiteral>(Field(1)); func->name = "__bitSwapLastTwo";
const auto two = std::make_shared<ASTLiteral>(Field(2));
node = makeASTFunction(
"bitOr",
makeASTFunction(
"bitShiftLeft",
makeASTFunction(
"bitAnd",
node->clone(),
one->clone()),
one->clone()),
makeASTFunction(
"bitShiftRight",
makeASTFunction(
"bitAnd",
node->clone(),
two->clone()),
one->clone()));
} }
else if (func->name == "and" || func->name == "indexHint") else if (func->name == "and" || func->name == "indexHint")
func->name = "bitAnd"; func->name = "bitAnd";