// Copyright 2023 PingCAP, Inc. // // 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 namespace DB { namespace tests { class Strcmp : public DB::tests::FunctionTest { }; TEST_F(Strcmp, Strcmp) try { // without collation { // column with column ASSERT_COLUMN_EQ( createColumn({-1, 1, 0, 0}), executeFunction( "strcmp", {createColumn({"a", "b", "a", ""}), createColumn({"b", "a", "a", ""})})); // column with nullable ASSERT_COLUMN_EQ( createColumn>({-1, 1, -1, std::nullopt, std::nullopt}), executeFunction( "strcmp", {createColumn>({"1", "123", "123", "123", std::nullopt}), createColumn>({"123", "1", "45", std::nullopt, "123"})})); // nullable with nullable ASSERT_COLUMN_EQ( createColumn>({-1, 1, 0, std::nullopt, std::nullopt}), executeFunction( "strcmp", {createColumn>({"", "123", "", "", std::nullopt}), createColumn>({"123", "", "", std::nullopt, ""})})); // column with constant ASSERT_COLUMN_EQ( createColumn>({-1, 0, 1, std::nullopt}), executeFunction( "strcmp", {createColumn>({"a", "b", "c", std::nullopt}), createConstColumn>(4, "b")})); // constant with column ASSERT_COLUMN_EQ( createColumn>({1, 0, -1, std::nullopt}), executeFunction( "strcmp", {createConstColumn>(4, "b"), createColumn>({"a", "b", "c", std::nullopt})})); // constant with constant ASSERT_COLUMN_EQ( createConstColumn(1, -1), executeFunction( "strcmp", {createConstColumn>(1, "a"), createConstColumn>(1, "b")})); // constant with nullable ASSERT_COLUMN_EQ( createColumn>({-1}), executeFunction("strcmp", {createColumn({"a"}), createColumn>({"b"})})); ASSERT_COLUMN_EQ( createColumn>({std::nullopt}), executeFunction("strcmp", {createColumn({"a"}), createColumn>({std::nullopt})})); } // with collation { // column with column ASSERT_COLUMN_EQ( createColumn({-1, 1, 0, 0}), executeFunction( "strcmp", {createColumn({"a", "b", "a", ""}), createColumn({"b", "a", "a", ""})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn({-1, 1, 0, 0}), executeFunction( "strcmp", {createColumn({"a", "b", "a", ""}), createColumn({"b", "a", "a", ""})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::BINARY))); ASSERT_COLUMN_EQ( createColumn({-1, 1, 0, 0}), executeFunction( "strcmp", {createColumn({"a", "b", "a", ""}), createColumn({"B", "A", "A", ""})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); // column with nullable ASSERT_COLUMN_EQ( createColumn>({-1, 1, -1, std::nullopt, std::nullopt}), executeFunction( "strcmp", {createColumn>({"1", "123", "123", "123", std::nullopt}), createColumn>({"123", "1", "45", std::nullopt, "123"})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); // nullable with nullable ASSERT_COLUMN_EQ( createColumn>({-1, 1, 0, std::nullopt, std::nullopt}), executeFunction( "strcmp", {createColumn>({"", "123", "", "", std::nullopt}), createColumn>({"123", "", "", std::nullopt, ""})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); // column with constant ASSERT_COLUMN_EQ( createColumn({-1}), executeFunction( "strcmp", {createColumn({"a"}), createConstColumn>(1, "b")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn({-1}), executeFunction( "strcmp", {createColumn({"A"}), createConstColumn>(1, "b")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn({-1}), executeFunction( "strcmp", {createColumn({"A"}), createConstColumn>(1, "B")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn({-1, 0, 1, 1}), executeFunction( "strcmp", {createColumn({"A", "B", "C", "D"}), createConstColumn>(4, "B")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); { std::string src(35, char(2)); std::string tar1 = src; std::string tar2 = tar1; std::string tar3 = tar1; tar2.back() = char(1); tar3.back() = char(3); ASSERT_COLUMN_EQ( createColumn({-1, 0, 1}), executeFunction( "strcmp", {createColumn({tar2, tar1, tar3}), createConstColumn>(3, src)}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::BINARY))); } // constant with column ASSERT_COLUMN_EQ( createColumn>({1, 0, -1, std::nullopt}), executeFunction( "strcmp", {createConstColumn>(4, "b"), createColumn>({"a", "b", "c", std::nullopt})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({1, 0, -1, std::nullopt}), executeFunction( "strcmp", {createConstColumn>(4, "B"), createColumn>({"a", "b", "c", std::nullopt})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({1, 0, -1, std::nullopt}), executeFunction( "strcmp", {createConstColumn>(4, "b"), createColumn>({"A", "B", "C", std::nullopt})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); // constant with constant ASSERT_COLUMN_EQ( createConstColumn(1, -1), executeFunction( "strcmp", {createConstColumn>(1, "a"), createConstColumn>(1, "b")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createConstColumn(1, -1), executeFunction( "strcmp", {createConstColumn>(1, "A"), createConstColumn>(1, "b")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createConstColumn(1, -1), executeFunction( "strcmp", {createConstColumn>(1, "a"), createConstColumn>(1, "B")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createConstColumn(1, -1), executeFunction( "strcmp", {createConstColumn>(1, "A"), createConstColumn>(1, "B")}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); // constant with nullable ASSERT_COLUMN_EQ( createColumn>({-1}), executeFunction( "strcmp", {createColumn({"a"}), createColumn>({"b"})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({-1}), executeFunction( "strcmp", {createColumn({"A"}), createColumn>({"b"})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({-1}), executeFunction( "strcmp", {createColumn({"a"}), createColumn>({"B"})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({-1}), executeFunction( "strcmp", {createColumn({"A"}), createColumn>({"B"})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({std::nullopt}), executeFunction( "strcmp", {createColumn({"a"}), createColumn>({std::nullopt})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); ASSERT_COLUMN_EQ( createColumn>({std::nullopt}), executeFunction( "strcmp", {createColumn({"A"}), createColumn>({std::nullopt})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI))); } } CATCH TEST_F(Strcmp, StrEq) try { const std::string equals_fn_name = "equals"; for (const auto col_id : { TiDB::ITiDBCollator::UTF8MB4_BIN, TiDB::ITiDBCollator::BINARY, }) { const auto * collator = TiDB::ITiDBCollator::getCollator(col_id); // with collation { // column : column ASSERT_COLUMN_EQ( createColumn({0, 0, 1, 1, 0}), executeFunction( equals_fn_name, {createColumn({"a", "b", "a", "", "00"}), createColumn({"b", "a", "a", "", "0"})}, collator)); // column : constant // constant : column { for (size_t size = 1; size < 35; ++size) { std::string a(size, '0'); std::string b(size, '0'); b.back() = '1'; ASSERT_COLUMN_EQ( createColumn({1, 0}), executeFunction( equals_fn_name, {createConstColumn(2, a), createColumn({a, b})}, collator)); ASSERT_COLUMN_EQ( createColumn({1, 0}), executeFunction( equals_fn_name, {createColumn({a, b}), createConstColumn(2, a)}, collator)); { auto c = a; a += " "; b += " "; c += " "; if (!collator->isBinary()) { ASSERT_COLUMN_EQ( createColumn({1, 0}), executeFunction( equals_fn_name, {createConstColumn(2, c), createColumn({a, b})}, collator)); ASSERT_COLUMN_EQ( createColumn({1, 0}), executeFunction( equals_fn_name, {createColumn({a, b}), createConstColumn(2, c)}, collator)); } else { ASSERT_COLUMN_EQ( createColumn({0, 0, 1}), executeFunction( equals_fn_name, {createConstColumn(3, c), createColumn({a, b, c})}, collator)); ASSERT_COLUMN_EQ( createColumn({0, 0, 1}), executeFunction( equals_fn_name, {createColumn({a, b, c}), createConstColumn(3, c)}, collator)); } } } } // column : nullable ASSERT_COLUMN_EQ( createColumn>({0, 0, 1, std::nullopt, std::nullopt}), executeFunction( equals_fn_name, {createColumn>({"1", "123", "45", "123", std::nullopt}), createColumn>({"123", "1", "45", std::nullopt, "123"})}, collator)); // column with constant ASSERT_COLUMN_EQ( createColumn>({0, 1, std::nullopt}), executeFunction( equals_fn_name, {createColumn>({"aa", "bb", std::nullopt}), createConstColumn>(3, "bb")}, collator)); // constant with column ASSERT_COLUMN_EQ( createColumn>({0, 1, std::nullopt}), executeFunction( equals_fn_name, {createConstColumn>(3, "bb"), createColumn>({"aa", "bb", std::nullopt})}, collator)); // constant with nullable ASSERT_COLUMN_EQ( createColumn>({0}), executeFunction( equals_fn_name, {createColumn({"a"}), createColumn>({"b"})}, collator)); ASSERT_COLUMN_EQ( createColumn>({std::nullopt}), executeFunction( equals_fn_name, {createColumn({"a"}), createColumn>({std::nullopt})}, collator)); } } { ASSERT_COLUMN_EQ( createColumn>({0, 1, std::nullopt}), executeFunction( equals_fn_name, {createConstColumn(3, ""), createColumn>({"123", "", std::nullopt})}, TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_BIN))); } } CATCH } // namespace tests } // namespace DB