HAWQ-1775. refacte bpchar implementation and test
diff --git a/depends/dbcommon/src/dbcommon/function/func.cc b/depends/dbcommon/src/dbcommon/function/func.cc
index 36bddd6..d7afa4e 100644
--- a/depends/dbcommon/src/dbcommon/function/func.cc
+++ b/depends/dbcommon/src/dbcommon/function/func.cc
@@ -372,7 +372,7 @@
FuncEntryArray.push_back({STRING_BTRIM_CHARS, "string_btrim_chars", STRINGID, {STRINGID, STRINGID}, string_btrim_chars});
FuncEntryArray.push_back({STRING_REPEAT, "string_repeat", STRINGID, {STRINGID, INTID}, string_repeat, false});
FuncEntryArray.push_back({STRING_CHR, "string_chr", STRINGID, {INTID}, string_chr, false});
- FuncEntryArray.push_back({STRING_BPCHAR, "string_bpchar", STRINGID, {STRINGID, INTID, BOOLEANID}, string_bpchar, false});
+ FuncEntryArray.push_back({STRING_BPCHAR, "string_bpchar", CHARID, {CHARID, INTID, BOOLEANID}, string_bpchar, false});
FuncEntryArray.push_back({STRING_LPAD, "string_lpad", STRINGID, {STRINGID, INTID, STRINGID}, string_lpad, false});
FuncEntryArray.push_back({STRING_RPAD, "string_rpad", STRINGID, {STRINGID, INTID, STRINGID}, string_rpad, false});
FuncEntryArray.push_back({STRING_LPAD_NOFILL, "string_lpad_nofill", STRINGID, {STRINGID, INTID}, string_lpad_nofill, false});
diff --git a/depends/dbcommon/src/dbcommon/function/string-function.cc b/depends/dbcommon/src/dbcommon/function/string-function.cc
index dbf11c6..edda95f 100644
--- a/depends/dbcommon/src/dbcommon/function/string-function.cc
+++ b/depends/dbcommon/src/dbcommon/function/string-function.cc
@@ -27,6 +27,22 @@
namespace dbcommon {
+inline void bpcharTrim(Datum *params, uint64_t size) {
+ for (uint64_t i = 1; i < size; i++) {
+ Object *para = DatumGetValue<Object *>(params[i]);
+ if (dynamic_cast<Scalar *>(para)) {
+ Scalar *temp = params[i];
+ if (temp->isnull) continue;
+
+ char *str = temp->value;
+ int32_t lenth = temp->length;
+ while (--lenth >= 0)
+ if (str[lenth] != ' ') break;
+ temp->length = lenth + 1;
+ }
+ }
+}
+
template <bool expetedMatch>
Datum string_like_proto(Datum *params, uint64_t size) {
assert(size == 3);
@@ -425,6 +441,7 @@
}
Datum bpchar_char_length(Datum *params, uint64_t size) {
+ bpcharTrim(params, size);
return string_char_length(params, size);
}
diff --git a/depends/dbcommon/test/unit/function/test-string-function.cc b/depends/dbcommon/test/unit/function/test-string-function.cc
index f374a21..861f2f8 100644
--- a/depends/dbcommon/test/unit/function/test-string-function.cc
+++ b/depends/dbcommon/test/unit/function/test-string-function.cc
@@ -19,13 +19,12 @@
#include <iostream>
-#include "gtest/gtest.h"
-
#include "dbcommon/function/string-binary-function.h"
#include "dbcommon/log/debug-logger.h"
#include "dbcommon/testutil/function-utils.h"
#include "dbcommon/testutil/scalar-utils.h"
#include "dbcommon/testutil/vector-utils.h"
+#include "gtest/gtest.h"
namespace dbcommon {
@@ -48,6 +47,25 @@
}
}
+TEST(TestFunction, bpchar_char_length) {
+ FunctionUtility fu(FuncKind::BPCHAR_CHAR_LENGTH);
+ auto ret = fu.generatePara<0, Vector>("NULL");
+
+ auto expect = fu.generatePara<0, Vector>("3 8 5 NULL 3 2 4");
+ auto strs =
+ fu.generatePara<1, Vector>("cat black的今天 sheep NULL fry is good");
+ std::vector<Datum> params{ret, strs};
+ fu.test(params.data(), params.size(), expect);
+
+ {
+ auto expect = fu.generatePara<0, Vector>("10 7 8 0");
+ auto strs =
+ fu.generatePara<1, Vector>("i am a stu, nic to,meet you, ", ',');
+ std::vector<Datum> params{ret, strs};
+ fu.test(params.data(), params.size(), expect);
+ }
+}
+
TEST(TestFunction, string_octet_length) {
FunctionUtility fu(FuncKind::STRING_OCTET_LENGTH);
auto ret = fu.generatePara<0, Vector>("NULL");
@@ -58,6 +76,16 @@
fu.test(params.data(), params.size(), expect);
}
+TEST(TestFunction, bpchar_octet_length) {
+ FunctionUtility fu(FuncKind::BPCHAR_OCTET_LENGTH);
+ auto ret = fu.generatePara<0, Vector>("NULL");
+
+ auto expect = fu.generatePara<0, Vector>("23 23 23 NULL 23 23 23");
+ auto strs = fu.generatePara<1, Vector>("cat black sheep NULL fry is good");
+ std::vector<Datum> params{ret, strs};
+ fu.test(params.data(), params.size(), expect);
+}
+
TEST(TestFunction, string_like) {
FunctionUtility fu(FuncKind::STRING_LIKE);
SelectList ret;
@@ -67,7 +95,30 @@
{
LOG_TESTING("non-ANSI pattern");
+ SelectList expect{7, 9};
+ auto pattern = fu.generatePara<2, Scalar>("_ee%");
+ std::vector<Datum> params{CreateDatum(&ret), strs, pattern};
+ fu.test(params.data(), params.size(), CreateDatum(&expect));
+ }
+ {
+ LOG_TESTING("ANSI pattern");
+ SelectList expect{4, 7};
+ auto pattern = fu.generatePara<2, Scalar>("%r%");
+ std::vector<Datum> params{CreateDatum(&ret), strs, pattern};
+ fu.test(params.data(), params.size(), CreateDatum(&expect));
+ }
+}
+
+TEST(TestFunction, bpchar_like) {
+ FunctionUtility fu(FuncKind::BPCHAR_LIKE);
+ SelectList ret;
+
+ auto strs = fu.generatePara<1, Vector>(
+ "cat NULL sheep NULL fry is good peer flee 你ee");
+
+ {
+ LOG_TESTING("non-ANSI pattern");
SelectList expect{7, 9};
auto pattern = fu.generatePara<2, Scalar>("_ee%");
std::vector<Datum> params{CreateDatum(&ret), strs, pattern};
@@ -108,6 +159,30 @@
}
}
+TEST(TestFunction, bpchar_not_like) {
+ FunctionUtility fu(FuncKind::BPCHAR_NOT_LIKE);
+ SelectList ret;
+
+ auto strs = fu.generatePara<1, Vector>(
+ "cat NULL sheep NULL fry is good peer flee 你ee try");
+
+ {
+ LOG_TESTING("non-ANSI pattern");
+ auto pattern = fu.generatePara<2, Scalar>("_ry ");
+ SelectList expect{0, 2, 5, 6, 7, 8, 9};
+ std::vector<Datum> params{CreateDatum(&ret), strs, pattern};
+ fu.test(params.data(), params.size(), CreateDatum(&expect));
+ }
+
+ {
+ LOG_TESTING("ANSI pattern");
+ auto pattern = fu.generatePara<2, Scalar>("%ee%");
+ SelectList expect{0, 4, 5, 6, 10};
+ std::vector<Datum> params{CreateDatum(&ret), strs, pattern};
+ fu.test(params.data(), params.size(), CreateDatum(&expect));
+ }
+}
+
TEST(TestFunction, string_substring_nolen) {
FunctionUtility fu(FuncKind::STRING_SUBSTRING_NOLEN);
auto ret = fu.generatePara<0, Vector>("NULL");
@@ -539,6 +614,17 @@
}
{
+ LOG_TESTING("Vector in Vector with KMP input");
+ auto lhs = vuString.generateVector("abcdeabcdeabcdeabcdeabcdeabcde");
+ auto rhs = vuString.generateVector("xabcdeabcdeabcdeabcdeabcdeabcde");
+ auto position = vuInteger.generateVector("2");
+
+ std::vector<Datum> params{CreateDatum(ret.get()), CreateDatum(rhs.get()),
+ CreateDatum(lhs.get())};
+ fu.test(params.data(), params.size(), CreateDatum(position.get()));
+ }
+
+ {
LOG_TESTING("Vector in Vector with normal input");
auto lhs = vuString.generateVector("一2三,,ab西,六六六,我 2,三四", ',');
auto rhs = vuString.generateVector(
@@ -1335,10 +1421,14 @@
INSTANTIATE_TEST_CASE_P(
string_bpchar, TestFunction,
::testing::Values(
+ TestFunctionEntry{
+ FuncKind::STRING_BPCHAR,
+ "Vector: abcdefghijklmnopqrstuvw",
+ {"Vector: abcdefghijklmnopqrstuvwxyz", "Vector: 27", "Vector: t"}},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
"Vector{delimiter=,}: a ,ab,NULL",
- {"Vector{delimiter=,}: a,ab ,NULL", "Vector: 6 6 6",
- "Vector: t t t"}},
+ {"Vector{delimiter=,}: a,ab ,NULL",
+ "Vector: 27 27 27", "Vector: t t t"}},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
"Error",
{"Vector: abc", "Vector: 6", "Vector: f"},
@@ -1346,11 +1436,11 @@
TestFunctionEntry{FuncKind::STRING_BPCHAR,
"Vector{delimiter=,}: 中 ,中国,a中国,NULL",
{"Vector{delimiter=,}: 中,中国 ,a中国B,NULL",
- "Vector: 6 6 7 6", "Vector: t t t t"}},
- TestFunctionEntry{
- FuncKind::STRING_BPCHAR,
- "Vector{delimiter=,}: a ,ab,NULL",
- {"Vector{delimiter=,}: a,ab ,NULL", "Vector: 6 6 6", "Scalar: t"}},
+ "Vector: 27 27 27 27", "Vector: t t t t"}},
+ TestFunctionEntry{FuncKind::STRING_BPCHAR,
+ "Vector{delimiter=,}: a ,ab,NULL",
+ {"Vector{delimiter=,}: a,ab ,NULL",
+ "Vector: 27 27 27", "Scalar: t"}},
TestFunctionEntry{
FuncKind::STRING_BPCHAR,
"Vector: NULL NULL NULL",
@@ -1362,7 +1452,7 @@
TestFunctionEntry{
FuncKind::STRING_BPCHAR,
"Vector{delimiter=,}: a ,ab,NULL",
- {"Vector{delimiter=,}: a,ab ,NULL", "Scalar: 6", "Vector: t t t"}},
+ {"Vector{delimiter=,}: a,ab ,NULL", "Scalar: 27", "Vector: t t t"}},
TestFunctionEntry{
FuncKind::STRING_BPCHAR,
"Vector: NULL NULL NULL",
@@ -1374,7 +1464,7 @@
TestFunctionEntry{
FuncKind::STRING_BPCHAR,
"Vector{delimiter=,}: a ,ab,NULL",
- {"Vector{delimiter=,}: a,ab ,NULL", "Scalar: 6", "Scalar: t"}},
+ {"Vector{delimiter=,}: a,ab ,NULL", "Scalar: 27", "Scalar: t"}},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
"Vector: NULL NULL NULL",
{"Vector: a ab NULL", "Scalar: NULL", "Scalar: t"}},
@@ -1382,9 +1472,11 @@
"Error",
{"Vector: abc", "Scalar: 6", "Scalar: f"},
ERRCODE_STRING_DATA_RIGHT_TRUNCATION},
- TestFunctionEntry{FuncKind::STRING_BPCHAR,
- "Vector: ab abc NULL",
- {"Scalar: abc", "Vector: 6 7 8", "Vector: t t NULL"}},
+ TestFunctionEntry{
+ FuncKind::STRING_BPCHAR,
+ "Vector: abc abc NULL",
+ {"Scalar: abc", "Vector: 27 27 27", "Vector: t t NULL"}},
+
TestFunctionEntry{
FuncKind::STRING_BPCHAR,
"Vector: NULL NULL NULL",
@@ -1394,8 +1486,8 @@
{"Scalar: abc", "Vector: 6", "Vector: f"},
ERRCODE_STRING_DATA_RIGHT_TRUNCATION},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
- "Vector: ab abc NULL",
- {"Scalar: abc", "Vector: 6 7 NULL", "Scalar: t"}},
+ "Vector: abc abc NULL",
+ {"Scalar: abc", "Vector: 27 27 NULL", "Scalar: t"}},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
"Vector: NULL NULL NULL",
{"Scalar: abc", "Vector: 6 7 NULL", "Scalar: NULL"}},
@@ -1404,8 +1496,8 @@
{"Scalar: abc", "Vector: 6", "Scalar: f"},
ERRCODE_STRING_DATA_RIGHT_TRUNCATION},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
- "Vector: ab ab NULL",
- {"Scalar: abc", "Scalar: 6", "Vector: t t NULL"}},
+ "Vector: abc abc NULL",
+ {"Scalar: abc", "Scalar: 27", "Vector: t t NULL"}},
TestFunctionEntry{FuncKind::STRING_BPCHAR,
"Vector: NULL NULL NULL",
{"Scalar: NULL", "Scalar: 6", "Vector: t t NULL"}},