| 1370 | } |
| 1371 | |
| 1372 | std::vector<StructField> parseStructTypeInfo(const std::string& structTypeStr, |
| 1373 | main::ClientContext* context, std::string defType) { |
| 1374 | auto leftBracketPos = structTypeStr.find('('); |
| 1375 | auto rightBracketPos = structTypeStr.find_last_of(')'); |
| 1376 | if (leftBracketPos == std::string::npos || rightBracketPos == std::string::npos) { |
| 1377 | throw Exception("Cannot parse struct type: " + structTypeStr); |
| 1378 | } |
| 1379 | // Remove the leading and trailing brackets. |
| 1380 | auto structFieldsStr = |
| 1381 | structTypeStr.substr(leftBracketPos + 1, rightBracketPos - leftBracketPos - 1); |
| 1382 | std::vector<StructField> structFields; |
| 1383 | auto structFieldStrs = parseStructFields(structFieldsStr); |
| 1384 | auto numFields = structFieldStrs.size(); |
| 1385 | if (numFields > INVALID_STRUCT_FIELD_IDX + 1) { |
| 1386 | throw BinderException(std::format("Too many fields in {} definition (max {}, got {})", |
| 1387 | defType, INVALID_STRUCT_FIELD_IDX + 1, numFields)); |
| 1388 | } |
| 1389 | std::set<std::string> fieldNames; |
| 1390 | for (auto& structFieldStr : structFieldStrs) { |
| 1391 | auto pos = structFieldStr.find(' '); |
| 1392 | auto fieldName = structFieldStr.substr(0, pos); |
| 1393 | if (!fieldNames.insert(fieldName).second) { |
| 1394 | throw BinderException( |
| 1395 | std::format("Duplicate field '{}' in {} definition", fieldName, defType)); |
| 1396 | } |
| 1397 | auto fieldTypeString = structFieldStr.substr(pos + 1); |
| 1398 | LogicalType fieldType = LogicalType::convertFromString(fieldTypeString, context); |
| 1399 | structFields.emplace_back(fieldName, std::move(fieldType)); |
| 1400 | } |
| 1401 | return structFields; |
| 1402 | } |
| 1403 | |
| 1404 | LogicalType parseStructType(const std::string& trimmedStr, main::ClientContext* context) { |
| 1405 | return LogicalType::STRUCT(parseStructTypeInfo(trimmedStr, context, "STRUCT")); |
no test coverage detected