| 786 | |
| 787 | template <StringFunctions::TrimPosition D, bool IS_IMPLICIT_WHITESPACE> |
| 788 | StringVal StringFunctions::DoTrimString(FunctionContext* ctx, |
| 789 | const StringVal& str, const StringVal& chars_to_trim) { |
| 790 | if (str.is_null) return StringVal::null(); |
| 791 | TrimContext* trim_ctx = reinterpret_cast<TrimContext*>( |
| 792 | ctx->GetFunctionState(FunctionContext::THREAD_LOCAL)); |
| 793 | |
| 794 | // When 'chars_to_trim' is not a constant, we need to reset TrimContext with new |
| 795 | // 'chars_to_trim'. |
| 796 | if (!IS_IMPLICIT_WHITESPACE && !ctx->IsArgConstant(1)) { |
| 797 | if (chars_to_trim.is_null) return str; |
| 798 | trim_ctx->Reset(chars_to_trim); |
| 799 | } |
| 800 | |
| 801 | // When dealing with UTF-8 characters in UTF-8 mode, use DoUtf8TrimString(). |
| 802 | if (trim_ctx->utf8_mode()) { |
| 803 | return DoUtf8TrimString<D>(str, *trim_ctx); |
| 804 | } |
| 805 | |
| 806 | // Otherwise, we continue to maintain the old behavior. |
| 807 | int32_t begin = 0; |
| 808 | int32_t end = str.len - 1; |
| 809 | // Find new starting position. |
| 810 | if constexpr (D == LEADING || D == BOTH) { |
| 811 | while (begin < str.len && trim_ctx->Contains(str.ptr[begin])) { |
| 812 | ++begin; |
| 813 | } |
| 814 | } |
| 815 | // Find new ending position. |
| 816 | if constexpr (D == TRAILING || D == BOTH) { |
| 817 | while (end >= begin && trim_ctx->Contains(str.ptr[end])) { |
| 818 | --end; |
| 819 | } |
| 820 | } |
| 821 | return StringVal(str.ptr + begin, end - begin + 1); |
| 822 | } |
| 823 | |
| 824 | template <StringFunctions::TrimPosition D> |
| 825 | StringVal StringFunctions::DoUtf8TrimString(const StringVal& str, |
nothing calls this directly
no test coverage detected