| /** |
| * 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 <initializer_list> |
| #include <utility> |
| |
| #include "types/Type.hpp" |
| #include "types/TypeFactory.hpp" |
| #include "types/TypeID.hpp" |
| #include "types/operations/binary_operations/BinaryOperation.hpp" |
| #include "types/operations/binary_operations/ModuloBinaryOperation.hpp" |
| #include "types/operations/binary_operations/tests/BinaryOperationTestUtil.hpp" |
| |
| #include "gtest/gtest.h" |
| |
| namespace quickstep { |
| |
| TEST(ModuloBinaryOperationTest, ResultTypeForPartialArgumentTypesTest) { |
| // If both argument types are unknown, the result is unknown. |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes(nullptr, nullptr)); |
| |
| // Double has highest precedence of numeric types. |
| for (const TypeID type_id : {kDouble}) { |
| const Type *result_type = ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| &TypeFactory::GetType(type_id, false), |
| nullptr); |
| ASSERT_NE(result_type, nullptr); |
| EXPECT_TRUE(TypeFactory::GetType(type_id, true).equals(*result_type)); |
| |
| result_type = ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| &TypeFactory::GetType(type_id, true), |
| nullptr); |
| ASSERT_NE(result_type, nullptr); |
| EXPECT_TRUE(TypeFactory::GetType(type_id, true).equals(*result_type)); |
| } |
| |
| // Other types for left argument are ambiguous or inapplicable. |
| for (const TypeID type_id : {kInt, kLong, kFloat, kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| &TypeFactory::GetType(type_id, false), |
| nullptr)); |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| &TypeFactory::GetType(type_id, true), |
| nullptr)); |
| } |
| for (const TypeID type_id : {kChar, kVarChar}) { |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| &TypeFactory::GetType(type_id, 10, false), |
| nullptr)); |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| &TypeFactory::GetType(type_id, 10, true), |
| nullptr)); |
| } |
| |
| // Can't determine a return type from just the divisor. |
| for (const TypeID type_id : {kInt, kLong, kFloat, kDouble, kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| nullptr, |
| &TypeFactory::GetType(type_id, false))); |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| nullptr, |
| &TypeFactory::GetType(type_id, true))); |
| } |
| for (const TypeID type_id : {kChar, kVarChar}) { |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| nullptr, |
| &TypeFactory::GetType(type_id, 10, false))); |
| EXPECT_EQ(nullptr, |
| ModuloBinaryOperation::Instance().resultTypeForPartialArgumentTypes( |
| nullptr, |
| &TypeFactory::GetType(type_id, 10, true))); |
| } |
| } |
| |
| TEST(ModuloBinaryOperationTest, PartialTypeSignatureIsPlausibleTest) { |
| // -------------------------------------------------------------------------- |
| // All 3 Types unknown. |
| EXPECT_TRUE(ModuloBinaryOperation::Instance().partialTypeSignatureIsPlausible( |
| nullptr, nullptr, nullptr)); |
| |
| // -------------------------------------------------------------------------- |
| // Result type known, both argument types unknown. |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndUnknownArguments( |
| ModuloBinaryOperation::Instance(), |
| {kInt, kLong, kFloat, kDouble}); |
| |
| // -------------------------------------------------------------------------- |
| // Result type unknown, left argument type known. |
| BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument( |
| ModuloBinaryOperation::Instance(), |
| {kInt, kLong, kFloat, kDouble}, |
| true, |
| false); |
| |
| // -------------------------------------------------------------------------- |
| // Result type unknown, right argument type known. |
| BinaryOperationTestUtil::CheckPlausibilityWithUnknownResultAndSingleKnownArgument( |
| ModuloBinaryOperation::Instance(), |
| {kInt, kLong, kFloat, kDouble}, |
| false, |
| true); |
| |
| // -------------------------------------------------------------------------- |
| // Result type and left argument type known. |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kInt, {kInt}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kLong, {kInt, kLong}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kFloat, {kInt, kFloat}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kDouble, {kInt, kLong, kFloat, kDouble}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kDatetime, {}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kDatetimeInterval, {}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kYearMonthInterval, {}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kChar, {}, true, false); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kVarChar, {}, true, false); |
| |
| // -------------------------------------------------------------------------- |
| // Result type and right argument type known. |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kInt, {kInt}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kLong, {kInt, kLong}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kFloat, {kInt, kFloat}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kDouble, {kInt, kLong, kFloat, kDouble}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kDatetime, {}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kDatetimeInterval, {}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kYearMonthInterval, {}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kChar, {}, false, true); |
| BinaryOperationTestUtil::CheckPlausibilityWithKnownResultAndSingleArgument( |
| ModuloBinaryOperation::Instance(), kVarChar, {}, false, true); |
| } |
| |
| TEST(ModuloBinaryOperationTest, PushDownTypeHintTest) { |
| const Type *result_type = nullptr; |
| std::pair<const Type*, const Type*> hints |
| = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| EXPECT_EQ(nullptr, hints.first); |
| EXPECT_EQ(nullptr, hints.second); |
| |
| // For any numeric result type, hints for arguments should be the same type. |
| for (const TypeID type_id : {kInt, kLong, kFloat, kDouble}) { |
| result_type = &TypeFactory::GetType(type_id, false); |
| hints = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| ASSERT_NE(hints.first, nullptr); |
| ASSERT_NE(hints.second, nullptr); |
| EXPECT_TRUE(result_type->equals(*hints.first)); |
| EXPECT_TRUE(result_type->equals(*hints.second)); |
| |
| result_type = &TypeFactory::GetType(type_id, true); |
| hints = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| ASSERT_NE(hints.first, nullptr); |
| ASSERT_NE(hints.second, nullptr); |
| EXPECT_TRUE(result_type->equals(*hints.first)); |
| EXPECT_TRUE(result_type->equals(*hints.second)); |
| } |
| |
| // Can't produce non-numeric types. |
| for (const TypeID type_id : {kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| result_type = &TypeFactory::GetType(type_id, false); |
| hints = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| EXPECT_EQ(nullptr, hints.first); |
| EXPECT_EQ(nullptr, hints.second); |
| |
| result_type = &TypeFactory::GetType(type_id, true); |
| hints = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| EXPECT_EQ(nullptr, hints.first); |
| EXPECT_EQ(nullptr, hints.second); |
| } |
| for (const TypeID type_id : {kChar, kVarChar}) { |
| result_type = &TypeFactory::GetType(type_id, 10, false); |
| hints = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| EXPECT_EQ(nullptr, hints.first); |
| EXPECT_EQ(nullptr, hints.second); |
| |
| result_type = &TypeFactory::GetType(type_id, 10, true); |
| hints = ModuloBinaryOperation::Instance().pushDownTypeHint(result_type); |
| EXPECT_EQ(nullptr, hints.first); |
| EXPECT_EQ(nullptr, hints.second); |
| } |
| } |
| |
| } // namespace quickstep |