| 227 | } |
| 228 | |
| 229 | StringVal StringFunctions::Rpad(FunctionContext* context, const StringVal& str, |
| 230 | const BigIntVal& len, const StringVal& pad) { |
| 231 | if (str.is_null || len.is_null || pad.is_null || len.val < 0) return StringVal::null(); |
| 232 | // Corner cases: Shrink the original string, or leave it alone. |
| 233 | // TODO: Hive seems to go into an infinite loop if pad->len == 0, |
| 234 | // so we should pay attention to Hive's future solution to be compatible. |
| 235 | if (len.val <= str.len || pad.len == 0) { |
| 236 | return StringVal(str.ptr, len.val); |
| 237 | } |
| 238 | if (len.val > StringVal::MAX_LENGTH) { |
| 239 | context->SetError(Substitute(ERROR_CHARACTER_LIMIT_EXCEEDED, |
| 240 | "rpad() result", |
| 241 | PrettyPrinter::Print(StringVal::MAX_LENGTH, TUnit::BYTES)).c_str()); |
| 242 | return StringVal::null(); |
| 243 | } |
| 244 | |
| 245 | StringVal result(context, len.val); |
| 246 | if (UNLIKELY(result.is_null)) return StringVal::null(); |
| 247 | memcpy(result.ptr, str.ptr, str.len); |
| 248 | |
| 249 | // Append chars of pad until desired length |
| 250 | uint8_t* ptr = result.ptr; |
| 251 | int pad_index = 0; |
| 252 | int result_len = str.len; |
| 253 | while (result_len < len.val) { |
| 254 | ptr[result_len++] = pad.ptr[pad_index++]; |
| 255 | pad_index = pad_index % pad.len; |
| 256 | } |
| 257 | return result; |
| 258 | } |
| 259 | |
| 260 | IntVal StringFunctions::Length(FunctionContext* context, const StringVal& str) { |
| 261 | if (str.is_null) return IntVal::null(); |
nothing calls this directly
no test coverage detected