// 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 #include #include #include #include #include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-compare" #include #pragma GCC diagnostic pop namespace DB { namespace tests { class StringTrim : public DB::tests::FunctionTest { }; TEST_F(StringTrim, stringTrimStringUnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); std::vector strs{" hello ", " h e llo", "hello ", " ", "hello, world"}; MutableColumnPtr csp = ColumnString::create(); for (const auto & str : strs) { csp->insert(Field(str.c_str(), str.size())); } Block test_block; ColumnWithTypeAndName ctn = ColumnWithTypeAndName(std::move(csp), std::make_shared(), "test_trim"); ColumnsWithTypeAndName ctns{ctn}; test_block.insert(ctn); // for result from trim, ltrim and rtrim test_block.insert({}); test_block.insert({}); test_block.insert({}); ColumnNumbers cns{0}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); const IColumn * res = test_block.getByPosition(1).column.get(); const ColumnString * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"hello", "h e llo", "hello", "", "hello, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {"hello ", "h e llo", "hello ", "", "hello, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 3); res = test_block.getByPosition(3).column.get(); c0_string = checkAndGetColumn(res); results = {" hello", " h e llo", "hello", "", "hello, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, stringTrimConstUnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); MutableColumnPtr cp = ColumnString::create(); cp->insert(Field(" hello ", 10)); ColumnPtr csp = ColumnConst::create(cp->getPtr(), 5); Block test_block; auto type = std::make_shared(); ColumnWithTypeAndName ctn = ColumnWithTypeAndName(csp, type, "test_trim_const"); ColumnsWithTypeAndName ctns{ctn}; test_block.insert(ctn); // for result from trim, ltrim and rtrim test_block.insert({}); test_block.insert({}); test_block.insert({}); ColumnNumbers cns{0}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); const IColumn * res = test_block.getByPosition(1).column.get(); const ColumnConst * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"hello", "hello", "hello", "hello", "hello"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {"hello ", "hello ", "hello ", "hello ", "hello "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 3); res = test_block.getByPosition(3).column.get(); c0_string = checkAndGetColumn(res); results = { " hello", " hello", " hello", " hello", " hello", }; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, stringTrimwsConstUnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); MutableColumnPtr cp = ColumnString::create(); cp->insert(Field(" hello ", 10)); MutableColumnPtr excp = ColumnString::create(); excp->insert(Field(" he", 4)); ColumnPtr csp = ColumnConst::create(cp->getPtr(), 5); ColumnPtr excsp = ColumnConst::create(excp->getPtr(), 5); Block test_block; ColumnWithTypeAndName ctn = ColumnWithTypeAndName(csp, std::make_shared(), "test_trim_const"); ColumnWithTypeAndName exctn = ColumnWithTypeAndName(excsp, std::make_shared(), "test_ex_trim_const"); ColumnsWithTypeAndName ctns{ctn, exctn}; test_block.insert(ctn); test_block.insert(exctn); // for result from trim, ltrim and rtrim test_block.insert({}); test_block.insert({}); test_block.insert({}); ColumnNumbers cns{0, 1}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); const IColumn * res = test_block.getByPosition(2).column.get(); const ColumnConst * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"llo ", "llo ", "llo ", "llo ", "llo "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {"llo ", "llo ", "llo ", "llo ", "llo "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 3); res = test_block.getByPosition(3).column.get(); c0_string = checkAndGetColumn(res); results = { " hello ", " hello ", " hello ", " hello ", " hello ", }; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, stringTrimwsUtf8UnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); std::vector strs{" 你好 ", " 上海", "北京晨凯", " ", " 你好, world "}; String trim = " "; MutableColumnPtr csp = ColumnString::create(); for (const auto & str : strs) { csp->insert(Field(str.c_str(), str.size())); } MutableColumnPtr cp2 = ColumnString::create(); cp2->insert(Field(trim.c_str(), trim.size())); ColumnPtr excsp = ColumnConst::create(cp2->getPtr(), 5); Block test_block; ColumnWithTypeAndName ctn = ColumnWithTypeAndName(std::move(csp), std::make_shared(), "test_trim"); ColumnWithTypeAndName exctn = ColumnWithTypeAndName(excsp, std::make_shared(), "test_ex_trim"); ColumnsWithTypeAndName ctns{ctn, exctn}; test_block.insert(ctn); // for result from trim, ltrim and rtrim test_block.insert(exctn); test_block.insert({}); ColumnNumbers cns{0, 1}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); const IColumn * res = test_block.getByPosition(2).column.get(); const ColumnString * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"你好", "上海", "北京晨凯", "", "你好, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {"你好 ", "上海", "北京晨凯", "", "你好, world "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {" 你好", " 上海", "北京晨凯", "", " 你好, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, stringTrimwsConstUtf8UnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); String str = " 你好 "; String trim = " 你"; MutableColumnPtr cp = ColumnString::create(); cp->insert(Field(str.c_str(), str.size())); ColumnPtr csp = ColumnConst::create(cp->getPtr(), 5); MutableColumnPtr cp2 = ColumnString::create(); cp2->insert(Field(trim.c_str(), trim.size())); ColumnPtr excsp = ColumnConst::create(cp2->getPtr(), 5); Block test_block; ColumnWithTypeAndName ctn = ColumnWithTypeAndName(csp, std::make_shared(), "test_trim"); ColumnWithTypeAndName exctn = ColumnWithTypeAndName(excsp, std::make_shared(), "test_ex_trim"); ColumnsWithTypeAndName ctns{ctn, exctn}; test_block.insert(ctn); // for result from trim, ltrim and rtrim test_block.insert(exctn); test_block.insert({}); ColumnNumbers cns{0, 1}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); const IColumn * res = test_block.getByPosition(2).column.get(); const ColumnConst * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"好 ", "好 ", "好 ", "好 ", "好 "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {"好 ", "好 ", "好 ", "好 ", "好 "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 2); res = test_block.getByPosition(2).column.get(); c0_string = checkAndGetColumn(res); results = {" 你好 ", " 你好 ", " 你好 ", " 你好 ", " 你好 "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, stringTrimUtf8UnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); std::vector strs{" 你好 ", " 上海", "北京晨凯", " ", "你好, world"}; MutableColumnPtr csp = ColumnString::create(); for (const auto & str : strs) { csp->insert(Field(str.c_str(), str.size())); } Block test_block; ColumnWithTypeAndName ctn = ColumnWithTypeAndName(std::move(csp), std::make_shared(), "test_trim"); ColumnsWithTypeAndName ctns{ctn}; test_block.insert(ctn); // for result from trim, ltrim and rtrim test_block.insert({}); ColumnNumbers cns{0}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); const IColumn * res = test_block.getByPosition(1).column.get(); const ColumnString * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"你好", "上海", "北京晨凯", "", "你好, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); res = test_block.getByPosition(1).column.get(); c0_string = checkAndGetColumn(res); results = {"你好 ", "上海", "北京晨凯", "", "你好, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); res = test_block.getByPosition(1).column.get(); c0_string = checkAndGetColumn(res); results = {" 你好", " 上海", "北京晨凯", "", "你好, world"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, stringTrimConstUtf8UnitTest) { const auto context = TiFlashTestEnv::getContext(); auto & factory = FunctionFactory::instance(); String str = " 你好 "; MutableColumnPtr cp = ColumnString::create(); cp->insert(Field(str.c_str(), str.size())); ColumnPtr csp = ColumnConst::create(cp->getPtr(), 5); Block test_block; ColumnWithTypeAndName ctn = ColumnWithTypeAndName(csp, std::make_shared(), "test_trim"); ColumnsWithTypeAndName ctns{ctn}; test_block.insert(ctn); // for result from trim, ltrim and rtrim test_block.insert({}); ColumnNumbers cns{0}; // test trim auto bp = factory.tryGet("tidbTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); const IColumn * res = test_block.getByPosition(1).column.get(); const ColumnConst * c0_string = checkAndGetColumn(res); Field res_field; std::vector results{"你好", "你好", "你好", "你好", "你好"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test ltrim bp = factory.tryGet("tidbLTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); res = test_block.getByPosition(1).column.get(); c0_string = checkAndGetColumn(res); results = {"你好 ", "你好 ", "你好 ", "你好 ", "你好 "}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } // test rtrim bp = factory.tryGet("tidbRTrim", *context); ASSERT_TRUE(bp != nullptr); ASSERT_TRUE(bp->isVariadic()); bp->build(ctns)->execute(test_block, cns, 1); res = test_block.getByPosition(1).column.get(); c0_string = checkAndGetColumn(res); results = {" 你好", " 你好", " 你好", " 你好", " 你好"}; for (size_t t = 0; t < results.size(); t++) { c0_string->get(t, res_field); String s = res_field.get(); EXPECT_EQ(results[t], s); } } TEST_F(StringTrim, strTrimTest) try { // trim(const) ASSERT_COLUMN_EQ( createConstColumn(5, "x"), executeFunction("tidbTrim", createConstColumn>(5, " x "))); // trim(const from const) ASSERT_COLUMN_EQ( createConstColumn(5, "a"), executeFunction( "tidbTrim", createConstColumn>(5, "xax"), createConstColumn>(5, "x"))); // trim(leading|trailing|both const from const) ASSERT_COLUMN_EQ( createConstColumn(5, "a"), executeFunction( "tidbTrim", createConstColumn>(5, "xax"), createConstColumn>(5, "x"), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createConstColumn(5, "a"), executeFunction( "tidbTrim", createConstColumn>(5, "xax"), createConstColumn>(5, "x"), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createConstColumn(5, "ax"), executeFunction( "tidbTrim", createConstColumn>(5, "xax"), createConstColumn>(5, "x"), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createConstColumn(5, "xa"), executeFunction( "tidbTrim", createConstColumn>(5, "xax"), createConstColumn>(5, "x"), createConstColumn>(5, 3))); // trim(column) ASSERT_COLUMN_EQ( createColumn>({"xx aa", "xxaa xx", "\t aa \t", "", {}}), executeFunction("tidbTrim", createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}))); ASSERT_COLUMN_EQ( createColumn({"xx aa", "xxaa xx", "\t aa \t", "", {}}), executeFunction("tidbTrim", createColumn({" xx aa", " xxaa xx ", "\t aa \t", "", {}}))); // trim(column from column) ASSERT_COLUMN_EQ( createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), executeFunction( "tidbTrim", createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), createColumn>({"x", "x", "x", "x", "x"}))); ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"x", "x", "x", "x", "x"}))); ASSERT_COLUMN_EQ( createColumn>({"x aa", "aa xx ", "axxa \tx", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xxx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"xx", "xx", "xx", "xx", "xx"}))); ASSERT_COLUMN_EQ( createColumn>({" aa ", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", " x", " x", " x", " x"}))); ASSERT_COLUMN_EQ( createColumn>({" aa ", "aa xx ", "a \tx", "axx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", "x", "xx", "xxa", " x"}))); ASSERT_COLUMN_EQ( createColumn({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), executeFunction( "tidbTrim", createColumn({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), createColumn({"x", "x", "x", "x", "x"}))); ASSERT_COLUMN_EQ( createColumn({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn({"x", "x", "x", "x", "x"}))); ASSERT_COLUMN_EQ( createColumn({"x aa", "aa xx ", "axxa \tx", "aa", {}}), executeFunction( "tidbTrim", createColumn({"xxx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn({"xx", "xx", "xx", "xx", "xx"}))); ASSERT_COLUMN_EQ( createColumn({" aa ", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn({" x", " x", " x", " x", " x"}))); ASSERT_COLUMN_EQ( createColumn({" aa ", "aa xx ", "a \tx", "axx", {}}), executeFunction( "tidbTrim", createColumn({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn({" x", "x", "xx", "xxa", " x"}))); // trim(both|leading|trailing column from column) ASSERT_COLUMN_EQ( createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), executeFunction( "tidbTrim", createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), executeFunction( "tidbTrim", createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), executeFunction( "tidbTrim", createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), executeFunction( "tidbTrim", createColumn>({" xx aa", " xxaa xx ", "\t aa \t", "", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 3))); ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \txxx", "aaxx", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({"xx aa", "xxaa xx ", "axxa \t", "xxaa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"x", "x", "x", "x", "x"}), createConstColumn>(5, 3))); ASSERT_COLUMN_EQ( createColumn>({"x aa", "aa xx ", "axxa \tx", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xxx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"xx", "xx", "xx", "xx", "xx"}), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({"x aa", "aa xx ", "axxa \tx", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xxx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"xx", "xx", "xx", "xx", "xx"}), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({"x aa", "aa xx ", "axxa \txxx", "aaxx", {}}), executeFunction( "tidbTrim", createColumn>({"xxx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"xx", "xx", "xx", "xx", "xx"}), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({"xxx aa", "xxaa xx ", "axxa \tx", "xxaa", {}}), executeFunction( "tidbTrim", createColumn>({"xxx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createColumn>({"xx", "xx", "xx", "xx", "xx"}), createConstColumn>(5, 3))); ASSERT_COLUMN_EQ( createColumn>({" aa ", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", " x", " x", " x", " x"}), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({" aa ", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", " x", " x", " x", " x"}), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({" aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", " x", " x", " x", " x"}), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({" x x aa ", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", " x", " x", " x", " x"}), createConstColumn>(5, 3))); ASSERT_COLUMN_EQ( createColumn>({" aa ", "aa xx ", "a \tx", "axx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", "x", "xx", "xxa", " x"}), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({" aa ", "aa xx ", "a \tx", "axx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", "x", "xx", "xxa", " x"}), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({" aa x", "aa xx ", "a \txxx", "axx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", "x", "xx", "xxa", " x"}), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({" x x aa ", "xaa xx ", "xxa \tx", "xxaaxx", {}}), executeFunction( "tidbTrim", createColumn>({" x x aa x", "xaa xx ", "xxa \txxx", "xxaaxx", {}}), createColumn>({" x", "x", "xx", "xxa", " x"}), createConstColumn>(5, 3))); // trim(const from column) ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createConstColumn>(5, "x"))); // trim(column from const) ASSERT_COLUMN_EQ( createColumn>({"ax ", "ax x", "x x", "xxax", {}}), executeFunction( "tidbTrim", createConstColumn>(5, "xxax x"), createColumn>({"x", "xx", "xxa", " x", {}}))); // trim(both|leading|trailing const from column) ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createConstColumn>(5, "x"), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \t", "aa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createConstColumn>(5, "x"), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({" aa", "aa xx ", "axxa \txxx", "aaxx", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createConstColumn>(5, "x"), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({"xx aa", "xxaa xx ", "axxa \t", "xxaa", {}}), executeFunction( "tidbTrim", createColumn>({"xx aa", "xxaa xx ", "axxa \txxx", "xxaaxx", {}}), createConstColumn>(5, "x"), createConstColumn>(5, 3))); // trim(both|leading|trailing column from const) ASSERT_COLUMN_EQ( createColumn>({"ax ", "ax x", "x x", "xxax", {}}), executeFunction( "tidbTrim", createConstColumn>(5, "xxax x"), createColumn>({"x", "xx", "xxa", " x", {}}), createConstColumn>(5, 0))); ASSERT_COLUMN_EQ( createColumn>({"ax ", "ax x", "x x", "xxax", {}}), executeFunction( "tidbTrim", createConstColumn>(5, "xxax x"), createColumn>({"x", "xx", "xxa", " x", {}}), createConstColumn>(5, 1))); ASSERT_COLUMN_EQ( createColumn>({"ax x", "ax x", "x x", "xxax x", {}}), executeFunction( "tidbTrim", createConstColumn>(5, "xxax x"), createColumn>({"x", "xx", "xxa", " x", {}}), createConstColumn>(5, 2))); ASSERT_COLUMN_EQ( createColumn>({"xxax ", "xxax x", "xxax x", "xxax", {}}), executeFunction( "tidbTrim", createConstColumn>(5, "xxax x"), createColumn>({"x", "xx", "xxa", " x", {}}), createConstColumn>(5, 3))); //different trim policy for (int i = 0; i < 3; i++) { //test NULL and "" case ASSERT_COLUMN_EQ( createColumn>({"", "", "", {}, "", "", ""}), executeFunction( "tidbTrim", createColumn>({"", "", "", "", "", "", ""}), createColumn>({"", "x", "xx", {}, "啊", "\t", " "}), createConstColumn>(7, i))); ASSERT_COLUMN_EQ( createColumn>({{}, {}, {}, {}, {}, {}, {}}), executeFunction( "tidbTrim", createColumn>({{}, {}, {}, {}, {}, {}, {}}), createColumn>({"", "x", "xx", {}, "啊", "\t", " "}), createConstColumn>(7, i))); //test repeated pattern: ASCII & non-ASCII ASSERT_COLUMN_EQ( createColumn>({"", "x", "", "x", "", "x", {}}), executeFunction( "tidbTrim", createColumn>({"", "x", "xx", "xxx", "xxxx", "xxxxx", {}}), createColumn>({"xx", "xx", "xx", "xx", "xx", "xx", "xx"}), createConstColumn>(7, i))); ASSERT_COLUMN_EQ( createColumn>({"", "啊", "", "啊", "", "啊"}), executeFunction( "tidbTrim", createColumn>({"", "啊", "啊啊", "啊啊啊", "啊啊啊啊", "啊啊啊啊啊"}), createColumn>({"啊啊", "啊啊", "啊啊", "啊啊", "啊啊", "啊啊"}), createConstColumn>(6, i))); } //test non-ASCII cases InferredDataInitializerList> results_columns_ws_with_core_text[] = { {" 波 波 ", "啊 波 波 啊", " 波 波 ", "啊 波 波 啊", " 波 波 "}, //default(both) {" 波 波 ", "啊 波 波 啊", " 波 波 ", "啊 波 波 啊", " 波 波 "}, //both {" 波 波 ", "啊 波 波 啊", " 波 波 啊啊", "啊 波 波 啊啊啊", " 波 波 啊啊啊啊"}, //left {" 波 波 ", "啊 波 波 啊", "啊啊 波 波 ", "啊啊啊 波 波 啊", "啊啊啊啊 波 波 "} //right }; InferredDataInitializerList> input_columns_ws_with_core_text = {" 波 波 ", "啊 波 波 啊", "啊啊 波 波 啊啊", "啊啊啊 波 波 啊啊啊", "啊啊啊啊 波 波 啊啊啊啊"}; //different trim policy for (int i = 0; i < 3; i++) { //non-const ASSERT_COLUMN_EQ( createColumn>(results_columns_ws_with_core_text[i]), executeFunction( "tidbTrim", createColumn>(input_columns_ws_with_core_text), createColumn>({"啊啊", "啊啊", "啊啊", "啊啊", "啊啊", "啊啊"}), createConstColumn>(6, i))); //const for (size_t j = 0; j < results_columns_ws_with_core_text[i].size(); j++) { const auto * input_itr = input_columns_ws_with_core_text.begin(); size_t cnt = 0; for (const auto * res_itr = results_columns_ws_with_core_text[i].begin(); res_itr != results_columns_ws_with_core_text[i].end() && input_itr != input_columns_ws_with_core_text.end(); res_itr++, input_itr++) { ASSERT_COLUMN_EQ( input_itr->has_value() ? createConstColumn(5, res_itr->value()) : createConstColumn>(5, *res_itr), executeFunction( "tidbTrim", createConstColumn>(5, *input_itr), createConstColumn>(5, "啊啊"), createConstColumn>(5, i))); cnt++; } ASSERT_EQ(cnt, input_columns_ws_with_core_text.size()); ASSERT_EQ(cnt, results_columns_ws_with_core_text[i].size()); } } } CATCH } // namespace tests } // namespace DB