MCPcopy Create free account
hub / github.com/apache/impala / ConcatWs

Method ConcatWs

be/src/exprs/string-functions-ir.cc:1278–1336  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1276}
1277
1278StringVal StringFunctions::ConcatWs(FunctionContext* context, const StringVal& sep,
1279 int num_children, const StringVal* strs) {
1280 DCHECK_GE(num_children, 1);
1281 DCHECK(strs != nullptr);
1282 if (sep.is_null) return StringVal::null();
1283
1284 // Loop once to compute valid start index, final string size and valid string object
1285 // count.
1286 int32_t valid_num_children = 0;
1287 int32_t valid_start_index = -1;
1288 int64_t total_size = 0;
1289 for (int32_t i = 0; i < num_children; ++i) {
1290 if (strs[i].is_null) continue;
1291
1292 if (valid_start_index == -1) {
1293 valid_start_index = i;
1294 // Calculate the space required by first valid string object.
1295 total_size += strs[i].len;
1296 } else {
1297 // Calculate the space required by subsequent valid string object.
1298 total_size += sep.len + strs[i].len;
1299 }
1300 // Record the count of valid string object.
1301 valid_num_children++;
1302 }
1303
1304 if (total_size > StringVal::MAX_LENGTH) {
1305 context->SetError(Substitute(ERROR_CHARACTER_LIMIT_EXCEEDED,
1306 "Concatenated string length",
1307 PrettyPrinter::Print(StringVal::MAX_LENGTH, TUnit::BYTES)).c_str());
1308 return StringVal::null();
1309 }
1310
1311 // If all data are invalid, or data size is zero, return empty string.
1312 if (valid_start_index < 0 || total_size <= 0) {
1313 return StringVal();
1314 }
1315 DCHECK_GT(valid_num_children, 0);
1316
1317 // Pass through if there's only one argument.
1318 if (valid_num_children == 1) return strs[valid_start_index];
1319
1320 // Reserve space needed by final result.
1321 StringVal result(context, total_size);
1322 if (UNLIKELY(result.is_null)) return StringVal::null();
1323
1324 // Loop to append the data.
1325 uint8_t* ptr = result.ptr;
1326 Ubsan::MemCpy(ptr, strs[valid_start_index].ptr, strs[valid_start_index].len);
1327 ptr += strs[valid_start_index].len;
1328 for (int32_t i = valid_start_index + 1; i < num_children; ++i) {
1329 if (strs[i].is_null) continue;
1330 Ubsan::MemCpy(ptr, sep.ptr, sep.len);
1331 ptr += sep.len;
1332 Ubsan::MemCpy(ptr, strs[i].ptr, strs[i].len);
1333 ptr += strs[i].len;
1334 }
1335 return result;

Callers

nothing calls this directly

Calls 3

SubstituteFunction · 0.85
StringValClass · 0.85
SetErrorMethod · 0.45

Tested by

no test coverage detected