| 38 | static union_field_idx_t findUnionMinCostTag(const LogicalType&, const LogicalType&); |
| 39 | |
| 40 | static void resolveNestedVector(std::shared_ptr<ValueVector> inputVector, ValueVector* resultVector, |
| 41 | uint64_t numOfEntries, CastFunctionBindData* dataPtr) { |
| 42 | const auto* inputType = &inputVector->dataType; |
| 43 | const auto* resultType = &resultVector->dataType; |
| 44 | while (true) { |
| 45 | if ((inputType->getPhysicalType() == PhysicalTypeID::LIST || |
| 46 | inputType->getPhysicalType() == PhysicalTypeID::ARRAY) && |
| 47 | (resultType->getPhysicalType() == PhysicalTypeID::LIST || |
| 48 | resultType->getPhysicalType() == PhysicalTypeID::ARRAY)) { |
| 49 | // copy data and nullmask from input |
| 50 | memcpy(resultVector->getData(), inputVector->getData(), |
| 51 | numOfEntries * resultVector->getNumBytesPerValue()); |
| 52 | resultVector->setNullFromBits(inputVector->getNullMask().getData(), 0, 0, numOfEntries); |
| 53 | |
| 54 | numOfEntries = ListVector::getDataVectorSize(inputVector.get()); |
| 55 | ListVector::resizeDataVector(resultVector, numOfEntries); |
| 56 | |
| 57 | inputVector = ListVector::getSharedDataVector(inputVector.get()); |
| 58 | resultVector = ListVector::getDataVector(resultVector); |
| 59 | inputType = &inputVector->dataType; |
| 60 | resultType = &resultVector->dataType; |
| 61 | } else if ((inputType->getLogicalTypeID() == LogicalTypeID::STRUCT && |
| 62 | resultType->getLogicalTypeID() == LogicalTypeID::STRUCT) || |
| 63 | CastArrayHelper::isUnionSpecialCast(*inputType, *resultType)) { |
| 64 | // Check if struct type can be cast |
| 65 | auto errorMsg = std::format("Unsupported casting function from {} to {}.", |
| 66 | inputType->toString(), resultType->toString()); |
| 67 | // Check if two structs have the same number of fields |
| 68 | if (StructType::getNumFields(*inputType) != StructType::getNumFields(*resultType)) { |
| 69 | throw ConversionException{errorMsg}; |
| 70 | } |
| 71 | |
| 72 | // Check if two structs have the same field names |
| 73 | auto inputTypeNames = StructType::getFieldNames(*inputType); |
| 74 | auto resultTypeNames = StructType::getFieldNames(*resultType); |
| 75 | |
| 76 | for (auto i = 0u; i < inputTypeNames.size(); i++) { |
| 77 | if (StringUtils::caseInsensitiveEquals(inputTypeNames[i], resultTypeNames[i])) { |
| 78 | continue; |
| 79 | } |
| 80 | throw ConversionException{errorMsg}; |
| 81 | } |
| 82 | |
| 83 | // copy data and nullmask from input |
| 84 | memcpy(resultVector->getData(), inputVector->getData(), |
| 85 | numOfEntries * resultVector->getNumBytesPerValue()); |
| 86 | resultVector->setNullFromBits(inputVector->getNullMask().getData(), 0, 0, numOfEntries); |
| 87 | |
| 88 | auto inputFieldVectors = StructVector::getFieldVectors(inputVector.get()); |
| 89 | auto resultFieldVectors = StructVector::getFieldVectors(resultVector); |
| 90 | for (auto i = 0u; i < inputFieldVectors.size(); i++) { |
| 91 | resolveNestedVector(inputFieldVectors[i], resultFieldVectors[i].get(), numOfEntries, |
| 92 | dataPtr); |
| 93 | } |
| 94 | return; |
| 95 | } else if (resultType->getLogicalTypeID() == LogicalTypeID::UNION) { |
| 96 | if (inputType->getLogicalTypeID() == LogicalTypeID::UNION) { |
| 97 | auto numFieldsSrc = UnionType::getNumFields(*inputType); |
no test coverage detected