Skip to content

Commit

Permalink
Add bitwise_and & bitwise_or SparkSQL functions (facebookincubator#3302
Browse files Browse the repository at this point in the history
…) (#75)
  • Loading branch information
PHILO-HE authored Nov 21, 2022
1 parent 8a064a8 commit 29fda23
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 0 deletions.
41 changes: 41 additions & 0 deletions velox/functions/sparksql/Bitwise.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed 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 "velox/functions/sparksql/Bitwise.h"

namespace facebook::velox::functions::sparksql {

template <typename T>
struct BitwiseAndFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a, TInput b) {
result = a & b;
}
};

template <typename T>
struct BitwiseOrFunction {
template <typename TInput>
FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a, TInput b) {
result = a | b;
}
};

void registerBitwiseFunctions(const std::string& prefix) {
registerBinaryIntegral<BitwiseAndFunction>({prefix + "bitwise_and"});
registerBinaryIntegral<BitwiseOrFunction>({prefix + "bitwise_or"});
}

} // namespace facebook::velox::functions::sparksql
26 changes: 26 additions & 0 deletions velox/functions/sparksql/Bitwise.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed 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.
*/
#pragma once

#include <string>
#include "velox/functions/Macros.h"
#include "velox/functions/lib/RegistrationHelpers.h"

namespace facebook::velox::functions::sparksql {

void registerBitwiseFunctions(const std::string& prefix);

} // namespace facebook::velox::functions::sparksql
1 change: 1 addition & 0 deletions velox/functions/sparksql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
add_library(
velox_functions_spark
ArraySort.cpp
Bitwise.cpp
CompareFunctionsNullSafe.cpp
Hash.cpp
In.cpp
Expand Down
2 changes: 2 additions & 0 deletions velox/functions/sparksql/Register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "velox/functions/prestosql/Rand.h"
#include "velox/functions/prestosql/StringFunctions.h"
#include "velox/functions/sparksql/ArraySort.h"
#include "velox/functions/sparksql/Bitwise.h"
#include "velox/functions/sparksql/CompareFunctionsNullSafe.h"
#include "velox/functions/sparksql/Hash.h"
#include "velox/functions/sparksql/In.h"
Expand Down Expand Up @@ -130,6 +131,7 @@ void registerFunctions(const std::string& prefix) {
// broken out into a separate compilation unit to improve build latency.
registerArithmeticFunctions(prefix);
registerCompareFunctions(prefix);
registerBitwiseFunctions(prefix);

// String sreach function
registerFunction<StartsWithFunction, bool, Varchar, Varchar>(
Expand Down
116 changes: 116 additions & 0 deletions velox/functions/sparksql/tests/BitwiseTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed 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 <gmock/gmock.h>
#include <optional>

#include "velox/functions/sparksql/tests/SparkFunctionBaseTest.h"

namespace facebook::velox::functions::sparksql::test {
using namespace facebook::velox::test;

namespace {

static constexpr auto kMin16 = std::numeric_limits<int16_t>::min();
static constexpr auto kMax16 = std::numeric_limits<int16_t>::max();
static constexpr auto kMin32 = std::numeric_limits<int32_t>::min();
static constexpr auto kMax32 = std::numeric_limits<int32_t>::max();
static constexpr auto kMin64 = std::numeric_limits<int64_t>::min();
static constexpr auto kMax64 = std::numeric_limits<int64_t>::max();
static constexpr int kMaxBits = std::numeric_limits<uint64_t>::digits;

class BitwiseTest : public SparkFunctionBaseTest {
protected:
template <typename T>
std::optional<T> bitwiseAnd(std::optional<T> a, std::optional<T> b) {
return evaluateOnce<T>("bitwise_and(c0, c1)", a, b);
}

template <typename T>
std::optional<T> bitwiseOr(std::optional<T> a, std::optional<T> b) {
return evaluateOnce<T>("bitwise_or(c0, c1)", a, b);
}
};

TEST_F(BitwiseTest, bitwiseAnd) {
EXPECT_EQ(bitwiseAnd<int32_t>(0, -1), 0);
EXPECT_EQ(bitwiseAnd<int32_t>(3, 8), 0);
EXPECT_EQ(bitwiseAnd<int32_t>(-4, 12), 12);
EXPECT_EQ(bitwiseAnd<int32_t>(60, 21), 20);

EXPECT_EQ(bitwiseAnd<int16_t>(kMin16, kMax16), 0);
EXPECT_EQ(bitwiseAnd<int16_t>(kMax16, kMax16), kMax16);
EXPECT_EQ(bitwiseAnd<int16_t>(kMax16, kMin16), 0);
EXPECT_EQ(bitwiseAnd<int16_t>(kMin16, kMin16), kMin16);
EXPECT_EQ(bitwiseAnd<int16_t>(kMax16, 1), 1);
EXPECT_EQ(bitwiseAnd<int16_t>(kMax16, -1), kMax16);
EXPECT_EQ(bitwiseAnd<int16_t>(kMin16, 1), 0);
EXPECT_EQ(bitwiseAnd<int16_t>(kMin16, -1), kMin16);

EXPECT_EQ(bitwiseAnd<int32_t>(kMin32, kMax32), 0);
EXPECT_EQ(bitwiseAnd<int32_t>(kMax32, kMax32), kMax32);
EXPECT_EQ(bitwiseAnd<int32_t>(kMax32, kMin32), 0);
EXPECT_EQ(bitwiseAnd<int32_t>(kMin32, kMin32), kMin32);
EXPECT_EQ(bitwiseAnd<int32_t>(kMax32, 1), 1);
EXPECT_EQ(bitwiseAnd<int32_t>(kMax32, -1), kMax32);
EXPECT_EQ(bitwiseAnd<int32_t>(kMin32, 1), 0);
EXPECT_EQ(bitwiseAnd<int32_t>(kMin32, -1), kMin32);

EXPECT_EQ(bitwiseAnd<int64_t>(kMin64, kMax64), 0);
EXPECT_EQ(bitwiseAnd<int64_t>(kMax64, kMax64), kMax64);
EXPECT_EQ(bitwiseAnd<int64_t>(kMax64, kMin64), 0);
EXPECT_EQ(bitwiseAnd<int64_t>(kMin64, kMin64), kMin64);
EXPECT_EQ(bitwiseAnd<int64_t>(kMax64, 1), 1);
EXPECT_EQ(bitwiseAnd<int64_t>(kMax64, -1), kMax64);
EXPECT_EQ(bitwiseAnd<int64_t>(kMin64, 1), 0);
EXPECT_EQ(bitwiseAnd<int64_t>(kMin64, -1), kMin64);
}

TEST_F(BitwiseTest, bitwiseOr) {
EXPECT_EQ(bitwiseOr<int32_t>(0, -1), -1);
EXPECT_EQ(bitwiseOr<int32_t>(3, 8), 11);
EXPECT_EQ(bitwiseOr<int32_t>(-4, 12), -4);
EXPECT_EQ(bitwiseOr<int32_t>(60, 21), 61);

EXPECT_EQ(bitwiseOr<int16_t>(kMin16, kMax16), -1);
EXPECT_EQ(bitwiseOr<int16_t>(kMax16, kMax16), kMax16);
EXPECT_EQ(bitwiseOr<int16_t>(kMax16, kMin16), -1);
EXPECT_EQ(bitwiseOr<int16_t>(kMin16, kMin16), kMin16);
EXPECT_EQ(bitwiseOr<int16_t>(kMax16, 1), kMax16);
EXPECT_EQ(bitwiseOr<int16_t>(kMax16, -1), -1);
EXPECT_EQ(bitwiseOr<int16_t>(kMin16, 1), kMin16 + 1);
EXPECT_EQ(bitwiseOr<int16_t>(kMin16, -1), -1);

EXPECT_EQ(bitwiseOr<int32_t>(kMin32, kMax32), -1);
EXPECT_EQ(bitwiseOr<int32_t>(kMax32, kMax32), kMax32);
EXPECT_EQ(bitwiseOr<int32_t>(kMax32, kMin32), -1);
EXPECT_EQ(bitwiseOr<int32_t>(kMin32, kMin32), kMin32);
EXPECT_EQ(bitwiseOr<int32_t>(kMax32, 1), kMax32);
EXPECT_EQ(bitwiseOr<int32_t>(kMax32, -1), -1);
EXPECT_EQ(bitwiseOr<int32_t>(kMin32, 1), kMin32 + 1);
EXPECT_EQ(bitwiseOr<int32_t>(kMin32, -1), -1);

EXPECT_EQ(bitwiseOr<int64_t>(kMin64, kMax64), -1);
EXPECT_EQ(bitwiseOr<int64_t>(kMax64, kMax64), kMax64);
EXPECT_EQ(bitwiseOr<int64_t>(kMax64, kMin64), -1);
EXPECT_EQ(bitwiseOr<int64_t>(kMin64, kMin64), kMin64);
EXPECT_EQ(bitwiseOr<int64_t>(kMax64, 1), kMax64);
EXPECT_EQ(bitwiseOr<int64_t>(kMax64, -1), -1);
EXPECT_EQ(bitwiseOr<int64_t>(kMin64, 1), kMin64 + 1);
EXPECT_EQ(bitwiseOr<int64_t>(kMin64, -1), -1);
}

} // namespace
} // namespace facebook::velox::functions::sparksql::test
1 change: 1 addition & 0 deletions velox/functions/sparksql/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_executable(
velox_functions_spark_test
ArithmeticTest.cpp
ArraySortTest.cpp
BitwiseTest.cpp
CompareNullSafeTests.cpp
HashTest.cpp
InTest.cpp
Expand Down

0 comments on commit 29fda23

Please sign in to comment.