4747namespace paimon ::orc {
4848namespace {
4949
50+ bool IsStringTypeCompatible (const ::orc::Type* src_type, const ::orc::Type* target_type) {
51+ ::orc::TypeKind src_kind = src_type->getKind ();
52+ return (src_kind == ::orc::TypeKind::CHAR || src_kind == ::orc::TypeKind::VARCHAR ) &&
53+ target_type->getKind () == ::orc::TypeKind::STRING ;
54+ }
55+
56+ bool IsCompleteTypeCompatible (const ::orc::Type* src_type, const ::orc::Type* target_type) {
57+ ::orc::TypeKind src_kind = src_type->getKind ();
58+ ::orc::TypeKind target_kind = target_type->getKind ();
59+ if (IsStringTypeCompatible (src_type, target_type)) {
60+ return true ;
61+ }
62+ if (src_kind != target_kind || src_type->getSubtypeCount () != target_type->getSubtypeCount ()) {
63+ return false ;
64+ }
65+ if (src_type->getSubtypeCount () == 0 ) {
66+ return src_type->toString () == target_type->toString ();
67+ }
68+ for (uint64_t i = 0 ; i < src_type->getSubtypeCount (); i++) {
69+ if (src_kind == ::orc::TypeKind::STRUCT &&
70+ src_type->getFieldName (i) != target_type->getFieldName (i)) {
71+ return false ;
72+ }
73+ if (!IsCompleteTypeCompatible (src_type->getSubtype (i), target_type->getSubtype (i))) {
74+ return false ;
75+ }
76+ }
77+ return true ;
78+ }
79+
5080void CollectAllColumnIds (const ::orc::Type* type, std::vector<uint64_t >* column_ids) {
5181 column_ids->push_back (type->getColumnId ());
5282 for (uint64_t i = 0 ; i < type->getSubtypeCount (); ++i) {
@@ -208,7 +238,7 @@ Status OrcFileBatchReader::CollectTargetColumnIds(const ::orc::Type* src_type,
208238 std::vector<uint64_t >* target_column_ids) {
209239 auto src_kind = src_type->getKind ();
210240 auto target_kind = target_type->getKind ();
211- if (src_kind != target_kind) {
241+ if (src_kind != target_kind && ! IsStringTypeCompatible (src_type, target_type) ) {
212242 return Status::Invalid (fmt::format (" type kind mismatch: src {} vs target {}" ,
213243 src_type->toString (), target_type->toString ()));
214244 }
@@ -235,7 +265,7 @@ Status OrcFileBatchReader::CollectTargetColumnIds(const ::orc::Type* src_type,
235265 // Partial field recall inside list/map types is unsupported, so the target must match
236266 // the complete source subtree. Include the container and every descendant because all
237267 // of their streams are recalled by the ORC reader.
238- if (src_type-> toString () != target_type-> toString ( )) {
268+ if (! IsCompleteTypeCompatible (src_type, target_type)) {
239269 return Status::Invalid (fmt::format (" type mismatch: src {} vs target {}" ,
240270 src_type->toString (), target_type->toString ()));
241271 }
0 commit comments