| /** |
| * 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 <algorithm> |
| #include <cstddef> |
| #include <cstdint> |
| #include <cstring> |
| #include <limits> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "types/DatetimeLit.hpp" |
| #include "types/IntervalLit.hpp" |
| #include "types/Type.hpp" |
| #include "types/TypeFactory.hpp" |
| #include "types/TypeID.hpp" |
| #include "types/TypedValue.hpp" |
| #include "types/operations/Operation.pb.h" |
| #include "types/operations/comparisons/Comparison.hpp" |
| #include "types/operations/comparisons/ComparisonFactory.hpp" |
| #include "types/operations/comparisons/ComparisonID.hpp" |
| #include "utility/Macros.hpp" |
| #include "utility/ScopedBuffer.hpp" |
| |
| #include "gtest/gtest.h" |
| |
| using std::int64_t; |
| using std::min; |
| using std::numeric_limits; |
| using std::pair; |
| using std::string; |
| using std::strlen; |
| using std::unique_ptr; |
| using std::vector; |
| |
| namespace quickstep { |
| |
| namespace { |
| |
| static const char kSampleStringShort[] = "foo"; |
| |
| static const char kSampleStringLong[] = |
| "Space is big. You just won't believe how vastly, hugely, mind-bogglingly " |
| "big it is. I mean, you may think it's a long way down the road to the " |
| "chemist's, but that's just peanuts to space."; |
| |
| } // namespace |
| |
| class ComparisonTest : public ::testing::Test { |
| protected: |
| typedef vector<const TypedValue *>::const_iterator const_iterator; |
| |
| virtual void SetUp() { |
| int_null_.reset(new TypedValue(kInt)); |
| int_zero_.reset(new TypedValue(0)); |
| int_positive_.reset(new TypedValue(12345)); |
| int_negative_.reset(new TypedValue(- int_positive_->getLiteral<int>())); |
| int_max_.reset(new TypedValue(numeric_limits<int>::max())); |
| int_min_.reset(new TypedValue(numeric_limits<int>::min())); |
| |
| numeric_typed_values_.emplace_back(int_null_.get(), |
| &TypeFactory::GetType(kInt, true)); |
| numeric_typed_values_.emplace_back(int_zero_.get(), |
| &TypeFactory::GetType(kInt, false)); |
| numeric_typed_values_.emplace_back(int_positive_.get(), |
| &TypeFactory::GetType(kInt, false)); |
| numeric_typed_values_.emplace_back(int_negative_.get(), |
| &TypeFactory::GetType(kInt, false)); |
| numeric_typed_values_.emplace_back(int_max_.get(), |
| &TypeFactory::GetType(kInt, false)); |
| numeric_typed_values_.emplace_back(int_min_.get(), |
| &TypeFactory::GetType(kInt, false)); |
| |
| long_null_.reset(new TypedValue(kLong)); |
| long_zero_.reset(new TypedValue(static_cast<int64_t>(0))); |
| long_positive_.reset(new TypedValue(static_cast<int64_t>(12345))); |
| long_negative_.reset(new TypedValue(- long_positive_->getLiteral<int64_t>())); |
| long_max_.reset(new TypedValue(numeric_limits<int64_t>::max())); |
| long_min_.reset(new TypedValue(numeric_limits<int64_t>::min())); |
| |
| numeric_typed_values_.emplace_back(long_null_.get(), |
| &TypeFactory::GetType(kLong, true)); |
| numeric_typed_values_.emplace_back(long_zero_.get(), |
| &TypeFactory::GetType(kLong, false)); |
| numeric_typed_values_.emplace_back(long_positive_.get(), |
| &TypeFactory::GetType(kLong, false)); |
| numeric_typed_values_.emplace_back(long_negative_.get(), |
| &TypeFactory::GetType(kLong, false)); |
| numeric_typed_values_.emplace_back(long_max_.get(), |
| &TypeFactory::GetType(kLong, false)); |
| numeric_typed_values_.emplace_back(long_min_.get(), |
| &TypeFactory::GetType(kLong, false)); |
| |
| float_null_.reset(new TypedValue(kFloat)); |
| float_zero_.reset(new TypedValue(static_cast<float>(0.0))); |
| float_positive_.reset(new TypedValue(static_cast<float>(123.45))); |
| float_negative_.reset(new TypedValue(- float_positive_->getLiteral<float>())); |
| float_max_.reset(new TypedValue(numeric_limits<float>::max())); |
| float_min_.reset(new TypedValue(numeric_limits<float>::min())); |
| |
| numeric_typed_values_.emplace_back(float_null_.get(), |
| &TypeFactory::GetType(kFloat, true)); |
| numeric_typed_values_.emplace_back(float_zero_.get(), |
| &TypeFactory::GetType(kFloat, false)); |
| numeric_typed_values_.emplace_back(float_positive_.get(), |
| &TypeFactory::GetType(kFloat, false)); |
| numeric_typed_values_.emplace_back(float_negative_.get(), |
| &TypeFactory::GetType(kFloat, false)); |
| numeric_typed_values_.emplace_back(float_max_.get(), |
| &TypeFactory::GetType(kFloat, false)); |
| numeric_typed_values_.emplace_back(float_min_.get(), |
| &TypeFactory::GetType(kFloat, false)); |
| |
| double_null_.reset(new TypedValue(kDouble)); |
| double_zero_.reset(new TypedValue(static_cast<double>(0))); |
| double_positive_.reset(new TypedValue(static_cast<double>(123.45))); |
| double_negative_.reset(new TypedValue(- double_positive_->getLiteral<double>())); |
| double_max_.reset(new TypedValue(numeric_limits<double>::max())); |
| double_min_.reset(new TypedValue(numeric_limits<double>::min())); |
| |
| numeric_typed_values_.emplace_back(double_null_.get(), |
| &TypeFactory::GetType(kDouble, true)); |
| numeric_typed_values_.emplace_back(double_zero_.get(), |
| &TypeFactory::GetType(kDouble, false)); |
| numeric_typed_values_.emplace_back(double_positive_.get(), |
| &TypeFactory::GetType(kDouble, false)); |
| numeric_typed_values_.emplace_back(double_negative_.get(), |
| &TypeFactory::GetType(kDouble, false)); |
| numeric_typed_values_.emplace_back(double_max_.get(), |
| &TypeFactory::GetType(kDouble, false)); |
| numeric_typed_values_.emplace_back(double_min_.get(), |
| &TypeFactory::GetType(kDouble, false)); |
| |
| date_null_.reset(new TypedValue(kDate)); |
| date_positive_.reset(new TypedValue(DateLit::Create(2016, 7, 15))); |
| date_negative_.reset(new TypedValue(DateLit::Create(-18017, 4, 13))); |
| date_max_.reset(new TypedValue(DateLit::Create(99999, 12, 31))); |
| date_min_.reset(new TypedValue(DateLit::Create(-99999, 1, 1))); |
| |
| date_typed_values_.emplace_back(date_null_.get(), |
| &TypeFactory::GetType(kDate, true)); |
| date_typed_values_.emplace_back(date_positive_.get(), |
| &TypeFactory::GetType(kDate, false)); |
| date_typed_values_.emplace_back(date_negative_.get(), |
| &TypeFactory::GetType(kDate, false)); |
| date_typed_values_.emplace_back(date_max_.get(), |
| &TypeFactory::GetType(kDate, false)); |
| date_typed_values_.emplace_back(date_min_.get(), |
| &TypeFactory::GetType(kDate, false)); |
| |
| datetime_null_.reset(new TypedValue(kDatetime)); |
| DatetimeLit datetime; |
| datetime.ticks = 0; |
| datetime_zero_.reset(new TypedValue(datetime)); |
| datetime.ticks = 12345678; |
| datetime_positive_.reset(new TypedValue(datetime)); |
| datetime.ticks = -87654321; |
| datetime_negative_.reset(new TypedValue(datetime)); |
| datetime.ticks = numeric_limits<int64_t>::max(); |
| datetime_max_.reset(new TypedValue(datetime)); |
| datetime.ticks = numeric_limits<int64_t>::min(); |
| datetime_min_.reset(new TypedValue(datetime)); |
| |
| datetime_typed_values_.emplace_back(datetime_null_.get(), |
| &TypeFactory::GetType(kDatetime, true)); |
| datetime_typed_values_.emplace_back(datetime_zero_.get(), |
| &TypeFactory::GetType(kDatetime, false)); |
| datetime_typed_values_.emplace_back(datetime_positive_.get(), |
| &TypeFactory::GetType(kDatetime, false)); |
| datetime_typed_values_.emplace_back(datetime_negative_.get(), |
| &TypeFactory::GetType(kDatetime, false)); |
| datetime_typed_values_.emplace_back(datetime_max_.get(), |
| &TypeFactory::GetType(kDatetime, false)); |
| datetime_typed_values_.emplace_back(datetime_min_.get(), |
| &TypeFactory::GetType(kDatetime, false)); |
| |
| datetime_interval_null_.reset(new TypedValue(kDatetimeInterval)); |
| DatetimeIntervalLit datetime_interval; |
| datetime_interval.interval_ticks = 0; |
| datetime_interval_zero_.reset(new TypedValue(datetime_interval)); |
| datetime_interval.interval_ticks = 87654321; |
| datetime_interval_positive_.reset(new TypedValue(datetime_interval)); |
| datetime_interval.interval_ticks = -12345678; |
| datetime_interval_negative_.reset(new TypedValue(datetime_interval)); |
| |
| datetime_interval_typed_values_.emplace_back(datetime_interval_null_.get(), |
| &TypeFactory::GetType(kDatetimeInterval, true)); |
| datetime_interval_typed_values_.emplace_back(datetime_interval_zero_.get(), |
| &TypeFactory::GetType(kDatetimeInterval, false)); |
| datetime_interval_typed_values_.emplace_back(datetime_interval_positive_.get(), |
| &TypeFactory::GetType(kDatetimeInterval, false)); |
| datetime_interval_typed_values_.emplace_back(datetime_interval_negative_.get(), |
| &TypeFactory::GetType(kDatetimeInterval, false)); |
| |
| year_month_interval_null_.reset(new TypedValue(kYearMonthInterval)); |
| YearMonthIntervalLit year_month_interval; |
| year_month_interval.months = 0; |
| year_month_interval_zero_.reset(new TypedValue(year_month_interval)); |
| year_month_interval.months = 12; // 1 year forward. |
| year_month_interval_positive_.reset(new TypedValue(year_month_interval)); |
| year_month_interval.months = -3; // 3 months backward. |
| year_month_interval_negative_.reset(new TypedValue(year_month_interval)); |
| |
| year_month_interval_typed_values_.emplace_back(year_month_interval_null_.get(), |
| &TypeFactory::GetType(kYearMonthInterval, true)); |
| year_month_interval_typed_values_.emplace_back(year_month_interval_zero_.get(), |
| &TypeFactory::GetType(kYearMonthInterval, false)); |
| year_month_interval_typed_values_.emplace_back(year_month_interval_positive_.get(), |
| &TypeFactory::GetType(kYearMonthInterval, false)); |
| year_month_interval_typed_values_.emplace_back(year_month_interval_negative_.get(), |
| &TypeFactory::GetType(kYearMonthInterval, false)); |
| |
| char_null_.reset(new TypedValue(kChar)); |
| varchar_null_.reset(new TypedValue(kVarChar)); |
| |
| string_typed_values_.emplace_back(char_null_.get(), |
| &TypeFactory::GetType(kChar, 10, true)); |
| string_typed_values_.emplace_back(varchar_null_.get(), |
| &TypeFactory::GetType(kVarChar, 10, true)); |
| |
| const std::size_t string_short_length = strlen(kSampleStringShort); |
| char_ref_short_.reset(new TypedValue(kChar, kSampleStringShort, string_short_length)); |
| char_lit_short_.reset(new TypedValue(kChar, kSampleStringShort, string_short_length)); |
| char_lit_short_->ensureNotReference(); |
| |
| char_ref_null_terminated_short_.reset(new TypedValue(kChar, kSampleStringShort, string_short_length + 1)); |
| char_lit_null_terminated_short_.reset(new TypedValue(kChar, kSampleStringShort, string_short_length + 1)); |
| char_lit_null_terminated_short_->ensureNotReference(); |
| |
| extended_short_char_buffer_.reset(new ScopedBuffer(strlen(kSampleStringShort) + 5)); |
| std::memset(extended_short_char_buffer_->get(), 0, string_short_length + 5); |
| std::memcpy(extended_short_char_buffer_->get(), kSampleStringShort, string_short_length); |
| |
| char_ref_extended_short_.reset(new TypedValue(kChar, extended_short_char_buffer_->get(), string_short_length + 5)); |
| |
| char_lit_extended_short_.reset(new TypedValue(kChar, extended_short_char_buffer_->get(), string_short_length + 5)); |
| char_lit_extended_short_->ensureNotReference(); |
| |
| varchar_ref_short_.reset(new TypedValue(kVarChar, kSampleStringShort, string_short_length + 1)); |
| varchar_lit_short_.reset(new TypedValue(kVarChar, kSampleStringShort, string_short_length + 1)); |
| varchar_lit_short_->ensureNotReference(); |
| |
| string_typed_values_.emplace_back( |
| char_ref_short_.get(), |
| &TypeFactory::GetType(kChar, |
| char_ref_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_lit_short_.get(), |
| &TypeFactory::GetType(kChar, |
| char_lit_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_ref_null_terminated_short_.get(), |
| &TypeFactory::GetType(kChar, |
| char_ref_null_terminated_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_lit_null_terminated_short_.get(), |
| &TypeFactory::GetType(kChar, |
| char_lit_null_terminated_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_ref_extended_short_.get(), |
| &TypeFactory::GetType(kChar, |
| char_ref_extended_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_lit_extended_short_.get(), |
| &TypeFactory::GetType(kChar, |
| char_lit_extended_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| varchar_ref_short_.get(), |
| &TypeFactory::GetType(kVarChar, |
| varchar_ref_short_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| varchar_lit_short_.get(), |
| &TypeFactory::GetType(kVarChar, |
| varchar_lit_short_->getAsciiStringLength(), |
| false)); |
| |
| const std::size_t string_long_length = strlen(kSampleStringLong); |
| char_ref_long_.reset(new TypedValue(kChar, kSampleStringLong, string_long_length)); |
| char_lit_long_.reset(new TypedValue(kChar, kSampleStringLong, string_long_length)); |
| char_lit_long_->ensureNotReference(); |
| |
| char_ref_null_terminated_long_.reset(new TypedValue(kChar, kSampleStringLong, string_long_length + 1)); |
| char_lit_null_terminated_long_.reset(new TypedValue(kChar, kSampleStringLong, string_long_length + 1)); |
| char_lit_null_terminated_long_->ensureNotReference(); |
| |
| extended_long_char_buffer_.reset(new ScopedBuffer(strlen(kSampleStringLong) + 5)); |
| std::memset(extended_long_char_buffer_->get(), 0, string_long_length + 5); |
| std::memcpy(extended_long_char_buffer_->get(), kSampleStringLong, string_long_length); |
| |
| char_ref_extended_long_.reset(new TypedValue(kChar, extended_long_char_buffer_->get(), string_long_length + 5)); |
| |
| char_lit_extended_long_.reset(new TypedValue(kChar, extended_long_char_buffer_->get(), string_long_length + 5)); |
| char_lit_extended_long_->ensureNotReference(); |
| |
| varchar_ref_long_.reset(new TypedValue(kVarChar, kSampleStringLong, string_long_length + 1)); |
| varchar_lit_long_.reset(new TypedValue(kVarChar, kSampleStringLong, string_long_length + 1)); |
| varchar_lit_long_->ensureNotReference(); |
| |
| string_typed_values_.emplace_back( |
| char_ref_long_.get(), |
| &TypeFactory::GetType(kChar, |
| char_ref_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_lit_long_.get(), |
| &TypeFactory::GetType(kChar, |
| char_lit_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_ref_null_terminated_long_.get(), |
| &TypeFactory::GetType(kChar, |
| char_ref_null_terminated_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_lit_null_terminated_long_.get(), |
| &TypeFactory::GetType(kChar, |
| char_lit_null_terminated_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_ref_extended_long_.get(), |
| &TypeFactory::GetType(kChar, |
| char_ref_extended_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| char_lit_extended_long_.get(), |
| &TypeFactory::GetType(kChar, |
| char_lit_extended_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| varchar_ref_long_.get(), |
| &TypeFactory::GetType(kVarChar, |
| varchar_ref_long_->getAsciiStringLength(), |
| false)); |
| string_typed_values_.emplace_back( |
| varchar_lit_long_.get(), |
| &TypeFactory::GetType(kVarChar, |
| varchar_lit_long_->getAsciiStringLength(), |
| false)); |
| } |
| |
| void checkComparison(const Comparison &comparison) { |
| checkNumericComparison(comparison); |
| checkStringComparison(comparison); |
| checkDateComparison(comparison); |
| checkDatetimeComparison(comparison); |
| checkDatetimeIntervalComparison(comparison); |
| checkYearMonthIntervalComparison(comparison); |
| } |
| |
| private: |
| template <typename NumericType> |
| static NumericType GetTypedValueAsNumeric(const TypedValue &value) { |
| switch (value.getTypeID()) { |
| case kInt: |
| return value.getLiteral<int>(); |
| case kLong: |
| return value.getLiteral<std::int64_t>(); |
| case kFloat: |
| return value.getLiteral<float>(); |
| case kDouble: |
| return value.getLiteral<double>(); |
| default: |
| FATAL_ERROR("TypedValue does not appear to be numeric."); |
| } |
| } |
| |
| void checkNumericComparison(const Comparison &comparison) { |
| for (const std::pair<const TypedValue*, const Type*> &left_item : numeric_typed_values_) { |
| for (const std::pair<const TypedValue*, const Type*> &right_item : numeric_typed_values_) { |
| checkNumericComparisonChecked(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| checkNumericComparisonUnchecked(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| } |
| } |
| } |
| |
| void checkNumericComparisonChecked(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| return; |
| } |
| |
| const Type *expected_type = TypeFactory::GetUnifyingType(left_type, |
| right_type); |
| ASSERT_NE(expected_type, nullptr); |
| |
| switch (expected_type->getTypeID()) { |
| case kInt: |
| checkNumericComparisonCheckedHelper<int>(comparison, |
| left, left_type, |
| right, right_type); |
| break; |
| case kLong: |
| checkNumericComparisonCheckedHelper<int64_t>(comparison, |
| left, left_type, |
| right, right_type); |
| break; |
| case kFloat: |
| checkNumericComparisonCheckedHelper<float>(comparison, |
| left, left_type, |
| right, right_type); |
| break; |
| case kDouble: |
| checkNumericComparisonCheckedHelper<double>(comparison, |
| left, left_type, |
| right, right_type); |
| break; |
| default: |
| FATAL_ERROR("Unsupported result type for the comparison."); |
| } |
| } |
| |
| template <typename NumericType> |
| inline void checkNumericComparisonCheckedHelper(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| return; |
| } |
| |
| bool expected = checkNumericComparisonHelper<NumericType>(comparison, left, right); |
| EXPECT_EQ(expected, comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| } |
| |
| void checkNumericComparisonUnchecked(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| unique_ptr<UncheckedComparator> comparator( |
| comparison.makeUncheckedComparatorForTypes(left_type, |
| right_type)); |
| |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparator->compareTypedValues(left, right)); |
| EXPECT_FALSE(comparator->compareDataPtrs( |
| left.isNull() ? nullptr : left.getDataPtr(), |
| right.isNull() ? nullptr : right.getDataPtr())); |
| return; |
| } |
| |
| const Type *expected_type = TypeFactory::GetUnifyingType(left_type, |
| right_type); |
| ASSERT_NE(expected_type, nullptr); |
| |
| switch (expected_type->getTypeID()) { |
| case kInt: |
| checkNumericComparisonUncheckedHelper<int>(comparison, *comparator, |
| left, left_type, |
| right, right_type); |
| break; |
| case kLong: |
| checkNumericComparisonUncheckedHelper<int64_t>(comparison, *comparator, |
| left, left_type, |
| right, right_type); |
| break; |
| case kFloat: |
| checkNumericComparisonUncheckedHelper<float>(comparison, *comparator, |
| left, left_type, |
| right, right_type); |
| break; |
| case kDouble: |
| checkNumericComparisonUncheckedHelper<double>(comparison, *comparator, |
| left, left_type, |
| right, right_type); |
| break; |
| default: |
| FATAL_ERROR("Unsupported result types for the comparison."); |
| } |
| } |
| |
| template <typename NumericType> |
| inline void checkNumericComparisonUncheckedHelper(const Comparison &comparison, |
| const UncheckedComparator &comparator, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| bool expected = checkNumericComparisonHelper<NumericType>(comparison, left, right); |
| EXPECT_EQ(expected, comparator.compareTypedValues(left, right)); |
| EXPECT_EQ(expected, comparator.compareDataPtrs(left.getDataPtr(), right.getDataPtr())); |
| } |
| |
| template <typename NumericType> |
| inline bool checkNumericComparisonHelper(const Comparison &comparison, |
| const TypedValue &left, |
| const TypedValue &right) { |
| const NumericType left_num = GetTypedValueAsNumeric<NumericType>(left); |
| const NumericType right_num = GetTypedValueAsNumeric<NumericType>(right); |
| |
| switch (comparison.getComparisonID()) { |
| case ComparisonID::kEqual: |
| return left_num == right_num; |
| case ComparisonID::kNotEqual: |
| return left_num != right_num; |
| case ComparisonID::kLess: |
| return left_num < right_num; |
| case ComparisonID::kLessOrEqual: |
| return left_num <= right_num; |
| case ComparisonID::kGreater: |
| return left_num > right_num; |
| case ComparisonID::kGreaterOrEqual: |
| return left_num >= right_num; |
| default: |
| FATAL_ERROR("Unsupported comparison type."); |
| } |
| } |
| |
| void checkDateComparison(const Comparison &comparison) { |
| for (const std::pair<const TypedValue*, const Type*> &left_item : date_typed_values_) { |
| for (const std::pair<const TypedValue*, const Type*> &right_item : date_typed_values_) { |
| checkDateComparisonChecked<DateLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| checkDateComparisonUnchecked<DateLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| } |
| } |
| } |
| |
| void checkDatetimeComparison(const Comparison &comparison) { |
| for (const std::pair<const TypedValue*, const Type*> &left_item : datetime_typed_values_) { |
| for (const std::pair<const TypedValue*, const Type*> &right_item : datetime_typed_values_) { |
| checkDateComparisonChecked<DatetimeLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| checkDateComparisonUnchecked<DatetimeLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| } |
| } |
| } |
| |
| void checkDatetimeIntervalComparison(const Comparison &comparison) { |
| for (const std::pair<const TypedValue*, const Type*> &left_item |
| : datetime_interval_typed_values_) { |
| for (const std::pair<const TypedValue*, const Type*> &right_item |
| : datetime_interval_typed_values_) { |
| checkDateComparisonChecked<DatetimeIntervalLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| checkDateComparisonUnchecked<DatetimeIntervalLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| } |
| } |
| } |
| |
| void checkYearMonthIntervalComparison(const Comparison &comparison) { |
| for (const std::pair<const TypedValue*, const Type*> &left_item |
| : year_month_interval_typed_values_) { |
| for (const std::pair<const TypedValue*, const Type*> &right_item |
| : year_month_interval_typed_values_) { |
| checkDateComparisonChecked<YearMonthIntervalLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| checkDateComparisonUnchecked<YearMonthIntervalLit>(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| } |
| } |
| } |
| |
| template <typename DateType> |
| void checkDateComparisonChecked(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| return; |
| } |
| |
| bool expected = checkDateComparisonHelper<DateType>(comparison, left, right); |
| EXPECT_EQ(expected, comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| } |
| |
| template <typename DateType> |
| void checkDateComparisonUnchecked(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| unique_ptr<UncheckedComparator> comparator( |
| comparison.makeUncheckedComparatorForTypes(left_type, |
| right_type)); |
| |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparator->compareTypedValues(left, right)); |
| EXPECT_FALSE(comparator->compareDataPtrs( |
| left.isNull() ? nullptr : left.getDataPtr(), |
| right.isNull() ? nullptr : right.getDataPtr())); |
| return; |
| } |
| |
| bool expected = checkDateComparisonHelper<DateType>(comparison, left, right); |
| EXPECT_EQ(expected, comparator->compareTypedValues(left, right)); |
| EXPECT_EQ(expected, comparator->compareDataPtrs(left.getDataPtr(), right.getDataPtr())); |
| } |
| |
| template <typename DateType> |
| inline bool checkDateComparisonHelper(const Comparison &comparison, |
| const TypedValue &left, |
| const TypedValue &right) { |
| switch (comparison.getComparisonID()) { |
| case ComparisonID::kEqual: |
| return left.getLiteral<DateType>() == right.getLiteral<DateType>(); |
| case ComparisonID::kNotEqual: |
| return left.getLiteral<DateType>() != right.getLiteral<DateType>(); |
| case ComparisonID::kLess: |
| return left.getLiteral<DateType>() < right.getLiteral<DateType>(); |
| case ComparisonID::kLessOrEqual: |
| return left.getLiteral<DateType>() <= right.getLiteral<DateType>(); |
| case ComparisonID::kGreater: |
| return left.getLiteral<DateType>() > right.getLiteral<DateType>(); |
| case ComparisonID::kGreaterOrEqual: |
| return left.getLiteral<DateType>() >= right.getLiteral<DateType>(); |
| default: |
| FATAL_ERROR("Unsupported comparison type."); |
| } |
| } |
| |
| void checkStringComparison(const Comparison &comparison) { |
| for (const std::pair<const TypedValue*, const Type*> &left_item : string_typed_values_) { |
| for (const std::pair<const TypedValue*, const Type*> &right_item : string_typed_values_) { |
| checkStringComparisonChecked(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| checkStringComparisonUnchecked(comparison, |
| *left_item.first, *left_item.second, |
| *right_item.first, *right_item.second); |
| } |
| } |
| } |
| |
| void checkStringComparisonChecked(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| return; |
| } |
| |
| bool expected = checkStringComparisonHelper(comparison, left, right); |
| EXPECT_EQ(expected, comparison.compareTypedValuesChecked(left, left_type, |
| right, right_type)); |
| } |
| |
| void checkStringComparisonUnchecked(const Comparison &comparison, |
| const TypedValue &left, |
| const Type &left_type, |
| const TypedValue &right, |
| const Type &right_type) { |
| unique_ptr<UncheckedComparator> comparator( |
| comparison.makeUncheckedComparatorForTypes(left_type, |
| right_type)); |
| |
| if (left.isNull() || right.isNull()) { |
| EXPECT_FALSE(comparator->compareTypedValues(left, right)); |
| EXPECT_FALSE(comparator->compareDataPtrs( |
| left.isNull() ? nullptr : left.getDataPtr(), |
| right.isNull() ? nullptr : right.getDataPtr())); |
| return; |
| } |
| |
| bool expected = checkStringComparisonHelper(comparison, left, right); |
| EXPECT_EQ(expected, comparator->compareTypedValues(left, right)); |
| EXPECT_EQ(expected, comparator->compareDataPtrs(left.getDataPtr(), right.getDataPtr())); |
| } |
| |
| inline bool checkStringComparisonHelper(const Comparison &comparison, |
| const TypedValue &left, |
| const TypedValue &right) { |
| const std::size_t left_length = left.getAsciiStringLength(); |
| const std::size_t right_length = right.getAsciiStringLength(); |
| const int compare_result = |
| strncmp(static_cast<const char*>(left.getOutOfLineData()), |
| static_cast<const char*>(right.getOutOfLineData()), |
| min(left_length, right_length)); |
| |
| switch (comparison.getComparisonID()) { |
| case ComparisonID::kEqual: |
| return compare_result == 0 && left_length == right_length; |
| case ComparisonID::kNotEqual: |
| return !(compare_result == 0 && left_length == right_length); |
| case ComparisonID::kLess: |
| return compare_result < 0 || (compare_result == 0 && left_length < right_length); |
| case ComparisonID::kLessOrEqual: |
| return compare_result < 0 || (compare_result == 0 && left_length <= right_length); |
| case ComparisonID::kGreater: |
| return compare_result > 0 || (compare_result == 0 && left_length > right_length); |
| case ComparisonID::kGreaterOrEqual: |
| return compare_result > 0 || (compare_result == 0 && left_length >= right_length); |
| default: |
| FATAL_ERROR("Unsupported comparison type."); |
| } |
| } |
| |
| unique_ptr<TypedValue> |
| int_null_, int_zero_, int_positive_, int_negative_, int_max_, int_min_, |
| long_null_, long_zero_, long_positive_, long_negative_, long_max_, long_min_, |
| float_null_, float_zero_, float_positive_, float_negative_, float_max_, float_min_, |
| double_null_, double_zero_, double_positive_, double_negative_, double_max_, double_min_, |
| char_null_, char_ref_short_, char_lit_short_, char_ref_long_, char_lit_long_, |
| char_ref_null_terminated_short_, char_lit_null_terminated_short_, |
| char_ref_null_terminated_long_, char_lit_null_terminated_long_, |
| char_ref_extended_short_, char_lit_extended_short_, |
| char_ref_extended_long_, char_lit_extended_long_, |
| varchar_null_, varchar_ref_short_, varchar_lit_short_, varchar_ref_long_, varchar_lit_long_, |
| date_null_, date_positive_, date_negative_, date_max_, date_min_, |
| datetime_null_, datetime_zero_, datetime_positive_, datetime_negative_, datetime_max_, datetime_min_, |
| datetime_interval_null_, datetime_interval_zero_, datetime_interval_positive_, datetime_interval_negative_, |
| year_month_interval_null_, year_month_interval_zero_, |
| year_month_interval_positive_, year_month_interval_negative_; |
| |
| unique_ptr<ScopedBuffer> extended_short_char_buffer_, extended_long_char_buffer_; |
| |
| vector<pair<const TypedValue*, const Type*>> |
| numeric_typed_values_, date_typed_values_, datetime_typed_values_, datetime_interval_typed_values_, |
| year_month_interval_typed_values_, string_typed_values_; |
| }; |
| |
| TEST_F(ComparisonTest, ComparisonTests) { |
| checkComparison(ComparisonFactory::GetComparison(ComparisonID::kEqual)); |
| checkComparison(ComparisonFactory::GetComparison(ComparisonID::kNotEqual)); |
| checkComparison(ComparisonFactory::GetComparison(ComparisonID::kLess)); |
| checkComparison(ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual)); |
| checkComparison(ComparisonFactory::GetComparison(ComparisonID::kGreater)); |
| checkComparison(ComparisonFactory::GetComparison(ComparisonID::kGreaterOrEqual)); |
| } |
| |
| void CheckComparisonSerialization(const Comparison &comparison) { |
| serialization::Comparison proto = comparison.getProto(); |
| switch (comparison.getComparisonID()) { |
| case ComparisonID::kEqual: |
| EXPECT_EQ(serialization::Comparison::EQUAL, proto.comparison_id()); |
| break; |
| case ComparisonID::kNotEqual: |
| EXPECT_EQ(serialization::Comparison::NOT_EQUAL, proto.comparison_id()); |
| break; |
| case ComparisonID::kLess: |
| EXPECT_EQ(serialization::Comparison::LESS, proto.comparison_id()); |
| break; |
| case ComparisonID::kLessOrEqual: |
| EXPECT_EQ(serialization::Comparison::LESS_OR_EQUAL, proto.comparison_id()); |
| break; |
| case ComparisonID::kGreater: |
| EXPECT_EQ(serialization::Comparison::GREATER, proto.comparison_id()); |
| break; |
| case ComparisonID::kGreaterOrEqual: |
| EXPECT_EQ(serialization::Comparison::GREATER_OR_EQUAL, proto.comparison_id()); |
| break; |
| case ComparisonID::kLike: |
| EXPECT_EQ(serialization::Comparison::LIKE, proto.comparison_id()); |
| break; |
| case ComparisonID::kNotLike: |
| EXPECT_EQ(serialization::Comparison::NOT_LIKE, proto.comparison_id()); |
| break; |
| case ComparisonID::kRegexMatch: |
| EXPECT_EQ(serialization::Comparison::REGEX_MATCH, proto.comparison_id()); |
| break; |
| case ComparisonID::kNotRegexMatch: |
| EXPECT_EQ(serialization::Comparison::NOT_REGEX_MATCH, proto.comparison_id()); |
| break; |
| |
| default: |
| FATAL_ERROR("operation is an unknown Comparison in CheckComparisonSerialization"); |
| } |
| |
| EXPECT_TRUE(comparison.equals(ComparisonFactory::ReconstructFromProto(proto))); |
| } |
| |
| TEST_F(ComparisonTest, ComparisonProtoSerializationTest) { |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kEqual)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kNotEqual)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kLess)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kGreater)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kGreaterOrEqual)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kLike)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kNotLike)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kRegexMatch)); |
| CheckComparisonSerialization(ComparisonFactory::GetComparison(ComparisonID::kNotRegexMatch)); |
| } |
| |
| // The 6 basic comparisons all have the same applicability to types. This |
| // general-purpose function checks Comparison::canComparePartialTypes() for any |
| // of them. |
| void CheckBasicComparisonApplicableToPartialTypes(const Comparison &comparison) { |
| // Assume applicable when neither side of the comparison is known. |
| EXPECT_TRUE(comparison.canComparePartialTypes(nullptr, nullptr)); |
| |
| // If only one argument is known, any orderable Type is OK. |
| for (const TypeID type_id |
| : {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| &TypeFactory::GetType(type_id, false), nullptr)); |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| &TypeFactory::GetType(type_id, true), nullptr)); |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| nullptr, &TypeFactory::GetType(type_id, false))); |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| nullptr, &TypeFactory::GetType(type_id, true))); |
| } |
| |
| for (const TypeID string_type_id : {kChar, kVarChar}) { |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| &TypeFactory::GetType(string_type_id, 10, false), nullptr)); |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| &TypeFactory::GetType(string_type_id, 10, true), nullptr)); |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| nullptr, &TypeFactory::GetType(string_type_id, 10, false))); |
| EXPECT_TRUE(comparison.canComparePartialTypes( |
| nullptr, &TypeFactory::GetType(string_type_id, 10, true))); |
| } |
| |
| // If both types are known, expect the same thing as canCompareTypes(). |
| for (const TypeID first_type_id |
| : {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| const Type &first_type = TypeFactory::GetType(first_type_id, false); |
| const Type &first_type_nullable = TypeFactory::GetType(first_type_id, true); |
| |
| for (const TypeID second_type_id |
| : {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| const Type &second_type = TypeFactory::GetType(second_type_id, false); |
| const Type &second_type_nullable = TypeFactory::GetType(second_type_id, true); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type), |
| comparison.canComparePartialTypes(&first_type, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type, &second_type_nullable)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type_nullable)); |
| } |
| |
| for (const TypeID second_type_id : {kChar, kVarChar}) { |
| const Type &second_type = TypeFactory::GetType(second_type_id, 10, false); |
| const Type &second_type_nullable = TypeFactory::GetType(second_type_id, 10, true); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type), |
| comparison.canComparePartialTypes(&first_type, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type, &second_type_nullable)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type_nullable)); |
| } |
| } |
| |
| for (const TypeID first_type_id : {kChar, kVarChar}) { |
| const Type &first_type = TypeFactory::GetType(first_type_id, 10, false); |
| const Type &first_type_nullable = TypeFactory::GetType(first_type_id, 10, true); |
| |
| for (const TypeID second_type_id |
| : {kInt, kLong, kFloat, kDouble, kDate, kDatetime, kDatetimeInterval, kYearMonthInterval}) { |
| const Type &second_type = TypeFactory::GetType(second_type_id, false); |
| const Type &second_type_nullable = TypeFactory::GetType(second_type_id, true); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type), |
| comparison.canComparePartialTypes(&first_type, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type, &second_type_nullable)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type_nullable)); |
| } |
| |
| for (const TypeID second_type_id : {kChar, kVarChar}) { |
| const Type &second_type = TypeFactory::GetType(second_type_id, 10, false); |
| const Type &second_type_nullable = TypeFactory::GetType(second_type_id, 10, true); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type), |
| comparison.canComparePartialTypes(&first_type, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type, &second_type_nullable)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type)); |
| EXPECT_EQ(comparison.canCompareTypes(first_type_nullable, second_type_nullable), |
| comparison.canComparePartialTypes(&first_type_nullable, &second_type_nullable)); |
| } |
| } |
| } |
| |
| TEST_F(ComparisonTest, CanComparePartialTypesTest) { |
| CheckBasicComparisonApplicableToPartialTypes( |
| ComparisonFactory::GetComparison(ComparisonID::kEqual)); |
| CheckBasicComparisonApplicableToPartialTypes( |
| ComparisonFactory::GetComparison(ComparisonID::kNotEqual)); |
| CheckBasicComparisonApplicableToPartialTypes( |
| ComparisonFactory::GetComparison(ComparisonID::kLess)); |
| CheckBasicComparisonApplicableToPartialTypes( |
| ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual)); |
| CheckBasicComparisonApplicableToPartialTypes( |
| ComparisonFactory::GetComparison(ComparisonID::kGreater)); |
| CheckBasicComparisonApplicableToPartialTypes( |
| ComparisonFactory::GetComparison(ComparisonID::kGreaterOrEqual)); |
| } |
| |
| TEST_F(ComparisonTest, PatternMatchingComparisonTest) { |
| const Comparison &like_comp = |
| ComparisonFactory::GetComparison(ComparisonID::kLike); |
| const Comparison ¬_like_comp = |
| ComparisonFactory::GetComparison(ComparisonID::kNotLike); |
| const Comparison ®ex_comp = |
| ComparisonFactory::GetComparison(ComparisonID::kRegexMatch); |
| const Comparison ¬_regex_comp = |
| ComparisonFactory::GetComparison(ComparisonID::kNotRegexMatch); |
| |
| // Check canCompareTypes method |
| for (const TypeID tid1 : {kChar, kVarChar}) { |
| const Type &t1 = TypeFactory::GetType(tid1, 10, false); |
| for (const TypeID tid2 : {kChar, kVarChar}) { |
| const Type &t2 = TypeFactory::GetType(tid2, 10, false); |
| EXPECT_TRUE(like_comp.canCompareTypes(t1, t2)); |
| EXPECT_TRUE(not_like_comp.canCompareTypes(t1, t2)); |
| EXPECT_TRUE(regex_comp.canCompareTypes(t1, t2)); |
| EXPECT_TRUE(not_regex_comp.canCompareTypes(t1, t2)); |
| } |
| } |
| |
| string text = "abc123\nXYZ\\n 127.0.0.1 @xxx.com"; |
| vector<string> matched_like_patterns = { |
| "%", |
| "abc%", |
| "%127.0.0.1%", |
| "%123_XYZ%", |
| "%\\% @%", |
| "abc%_%_3%" }; |
| vector<string> not_matched_like_patterns = { |
| "abc", |
| "%127__0.0.1%", |
| "abc%_%_2", |
| "%\\nXYZ%" }; |
| vector<string> matched_regex_patterns = { |
| "(.|\n)*", |
| "abc[^x]+xxx\\..*", |
| "(.|\n)*\\d+\\.\\d+\\.\\d+\\.\\d+.*", |
| "(.|\n)*[a-zA-Z]{3}.*" }; |
| vector<string> not_matched_regex_patterns = { |
| ".*", |
| ".*\\d{4}.*", |
| "(.|\n)*XYZ\n .*" }; |
| |
| for (const TypeID tid1 : {kChar, kVarChar}) { |
| const Type &t1 = TypeFactory::GetType(tid1, 32, false); |
| const TypedValue text_value(tid1, text.c_str(), text.size() + 1); |
| |
| for (const TypeID tid2 : {kChar, kVarChar}) { |
| const Type &t2 = TypeFactory::GetType(tid2, 32, false); |
| |
| for (const string &sp : matched_like_patterns) { |
| const TypedValue pattern_value(tid2, sp.c_str(), sp.size() + 1); |
| EXPECT_TRUE(like_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| EXPECT_FALSE(not_like_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| } |
| |
| for (const string &sp : not_matched_like_patterns) { |
| const TypedValue pattern_value(tid2, sp.c_str(), sp.size() + 1); |
| EXPECT_FALSE(like_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| EXPECT_TRUE(not_like_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| } |
| |
| for (const string &sp : matched_regex_patterns) { |
| const TypedValue pattern_value(tid2, sp.c_str(), sp.size() + 1); |
| EXPECT_TRUE(regex_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| EXPECT_FALSE(not_regex_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| } |
| |
| for (const string &sp : not_matched_regex_patterns) { |
| const TypedValue pattern_value(tid2, sp.c_str(), sp.size() + 1); |
| EXPECT_FALSE(regex_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| EXPECT_TRUE(not_regex_comp.compareTypedValuesChecked(text_value, t1, pattern_value, t2)); |
| } |
| } |
| } |
| } |
| |
| } // namespace quickstep |