diff --git a/be/src/vec/functions/function_bit_count.cpp b/be/src/vec/functions/function_bit_count.cpp new file mode 100644 index 0000000000..66ef9d4c4f --- /dev/null +++ b/be/src/vec/functions/function_bit_count.cpp @@ -0,0 +1,61 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include +#include +#include +#include + +#include "common/exception.h" +#include "common/status.h" +#include "gutil/integral_types.h" +#include "util/radix_sort.h" +#include "vec/core/types.h" +#include "vec/functions/function_unary_arithmetic.h" +#include "vec/functions/simple_function_factory.h" + +namespace doris::vectorized { + +struct NameBitCount { + static constexpr auto name = "bit_count"; +}; + +template +struct BitCountImpl { + // No unsigned type in Java. So we need signed number as return type + // Int8_MAX = 127 + using ResultType = std::conditional_t= 128, Int16, Int8>; + + static inline ResultType apply(T a) { + if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v) { + return std::popcount(static_cast>(a)); + } else { + throw Exception(ErrorCode::INVALID_ARGUMENT, + "bit_count only support using INTEGER as operator"); + } + } +}; + +using FunctionBitCount = FunctionUnaryArithmetic; + +void register_function_bit_count(SimpleFunctionFactory& factory) { + factory.register_function(); +} + +} // namespace doris::vectorized diff --git a/be/src/vec/functions/function_bit_shift.cpp b/be/src/vec/functions/function_bit_shift.cpp new file mode 100644 index 0000000000..36a5c59e3c --- /dev/null +++ b/be/src/vec/functions/function_bit_shift.cpp @@ -0,0 +1,90 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include +#include +#include +#include +#include +#include + +#include "common/exception.h" +#include "common/logging.h" +#include "common/status.h" +#include "gutil/integral_types.h" +#include "util/radix_sort.h" +#include "vec/core/types.h" +#include "vec/functions/function_binary_arithmetic.h" +#include "vec/functions/simple_function_factory.h" + +namespace doris::vectorized { + +struct NameBitShiftLeft { + static constexpr auto name = "bit_shift_left"; +}; + +struct NameBitShiftRight { + static constexpr auto name = "bit_shift_right"; +}; + +template +struct BitShiftLeftImpl { + using ResultType = typename NumberTraits::ResultOfBit::Type; + + template + static inline Result apply(A a, B b) { + if constexpr (!std::is_same_v || !std::is_same_v) { + throw Exception(ErrorCode::NOT_FOUND, + "bit_shift_left only supports [BIGINT, TINYINT] as operator"); + } else { + // return zero if b < 0, keep consistent with mysql + // cast to unsigned so that we can do logical shift by default, keep consistent with mysql + return b < 0 ? 0 + : static_cast::type>(a) + << static_cast(b); + } + } +}; + +template +struct BitShiftRightImpl { + using ResultType = typename NumberTraits::ResultOfBit::Type; + + template + static inline Result apply(A a, B b) { + if constexpr (!std::is_same_v || !std::is_same_v) { + throw Exception(ErrorCode::NOT_FOUND, + "bit_shift_right only supports [BIGINT, TINYINT] as operator"); + } else { + // return zero if b < 0, keep consistent with mysql + // cast to unsigned so that we can do logical shift by default, keep consistent with mysql + return b < 0 ? 0 + : static_cast::type>(a) >> + static_cast(b); + } + } +}; + +using FunctionBitShiftLeft = FunctionBinaryArithmetic; +using FunctionBitShiftRight = FunctionBinaryArithmetic; + +void register_function_bit_shift(SimpleFunctionFactory& factory) { + factory.register_function(); + factory.register_function(); +} + +} // namespace doris::vectorized diff --git a/be/src/vec/functions/simple_function_factory.h b/be/src/vec/functions/simple_function_factory.h index 0992239e99..5c47198fd6 100644 --- a/be/src/vec/functions/simple_function_factory.h +++ b/be/src/vec/functions/simple_function_factory.h @@ -48,6 +48,8 @@ void register_function_multiply(SimpleFunctionFactory& factory); void register_function_divide(SimpleFunctionFactory& factory); void register_function_int_div(SimpleFunctionFactory& factory); void register_function_bit(SimpleFunctionFactory& factory); +void register_function_bit_count(SimpleFunctionFactory& factory); +void register_function_bit_shift(SimpleFunctionFactory& factory); void register_function_math(SimpleFunctionFactory& factory); void register_function_modulo(SimpleFunctionFactory& factory); void register_function_bitmap(SimpleFunctionFactory& factory); @@ -229,6 +231,8 @@ public: register_function_int_div(instance); register_function_modulo(instance); register_function_bit(instance); + register_function_bit_count(instance); + register_function_bit_shift(instance); register_function_is_null(instance); register_function_is_not_null(instance); register_function_nullables(instance); diff --git a/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitcount.md b/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitcount.md new file mode 100644 index 0000000000..2518e35f2f --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitcount.md @@ -0,0 +1,52 @@ +--- +{ +"title": "BIT_COUNT", +"language": "en" +} +--- + + + +## bit_count +### description +#### Syntax + +`BIT_COUNT(Integer-type x)` + +Returns the exist count of one in 2's complement represent of integer x. + +Integer-type could be: TINYINT、SMALLINT、INT、BIGINT、LARGEINT + +### example + +``` +select "0b11111111", bit_count(-1) +-------------- + ++--------------+---------------+ +| '0b11111111' | bit_count(-1) | ++--------------+---------------+ +| 0b11111111 | 8 | ++--------------+---------------+ +``` + +### keywords + + BITCOUNT, BIT_COUNT diff --git a/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitshfitleft.md b/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitshfitleft.md new file mode 100644 index 0000000000..b48313c242 --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitshfitleft.md @@ -0,0 +1,71 @@ +--- +{ +"title": "BIT_SHIFT_LEFT", +"language": "en" +} +--- + + + +## bit_shift_left +### description +#### syntax + +`BIT_SHIFT_LEFT(BIGINT x, TINYINT c)` + +Do logical left shift to `BIGINT` type x by c bits, and return result as a `BIGINT`. +Return zero if `c` is less than 0. + +### example +Normal case +```sql +select 8 as x, number as c, bit_shift_left(8, number) as bit_shift_left from numbers("number"="5") +-------------- + ++------+------+----------------+ +| x | c | bit_shift_left | ++------+------+----------------+ +| 8 | 0 | 8 | +| 8 | 1 | 16 | +| 8 | 2 | 32 | +| 8 | 3 | 64 | +| 8 | 4 | 128 | ++------+------+----------------+ +5 rows in set (0.04 sec) +``` +Left shift result of `9223372036854775807` which is `BIGINT_MAX` by 1 bit will get -2. +```sql +WITH tbl AS ( + SELECT 9223372036854775807 AS BIGINT_MAX +) +SELECT BIGINT_MAX, bit_shift_left(BIGINT_MAX, 1) +FROM tbl +-------------- + ++---------------------+-------------------------------+ +| BIGINT_MAX | bit_shift_left(BIGINT_MAX, 1) | ++---------------------+-------------------------------+ +| 9223372036854775807 | -2 | ++---------------------+-------------------------------+ +1 row in set (0.05 sec) +``` +### keywords + + BITSHIFT, BITSHIFTLEFT diff --git a/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitshfitright.md b/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitshfitright.md new file mode 100644 index 0000000000..8d44c3421b --- /dev/null +++ b/docs/en/docs/sql-manual/sql-functions/bitwise-functions/bitshfitright.md @@ -0,0 +1,79 @@ +--- +{ +"title": "BIT_SHIFT_RIGHT", +"language": "en" +} +--- + + + +## bit_shift_right +### description +#### syntax + +`BIT_SHIFT_RIGHT(BIGINT x, TINYINT c)` + +Return result of logical right shift of `BIGINT` type x by c bits. + +### example +Normal case +```sql +select 1024 as x, number as c, bit_shift_right(1024, number) as bit_shift_right from numbers("number"="5") +-------------- + ++------+------+-----------------+ +| x | c | bit_shift_right | ++------+------+-----------------+ +| 1024 | 0 | 1024 | +| 1024 | 1 | 512 | +| 1024 | 2 | 256 | +| 1024 | 3 | 128 | +| 1024 | 4 | 64 | ++------+------+-----------------+ +5 rows in set (0.03 sec) +``` +Logical right shift `BIGINT` -1 by 1 bits gets `BIGINT_MAX` +```sql +select bit_shift_right(-1, 1) +-------------- + ++------------------------+ +| bit_shift_right(-1, 1) | ++------------------------+ +| 9223372036854775807 | ++------------------------+ +``` +Return zero if `c` is less than 0 +```sql +select bit_shift_right(100, -1) +-------------- + ++--------------------------+ +| bit_shift_right(100, -1) | ++--------------------------+ +| 0 | ++--------------------------+ +1 row in set (0.04 sec) +``` + + +### keywords + + BITSHIFT, BITSHIFTRIGHT diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitcount.md b/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitcount.md new file mode 100644 index 0000000000..9dfdd7e9d4 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitcount.md @@ -0,0 +1,52 @@ +--- +{ +"title": "BIT_COUNT", +"language": "zh-CH" +} +--- + + + +## bit_count +### description +#### Syntax + +`BIT_COUNT(Integer-type x)` + +统计整型 x 的二的补码表示中 1 的个数。 + +整型可以是:TINYINT、SMALLINT、INT、BIGINT、LARGEINT + +### example + +``` +select "0b11111111", bit_count(-1) +-------------- + ++--------------+---------------+ +| '0b11111111' | bit_count(-1) | ++--------------+---------------+ +| 0b11111111 | 8 | ++--------------+---------------+ +``` + +### keywords + + BITCOUNT, BIT_COUNT diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitshiftleft.md b/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitshiftleft.md new file mode 100644 index 0000000000..1729b7ac75 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitshiftleft.md @@ -0,0 +1,71 @@ +--- +{ +"title": "BIT_SHIFT_LEFT", +"language": "zh-CN" +} +--- + + + +## bit_shift_left +### description +#### syntax + +`BIT_SHIFT_LEFT(BIGINT x, TINYINT c)` + +将 BIGINT 类型的 x 向左移动 c 位,并将结果作为 BIGINT 返回。 +如果 c 小于 0,则返回零。 + +### example +```sql +select 8 as x, number as c, bit_shift_left(8, number) as bit_shift_left from numbers("number"="5") +-------------- + ++------+------+----------------+ +| x | c | bit_shift_left | ++------+------+----------------+ +| 8 | 0 | 8 | +| 8 | 1 | 16 | +| 8 | 2 | 32 | +| 8 | 3 | 64 | +| 8 | 4 | 128 | ++------+------+----------------+ +5 rows in set (0.04 sec) +``` +对于 BIGINT 类型的最大值 9223372036854775807(即 BIGINT_MAX),进行一位左移的结果将得到 -2。 +```sql +WITH tbl AS ( + SELECT 9223372036854775807 AS BIGINT_MAX +) +SELECT BIGINT_MAX, bit_shift_left(BIGINT_MAX, 1) +FROM tbl +-------------- + ++---------------------+-------------------------------+ +| BIGINT_MAX | bit_shift_left(BIGINT_MAX, 1) | ++---------------------+-------------------------------+ +| 9223372036854775807 | -2 | ++---------------------+-------------------------------+ +1 row in set (0.05 sec) +``` + +### keywords + + BITSHIFT, BITSHIFTLEFT diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitshiftright.md b/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitshiftright.md new file mode 100644 index 0000000000..4308bff470 --- /dev/null +++ b/docs/zh-CN/docs/sql-manual/sql-functions/bitwise-functions/bitshiftright.md @@ -0,0 +1,78 @@ +--- +{ +"title": "BIT_SHIFT_RIGHT", +"language": "zh-CN" +} +--- + + +## bit_shift_right +### description +#### syntax + +`BIT_SHIFT_RIGHT(BIGINT x, TINYINT c)` + +返回对 BIGINT 类型 x 进行逻辑右移 c 位的结果。 + +### example +Normal case +```sql +select 1024 as x, number as c, bit_shift_right(1024, number) as bit_shift_right from numbers("number"="5") +-------------- + ++------+------+-----------------+ +| x | c | bit_shift_right | ++------+------+-----------------+ +| 1024 | 0 | 1024 | +| 1024 | 1 | 512 | +| 1024 | 2 | 256 | +| 1024 | 3 | 128 | +| 1024 | 4 | 64 | ++------+------+-----------------+ +5 rows in set (0.03 sec) +``` +BIGINT -1 逻辑右移一位得到的结果是 BIGINT_MAX + +```sql +select bit_shift_right(-1, 1) +-------------- + ++------------------------+ +| bit_shift_right(-1, 1) | ++------------------------+ +| 9223372036854775807 | ++------------------------+ +``` +如果 c 小于 0 得到的结果始终为 0 +```sql +select bit_shift_right(100, -1) +-------------- + ++--------------------------+ +| bit_shift_right(100, -1) | ++--------------------------+ +| 0 | ++--------------------------+ +1 row in set (0.04 sec) +``` + +### keywords + + BITSHIFT, BITSHIFTRIGHT diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java index fcc2a351bf..492c561f0a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java @@ -73,7 +73,10 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ascii; import org.apache.doris.nereids.trees.expressions.functions.scalar.Asin; import org.apache.doris.nereids.trees.expressions.functions.scalar.Atan; import org.apache.doris.nereids.trees.expressions.functions.scalar.Bin; +import org.apache.doris.nereids.trees.expressions.functions.scalar.BitCount; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitLength; +import org.apache.doris.nereids.trees.expressions.functions.scalar.BitShiftLeft; +import org.apache.doris.nereids.trees.expressions.functions.scalar.BitShiftRight; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapAnd; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapAndCount; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapAndNot; @@ -486,6 +489,7 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(Asin.class, "asin"), scalar(Atan.class, "atan"), scalar(Bin.class, "bin"), + scalar(BitCount.class, "bit_count"), scalar(BitLength.class, "bit_length"), scalar(BitmapAnd.class, "bitmap_and"), scalar(BitmapAndCount.class, "bitmap_and_count"), @@ -516,6 +520,8 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(BitmapToString.class, "bitmap_to_string"), scalar(BitmapXor.class, "bitmap_xor"), scalar(BitmapXorCount.class, "bitmap_xor_count"), + scalar(BitShiftLeft.class, "bit_shift_left"), + scalar(BitShiftRight.class, "bit_shift_right"), scalar(Cardinality.class, "array_size", "cardinality", "size"), scalar(Cbrt.class, "cbrt"), scalar(Ceil.class, "ceil", "ceiling"), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitCount.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitCount.java new file mode 100644 index 0000000000..5cbbf24df9 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitCount.java @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; +import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.BigIntType; +import org.apache.doris.nereids.types.IntegerType; +import org.apache.doris.nereids.types.LargeIntType; +import org.apache.doris.nereids.types.SmallIntType; +import org.apache.doris.nereids.types.TinyIntType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** BitCount function */ + +public class BitCount extends ScalarFunction + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullable { + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(TinyIntType.INSTANCE).args(TinyIntType.INSTANCE), + FunctionSignature.ret(TinyIntType.INSTANCE).args(SmallIntType.INSTANCE), + FunctionSignature.ret(TinyIntType.INSTANCE).args(IntegerType.INSTANCE), + FunctionSignature.ret(TinyIntType.INSTANCE).args(BigIntType.INSTANCE), + FunctionSignature.ret(SmallIntType.INSTANCE).args(LargeIntType.INSTANCE)); + + public BitCount(Expression arg) { + super("bit_count", arg); + } + + @Override + public BitCount withChildren(List children) { + Preconditions.checkArgument(children.size() == 1); + return new BitCount(children.get(0)); + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitBitCount(this, context); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitShiftLeft.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitShiftLeft.java new file mode 100644 index 0000000000..aa78d01e32 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitShiftLeft.java @@ -0,0 +1,61 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; +import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.BigIntType; +import org.apache.doris.nereids.types.TinyIntType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** BitShiftLeft function */ + +public class BitShiftLeft extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullable { + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(BigIntType.INSTANCE).args(BigIntType.INSTANCE, TinyIntType.INSTANCE)); + + public BitShiftLeft(Expression arg1, Expression arg2) { + super("bit_shift_left", arg1, arg2); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitBitShiftLeft(this, context); + } + + @Override + public BitShiftLeft withChildren(List children) { + Preconditions.checkArgument(children.size() == 2); + return new BitShiftLeft(children.get(0), children.get(1)); + } +} + diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitShiftRight.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitShiftRight.java new file mode 100644 index 0000000000..ab2bce00a0 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/BitShiftRight.java @@ -0,0 +1,63 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; +import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.BigIntType; +import org.apache.doris.nereids.types.TinyIntType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** BitShiftRight + * Do logical right shift to a BigInt value x by c bits. + */ + +public class BitShiftRight extends ScalarFunction + implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullable { + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(BigIntType.INSTANCE).args(BigIntType.INSTANCE, TinyIntType.INSTANCE)); + + public BitShiftRight(Expression arg1, Expression arg2) { + super("bit_shift_right", arg1, arg2); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitBitShiftRight(this, context); + } + + @Override + public BitShiftRight withChildren(List children) { + Preconditions.checkArgument(children.size() == 2); + return new BitShiftRight(children.get(0), children.get(1)); + } +} + diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java index 01823f7819..8629d15b2b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java @@ -73,7 +73,10 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Ascii; import org.apache.doris.nereids.trees.expressions.functions.scalar.Asin; import org.apache.doris.nereids.trees.expressions.functions.scalar.Atan; import org.apache.doris.nereids.trees.expressions.functions.scalar.Bin; +import org.apache.doris.nereids.trees.expressions.functions.scalar.BitCount; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitLength; +import org.apache.doris.nereids.trees.expressions.functions.scalar.BitShiftLeft; +import org.apache.doris.nereids.trees.expressions.functions.scalar.BitShiftRight; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapAnd; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapAndCount; import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapAndNot; @@ -625,6 +628,10 @@ public interface ScalarFunctionVisitor { return visitScalarFunction(bin, context); } + default R visitBitCount(BitCount bitCount, C context) { + return visitScalarFunction(bitCount, context); + } + default R visitBitLength(BitLength bitLength, C context) { return visitScalarFunction(bitLength, context); } @@ -745,6 +752,14 @@ public interface ScalarFunctionVisitor { return visitScalarFunction(bitmapXorCount, context); } + default R visitBitShiftLeft(BitShiftLeft bitShiftLeft, C context) { + return visitScalarFunction(bitShiftLeft, context); + } + + default R visitBitShiftRight(BitShiftRight bitShiftRight, C context) { + return visitScalarFunction(bitShiftRight, context); + } + default R visitCardinality(Cardinality cardinality, C context) { return visitScalarFunction(cardinality, context); } diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 183b38bdfd..a9d2fe26dc 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -51,6 +51,12 @@ visible_functions = { [['bitand'], 'INT', ['INT', 'INT'], ''], [['bitand'], 'BIGINT', ['BIGINT', 'BIGINT'], ''], [['bitand'], 'LARGEINT', ['LARGEINT', 'LARGEINT'], ''], + + [['bit_count'], 'TINYINT', ['TINYINT'], ''], + [['bit_count'], 'TINYINT', ['SMALLINT'], ''], + [['bit_count'], 'TINYINT', ['INT'], ''], + [['bit_count'], 'TINYINT', ['BIGINT'], ''], + [['bit_count'], 'SMALLINT', ['LARGEINT'], ''], [['bitor'], 'TINYINT', ['TINYINT', 'TINYINT'], ''], [['bitor'], 'SMALLINT', ['SMALLINT', 'SMALLINT'], ''], @@ -68,7 +74,10 @@ visible_functions = { [['bitnot'], 'SMALLINT', ['SMALLINT'], ''], [['bitnot'], 'INT', ['INT'], ''], [['bitnot'], 'BIGINT', ['BIGINT'], ''], - [['bitnot'], 'LARGEINT', ['LARGEINT'], ''] + [['bitnot'], 'LARGEINT', ['LARGEINT'], ''], + + [['bit_shift_left'], 'BIGINT', ['BIGINT', 'TINYINT'], ''], + [['bit_shift_right'], 'BIGINT', ['BIGINT', 'TINYINT'], ''] ], # map functions diff --git a/regression-test/data/correctness_p0/test_bit_function.out b/regression-test/data/correctness_p0/test_bit_function.out index 0fe60dde32..02334fcab2 100644 --- a/regression-test/data/correctness_p0/test_bit_function.out +++ b/regression-test/data/correctness_p0/test_bit_function.out @@ -2,3 +2,135 @@ -- !select -- 64 123713 123649 -322 +-- !bit_count -- +0 +1 +1 +2 +1 +2 +2 +3 +1 +2 + +-- !bit_count -- +0 + +-- !bit_count -- +8 + +-- !bit_count -- +8 + +-- !bit_count -- +16 + +-- !bit_count -- +32 + +-- !bit_count -- +64 + +-- !bit_count -- +128 + +-- !bit_count_TINYINT_MAX -- +7 + +-- !bit_count_TINYINT_MIN -- +1 + +-- !bit_count_SMALLINT_MAX -- +15 + +-- !bit_count_SMALLINT_MIN -- +1 + +-- !bit_count_INT_MAX -- +31 + +-- !bit_count_INT_IN -- +1 + +-- !bit_count_INT64_MAX -- +63 + +-- !bit_count_INT64_MIN -- +1 + +-- !bit_count_INT128_MAX -- +127 127 + +-- !bit_count_INT128_MIN -- +1 1 + +-- !select -- +1 1 + +-- !bit_count -- +0 +1 +1 +2 +1 +2 +2 +3 +1 +2 + +-- !bit_count -- +0 + +-- !bit_count -- +8 + +-- !bit_count -- +8 + +-- !bit_count -- +16 + +-- !bit_count -- +32 + +-- !bit_count -- +64 + +-- !bit_count -- +128 + +-- !bit_count_TINYINT_MAX -- +7 + +-- !bit_count_TINYINT_MIN -- +1 + +-- !bit_count_SMALLINT_MAX -- +15 + +-- !bit_count_SMALLINT_MIN -- +1 + +-- !bit_count_INT_MAX -- +31 + +-- !bit_count_INT_IN -- +1 + +-- !bit_count_INT64_MAX -- +63 + +-- !bit_count_INT64_MIN -- +1 + +-- !bit_count_INT128_MAX -- +127 127 + +-- !bit_count_INT128_MIN -- +1 1 + +-- !select -- +1 1 + diff --git a/regression-test/data/correctness_p0/test_bit_shift_lagency.out b/regression-test/data/correctness_p0/test_bit_shift_lagency.out new file mode 100644 index 0000000000..1c956fe3c7 --- /dev/null +++ b/regression-test/data/correctness_p0/test_bit_shift_lagency.out @@ -0,0 +1,345 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !comment -- +testing big_shift_left + +-- !numbers -- +0 +16 +32 +48 +64 +80 +96 +112 +128 +144 + +-- !0 -- +0 + +-- !1 -- +1024 + +-- !2 -- +-9223372036854775808 + +-- !3 -- +1 + +-- !select -- +254 + +-- !select -- +254 + +-- !int64_max -- +9223372036854775807 -2 + +-- !int64_min -- +-9223372036854775808 0 + +-- !select -- +127 -9223372036854775808 + +-- !select -- +-128 0 + +-- !select -- +0 254 65534 4294967294 -2 +1 -256 -65536 -4294967296 -2 + +-- !comment -- +testing big_shift_right + +-- !select -- +0 + +-- !select -- +0 + +-- !select -- +1 + +-- !select -- +0 + +-- !select -- +9223372036854775807 + +-- !select -- +2 + +-- !select -- +1 + +-- !select -- +-9223372036854775808 + +-- !select -- +0 + +-- !select -- +0 + +-- !select -- +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 + +-- !select -- +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 + diff --git a/regression-test/data/correctness_p0/test_bit_shift_nereids.out b/regression-test/data/correctness_p0/test_bit_shift_nereids.out new file mode 100644 index 0000000000..1c956fe3c7 --- /dev/null +++ b/regression-test/data/correctness_p0/test_bit_shift_nereids.out @@ -0,0 +1,345 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !comment -- +testing big_shift_left + +-- !numbers -- +0 +16 +32 +48 +64 +80 +96 +112 +128 +144 + +-- !0 -- +0 + +-- !1 -- +1024 + +-- !2 -- +-9223372036854775808 + +-- !3 -- +1 + +-- !select -- +254 + +-- !select -- +254 + +-- !int64_max -- +9223372036854775807 -2 + +-- !int64_min -- +-9223372036854775808 0 + +-- !select -- +127 -9223372036854775808 + +-- !select -- +-128 0 + +-- !select -- +0 254 65534 4294967294 -2 +1 -256 -65536 -4294967296 -2 + +-- !comment -- +testing big_shift_right + +-- !select -- +0 + +-- !select -- +0 + +-- !select -- +1 + +-- !select -- +0 + +-- !select -- +9223372036854775807 + +-- !select -- +2 + +-- !select -- +1 + +-- !select -- +-9223372036854775808 + +-- !select -- +0 + +-- !select -- +0 + +-- !select -- +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 + +-- !select -- +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 + diff --git a/regression-test/suites/correctness_p0/test_bit_function.groovy b/regression-test/suites/correctness_p0/test_bit_function.groovy index 10b6e52de1..fc7b2c454b 100644 --- a/regression-test/suites/correctness_p0/test_bit_function.groovy +++ b/regression-test/suites/correctness_p0/test_bit_function.groovy @@ -18,4 +18,67 @@ suite("test_bit_functions") { sql "SET enable_nereids_planner=false" qt_select 'select bitand(123456, 321.0), bitor(123456, 321.0), bitxor(123456, 321.0), bitnot(321.0);' + + sql "SET enable_nereids_planner=false;" + qt_bit_count 'select bit_count(number) from numbers("number"="10");' + qt_bit_count 'select bit_count(0);' + qt_bit_count 'select bit_count(-1);' + qt_bit_count 'select bit_count(cast (-1 as tinyint));' // 8 + qt_bit_count 'select bit_count(cast (-1 as smallint));' // 16 + qt_bit_count 'select bit_count(cast (-1 as int));' // 32 + qt_bit_count 'select bit_count(cast (-1 as bigint));' // 64 + qt_bit_count 'select bit_count(cast (-1 as largeint));' // 128 + qt_bit_count_TINYINT_MAX 'select bit_count(cast (127 as tinyint));' // TINYINT_MAX + qt_bit_count_TINYINT_MIN 'select bit_count(cast (-128 as tinyint));' // TINYINT_MIN + qt_bit_count_SMALLINT_MAX 'select bit_count(cast (32767 as smallint));' // SMALLINT_MAX + qt_bit_count_SMALLINT_MIN 'select bit_count(cast (-32768 as smallint));' // SMALLINT_MIN + qt_bit_count_INT_MAX 'select bit_count(cast (2147483647 as int));' // INT_MAX + qt_bit_count_INT_IN 'select bit_count(cast (-2147483648 as int));' // INT_MIN + qt_bit_count_INT64_MAX 'select bit_count(cast (9223372036854775807 as bigint));' // INT64_MAX + qt_bit_count_INT64_MIN 'select bit_count(cast (-9223372036854775808 as bigint));' // INT64_MIN + // INT128_MAX + qt_bit_count_INT128_MAX """ + select bit_count(170141183460469231731687303715884105727), + bit_count(cast (170141183460469231731687303715884105727 as largeint)); + """ + // INT128_MIN + qt_bit_count_INT128_MIN """ + select bit_count(-170141183460469231731687303715884105728), + bit_count(cast (-170141183460469231731687303715884105728 as largeint)); + """ + + qt_select "select bit_count(bit_shift_right(-1, 63)), bit_count(bit_shift_right(-1, 63));" + + sql "SET enable_nereids_planner=true;" + sql "SET enable_fallback_to_original_planner=false;" + + qt_bit_count 'select bit_count(number) from numbers("number"="10");' + qt_bit_count 'select bit_count(0);' + qt_bit_count 'select bit_count(-1);' + qt_bit_count 'select bit_count(cast (-1 as tinyint));' // 8 + qt_bit_count 'select bit_count(cast (-1 as smallint));' // 16 + qt_bit_count 'select bit_count(cast (-1 as int));' // 32 + qt_bit_count 'select bit_count(cast (-1 as bigint));' // 64 + qt_bit_count 'select bit_count(cast (-1 as largeint));' // 128 + qt_bit_count_TINYINT_MAX 'select bit_count(cast (127 as tinyint));' // TINYINT_MAX + qt_bit_count_TINYINT_MIN 'select bit_count(cast (-128 as tinyint));' // TINYINT_MIN + qt_bit_count_SMALLINT_MAX 'select bit_count(cast (32767 as smallint));' // SMALLINT_MAX + qt_bit_count_SMALLINT_MIN 'select bit_count(cast (-32768 as smallint));' // SMALLINT_MIN + qt_bit_count_INT_MAX 'select bit_count(cast (2147483647 as int));' // INT_MAX + qt_bit_count_INT_IN 'select bit_count(cast (-2147483648 as int));' // INT_MIN + qt_bit_count_INT64_MAX 'select bit_count(cast (9223372036854775807 as bigint));' // INT64_MAX + qt_bit_count_INT64_MIN 'select bit_count(cast (-9223372036854775808 as bigint));' // INT64_MIN + // INT128_MAX + qt_bit_count_INT128_MAX """ + select bit_count(170141183460469231731687303715884105727), + bit_count(cast (170141183460469231731687303715884105727 as largeint)); + """ + // INT128_MIN + qt_bit_count_INT128_MIN """ + select bit_count(-170141183460469231731687303715884105728), + bit_count(cast (-170141183460469231731687303715884105728 as largeint)); + """ + + qt_select "select bit_count(bit_shift_right(-1, 63)), bit_count(bit_shift_right(-1, 63));" + } diff --git a/regression-test/suites/correctness_p0/test_bit_shift_lagency.groovy b/regression-test/suites/correctness_p0/test_bit_shift_lagency.groovy new file mode 100644 index 0000000000..2db6ab0e90 --- /dev/null +++ b/regression-test/suites/correctness_p0/test_bit_shift_lagency.groovy @@ -0,0 +1,105 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_bit_shift_lagency") { + sql "SET enable_nereids_planner=false;" + + qt_comment """ + select "testing big_shift_left"; + """ + def INT64_MAX=9223372036854775807; + def INT64_MIN=-9223372036854775808; + def INT8_MAX=127 + def INT8_MIN=-128 + + // bit_shift_left + + qt_numbers 'select bit_shift_left(number, 4) from numbers("number"="10");' + qt_0 "select bit_shift_left(0, 0);" + qt_1 "select bit_shift_left(1, 10);" + qt_2 "select bit_shift_left(1, 63);" + qt_3 "select bit_shift_left(1, 64);" + qt_select "select bit_shift_left(127, 1);" + qt_select "select bit_shift_left(cast (127 as TINYINT), 1);" + qt_int64_max """ + WITH tbl AS ( + SELECT ${INT64_MAX} AS BIGINT_MAX) + SELECT BIGINT_MAX, bit_shift_left(BIGINT_MAX, 1) + FROM tbl + """ + qt_int64_min """ + WITH tbl AS ( + SELECT ${INT64_MIN} AS BIGINT_MIN) + SELECT BIGINT_MIN, bit_shift_left(BIGINT_MIN, 1) + FROM tbl + """ + qt_select """ + WITH tbl AS ( + SELECT ${INT8_MAX} AS TINYINT_MAX) + SELECT TINYINT_MAX, bit_shift_left(1, TINYINT_MAX) + FROM tbl + """ + qt_select """ + WITH tbl AS ( + SELECT ${INT8_MIN} AS TINYINT_MIN) + SELECT TINYINT_MIN, bit_shift_left(1, TINYINT_MIN) + FROM tbl + """ + + sql """ drop table if exists test_bit_shift_nereids; """ + sql """ + create table test_bit_shift_nereids ( + rid tinyint, + ti tinyint, + si smallint, + i int, + bi bigint + ) distributed by HASH(rid) + properties("replication_num"="1"); + """ + sql """ insert into test_bit_shift_nereids values + (0, 127, 32767, 2147483647, ${INT64_MAX}), + (1, -128, -32768, -2147483648, ${INT64_MAX})""" + + qt_select """ + select rid, + bit_shift_left(ti, 1), bit_shift_left(si, 1), + bit_shift_left(i, 1), bit_shift_left(bi, 1) + from test_bit_shift_nereids order by rid; """ + + // bit_shift_right + + qt_comment """ + select "testing big_shift_right"; + """ + + qt_select "SELECT bit_shift_right(0, 0);" + qt_select "SELECT bit_shift_right(0, 127);" + qt_select "SELECT bit_shift_right(${INT64_MAX}, 62);" + qt_select "SELECT bit_shift_right(${INT64_MAX}, 63);" + qt_select "SELECT bit_shift_right(${INT64_MAX}, 64);" + qt_select "SELECT bit_shift_right(${INT64_MIN}, 62);" + qt_select "SELECT bit_shift_right(${INT64_MIN}, 63);" + qt_select "SELECT bit_shift_right(${INT64_MIN}, 64);" + qt_select "SELECT bit_shift_right(1, ${INT8_MAX});" + qt_select "SELECT bit_shift_right(1, ${INT8_MIN});" + + // nagitave shift count + + qt_select """SELECT bit_shift_right(1, -number) from numbers("number"="129") order by number;""" + qt_select """SELECT bit_shift_right(1, -number) from numbers("number"="129") order by number;""" +} diff --git a/regression-test/suites/correctness_p0/test_bit_shift_nereids.groovy b/regression-test/suites/correctness_p0/test_bit_shift_nereids.groovy new file mode 100644 index 0000000000..65f8687737 --- /dev/null +++ b/regression-test/suites/correctness_p0/test_bit_shift_nereids.groovy @@ -0,0 +1,105 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_bit_shift_nereids") { + sql "SET enable_nereids_planner=true;" + sql "SET enable_fallback_to_original_planner=false;" + + qt_comment """ + select "testing big_shift_left"; + """ + def INT64_MAX=9223372036854775807; + def INT64_MIN=-9223372036854775808; + def INT8_MAX=127 + def INT8_MIN=-128 + + // bit_shift_left + + qt_numbers 'select bit_shift_left(number, 4) from numbers("number"="10");' + qt_0 "select bit_shift_left(0, 0);" + qt_1 "select bit_shift_left(1, 10);" + qt_2 "select bit_shift_left(1, 63);" + qt_3 "select bit_shift_left(1, 64);" + qt_select "select bit_shift_left(127, 1);" + qt_select "select bit_shift_left(cast (127 as TINYINT), 1);" + qt_int64_max """ + WITH tbl AS ( + SELECT ${INT64_MAX} AS BIGINT_MAX) + SELECT BIGINT_MAX, bit_shift_left(BIGINT_MAX, 1) + FROM tbl + """ + qt_int64_min """ + WITH tbl AS ( + SELECT ${INT64_MIN} AS BIGINT_MIN) + SELECT BIGINT_MIN, bit_shift_left(BIGINT_MIN, 1) + FROM tbl + """ + qt_select """ + WITH tbl AS ( + SELECT ${INT8_MAX} AS TINYINT_MAX) + SELECT TINYINT_MAX, bit_shift_left(1, TINYINT_MAX) + FROM tbl + """ + qt_select """ + WITH tbl AS ( + SELECT ${INT8_MIN} AS TINYINT_MIN) + SELECT TINYINT_MIN, bit_shift_left(1, TINYINT_MIN) + FROM tbl + """ + + sql """ drop table if exists test_bit_shift_nereids; """ + sql """ + create table test_bit_shift_nereids ( + rid tinyint, + ti tinyint, + si smallint, + i int, + bi bigint + ) distributed by HASH(rid) + properties("replication_num"="1"); + """ + sql """ insert into test_bit_shift_nereids values + (0, 127, 32767, 2147483647, ${INT64_MAX}), + (1, -128, -32768, -2147483648, ${INT64_MAX})""" + + qt_select """ + select rid, + bit_shift_left(ti, 1), bit_shift_left(si, 1), + bit_shift_left(i, 1), bit_shift_left(bi, 1) + from test_bit_shift_nereids order by rid; """ + // bit_shift_right + + qt_comment """ + select "testing big_shift_right"; + """ + + qt_select "SELECT bit_shift_right(0, 0);" + qt_select "SELECT bit_shift_right(0, 127);" + qt_select "SELECT bit_shift_right(${INT64_MAX}, 62);" + qt_select "SELECT bit_shift_right(${INT64_MAX}, 63);" + qt_select "SELECT bit_shift_right(${INT64_MAX}, 64);" + qt_select "SELECT bit_shift_right(${INT64_MIN}, 62);" + qt_select "SELECT bit_shift_right(${INT64_MIN}, 63);" + qt_select "SELECT bit_shift_right(${INT64_MIN}, 64);" + qt_select "SELECT bit_shift_right(1, ${INT8_MAX});" + qt_select "SELECT bit_shift_right(1, ${INT8_MIN});" + + // nagitave shift count + + qt_select """SELECT bit_shift_right(1, -number) from numbers("number"="129") order by number;""" + qt_select """SELECT bit_shift_right(1, -number) from numbers("number"="129") order by number;""" +}