| 196 | } |
| 197 | |
| 198 | StringVal StringFunctions::Lpad(FunctionContext* context, const StringVal& str, |
| 199 | const BigIntVal& len, const StringVal& pad) { |
| 200 | if (str.is_null || len.is_null || pad.is_null || len.val < 0) return StringVal::null(); |
| 201 | // Corner cases: Shrink the original string, or leave it alone. |
| 202 | // TODO: Hive seems to go into an infinite loop if pad.len == 0, |
| 203 | // so we should pay attention to Hive's future solution to be compatible. |
| 204 | if (len.val <= str.len || pad.len == 0) return StringVal(str.ptr, len.val); |
| 205 | if (len.val > StringVal::MAX_LENGTH) { |
| 206 | context->SetError(Substitute(ERROR_CHARACTER_LIMIT_EXCEEDED, |
| 207 | "lpad() result", |
| 208 | PrettyPrinter::Print(StringVal::MAX_LENGTH, TUnit::BYTES)).c_str()); |
| 209 | return StringVal::null(); |
| 210 | } |
| 211 | StringVal result(context, len.val); |
| 212 | if (UNLIKELY(result.is_null)) return StringVal::null(); |
| 213 | int padded_prefix_len = len.val - str.len; |
| 214 | int pad_index = 0; |
| 215 | int result_index = 0; |
| 216 | uint8_t* ptr = result.ptr; |
| 217 | |
| 218 | // Prepend chars of pad. |
| 219 | while (result_index < padded_prefix_len) { |
| 220 | ptr[result_index++] = pad.ptr[pad_index++]; |
| 221 | pad_index = pad_index % pad.len; |
| 222 | } |
| 223 | |
| 224 | // Append given string. |
| 225 | memcpy(ptr + result_index, str.ptr, str.len); |
| 226 | return result; |
| 227 | } |
| 228 | |
| 229 | StringVal StringFunctions::Rpad(FunctionContext* context, const StringVal& str, |
| 230 | const BigIntVal& len, const StringVal& pad) { |
nothing calls this directly
no test coverage detected