Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix sql failed when using replace function #9524

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
84 changes: 80 additions & 4 deletions dbms/src/Functions/FunctionsStringReplace.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,19 @@ class FunctionStringReplace : public IFunction
auto needle = c1_const->getValue<String>();
auto replacement = c2_const->getValue<String>();

if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
bool col_const = column_src->isColumnConst();

if (col_const)
{
std::string result_value;
const auto * src_const = typeid_cast<const ColumnConst *>(column_src.get());
auto src = src_const->getValue<String>();
Impl::constant(src, needle, replacement, pos, occ, match_type, collator, result_value);
auto col_res = ColumnString::create();
col_res->insert(result_value);
column_result.column = std::move(col_res);
}
else if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
{
auto col_res = ColumnString::create();
Impl::vector(
Expand Down Expand Up @@ -232,7 +244,28 @@ class FunctionStringReplace : public IFunction
const auto * col_replacement_const = typeid_cast<const ColumnConst *>(column_replacement.get());
auto replacement = col_replacement_const->getValue<String>();

if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
bool col_const = column_src->isColumnConst();
EricZequan marked this conversation as resolved.
Show resolved Hide resolved

if (col_const)
{
auto new_src = column_src->convertToFullColumnIfConst();
EricZequan marked this conversation as resolved.
Show resolved Hide resolved
const auto * col = typeid_cast<const ColumnString *>(new_src.get());
auto col_res = ColumnString::create();
Impl::vectorNonConstNeedle(
col->getChars(),
col->getOffsets(),
col_needle->getChars(),
col_needle->getOffsets(),
replacement,
pos,
occ,
match_type,
collator,
col_res->getChars(),
col_res->getOffsets());
column_result.column = std::move(col_res);
}
else if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
{
auto col_res = ColumnString::create();
Impl::vectorNonConstNeedle(
Expand Down Expand Up @@ -292,7 +325,28 @@ class FunctionStringReplace : public IFunction
auto needle = col_needle_const->getValue<String>();
const auto * col_replacement = typeid_cast<const ColumnString *>(column_replacement.get());

if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
bool col_const = column_src->isColumnConst();

if (col_const)
{
auto new_src = column_src->convertToFullColumnIfConst();
const auto * col = typeid_cast<const ColumnString *>(new_src.get());
auto col_res = ColumnString::create();
Impl::vectorNonConstReplacement(
col->getChars(),
col->getOffsets(),
needle,
col_replacement->getChars(),
col_replacement->getOffsets(),
pos,
occ,
match_type,
collator,
col_res->getChars(),
col_res->getOffsets());
column_result.column = std::move(col_res);
}
else if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
{
auto col_res = ColumnString::create();
Impl::vectorNonConstReplacement(
Expand Down Expand Up @@ -351,7 +405,29 @@ class FunctionStringReplace : public IFunction
const auto * col_needle = typeid_cast<const ColumnString *>(column_needle.get());
const auto * col_replacement = typeid_cast<const ColumnString *>(column_replacement.get());

if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
bool col_const = column_src->isColumnConst();

if (col_const)
{
auto new_src = column_src->convertToFullColumnIfConst();
const auto * col = typeid_cast<const ColumnString *>(new_src.get());
auto col_res = ColumnString::create();
Impl::vectorNonConstNeedleReplacement(
col->getChars(),
col->getOffsets(),
col_needle->getChars(),
col_needle->getOffsets(),
col_replacement->getChars(),
col_replacement->getOffsets(),
pos,
occ,
match_type,
collator,
col_res->getChars(),
col_res->getOffsets());
column_result.column = std::move(col_res);
}
else if (const auto * col = checkAndGetColumn<ColumnString>(column_src.get()))
{
auto col_res = ColumnString::create();
Impl::vectorNonConstNeedleReplacement(
Expand Down
32 changes: 32 additions & 0 deletions dbms/src/Functions/tests/gtest_strings_replace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,38 @@ try
toVec({" hello ", " h e llo", "hello ", " ", "hello, world"}),
toVec({" ", "h", "", "h", ","}),
toVec({"", "x", "xx", " ", ","})));

/// const src replacement
ASSERT_COLUMN_EQ(
toVec({"Good Night", "Bad Afternoon", "Good Afterwhile"}),
executeFunction(
"replaceAll",
toConst({"Good Afternoon"}),
toVec({"Afternoon", "Good", "noon"}),
toVec({"Night", "Bad", "while"})));

/// const src and needle replacement
ASSERT_COLUMN_EQ(
toVec({"Good Night", "Good Bad", "Good while"}),
executeFunction(
"replaceAll",
toConst({"Good Afternoon"}),
toConst({"Afternoon"}),
toVec({"Night", "Bad", "while"})));

/// const src and replace replacement
ASSERT_COLUMN_EQ(
toVec({"Good Night", "Night Afternoon", "Good AfterNight"}),
executeFunction(
"replaceAll",
toConst({"Good Afternoon"}),
toVec({"Afternoon", "Good", "noon"}),
toConst({"Night"})));

/// const src and replace replacement
ASSERT_COLUMN_EQ(
toVec({"Good Night"}),
executeFunction("replaceAll", toConst({"Good Afternoon"}), toConst({"Afternoon"}), toConst({"Night"})));
}
CATCH

Expand Down