| 703 | } |
| 704 | |
| 705 | static std::unique_ptr<ScalarFunction> bindCastToUnionFunction(const std::string& functionName, |
| 706 | const LogicalType& sourceType, const LogicalType& targetType) { |
| 707 | auto minCostTag = findUnionMinCostTag(sourceType, targetType); |
| 708 | const auto& innerType = common::UnionType::getFieldType(targetType, minCostTag); |
| 709 | CastToUnionBindData::inner_func_t innerFunc; |
| 710 | if (sourceType == innerType) { |
| 711 | innerFunc = [](ValueVector* inputVector, ValueVector& valVector, SelectionVector*, |
| 712 | uint64_t inputPos, uint64_t resultPos) { |
| 713 | valVector.copyFromVectorData(inputPos, inputVector, resultPos); |
| 714 | }; |
| 715 | } else { |
| 716 | std::shared_ptr<ScalarFunction> innerCast = |
| 717 | CastFunction::bindCastFunction("CAST", sourceType, innerType); |
| 718 | innerFunc = [innerCast](ValueVector* inputVector, ValueVector& valVector, |
| 719 | SelectionVector* selVector, uint64_t, uint64_t) { |
| 720 | // Can we just use inputPos / resultPos and not the entire sel vector? |
| 721 | auto input = std::shared_ptr<ValueVector>(inputVector, [](ValueVector*) {}); |
| 722 | innerCast->execFunc({input}, {selVector}, valVector, selVector, nullptr /* dataPtr */); |
| 723 | }; |
| 724 | } |
| 725 | auto castFunc = std::make_unique<ScalarFunction>(functionName, |
| 726 | std::vector<LogicalTypeID>{sourceType.getLogicalTypeID()}, targetType.getLogicalTypeID(), |
| 727 | ScalarFunction::UnaryCastExecFunction<void, void, CastToUnion, UnaryFunctionExecutor, |
| 728 | UnaryCastUnionFunctionWrapper>); |
| 729 | castFunc->bindFunc = [minCostTag, innerFunc, &targetType](const ScalarBindFuncInput&) { |
| 730 | return std::make_unique<CastToUnionBindData>(minCostTag, innerFunc, targetType.copy()); |
| 731 | }; |
| 732 | return castFunc; |
| 733 | } |
| 734 | |
| 735 | static std::unique_ptr<ScalarFunction> bindCastBetweenNested(const std::string& functionName, |
| 736 | const LogicalType& sourceType, const LogicalType& targetType) { |
no test coverage detected