github-actions[bot] commented on code in PR #65675:
URL: https://github.com/apache/doris/pull/65675#discussion_r3594352296


##########
be/src/format_v2/table_reader.cpp:
##########
@@ -144,13 +144,15 @@ const schema::external::TField* get_field_ptr(const 
schema::external::TFieldPtr&
 }
 
 bool external_field_matches_name(const schema::external::TField& field, const 
std::string& name) {
-    if (field.__isset.name && to_lower(field.name) == to_lower(name)) {
-        return true;
+    if (field.__isset.name_mapping) {

Review Comment:
   This predicate is also used to associate a projected slot with the current 
table schema, before any legacy-file matching occurs. A projected slot 
initially has only its current name, so `TField{name="b", id=2, 
name_mapping=[]}` (or alias-only `new_b -> old_b`) fails this lookup and 
`annotate_projected_column` never copies the field id, aliases, or 
mapping-present marker. An id-bearing file then selects `BY_FIELD_ID`, but the 
projected column has no id and is materialized as NULL; an alias-only no-id 
file likewise cannot find `old_b`. Associate the current schema by its current 
name/id first, apply strict aliases only when matching an id-less file, and 
propagate `has_name_mapping` recursively through `AccessPathParser`.



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/DorisTypeToIcebergType.java:
##########
@@ -73,7 +73,12 @@ public Type struct(StructType struct, List<Type> types) {
             Type type = types.get(i);
 
             int id = isRoot ? i : getNextId();
-            String fieldName = isRoot && !rootFieldNames.isEmpty() ? 
rootFieldNames.get(i) : field.getName();
+            // Top-level names come from rootFieldNames (#65094, 
case-preserved from the DDL columns);
+            // nested struct field names use the case-preserved originalName 
so a Doris-created/altered
+            // Iceberg table keeps cross-engine-faithful nested names. 
Internal tables are unaffected
+            // (only this Iceberg-scoped visitor reads getOriginalName()).
+            String fieldName = isRoot && !rootFieldNames.isEmpty()
+                    ? rootFieldNames.get(i) : field.getOriginalName();

Review Comment:
   `getOriginalName()` preserves names converted inside this visitor, but the 
supported complex-MODIFY append path passes the new child's own name outside 
it: `IcebergMetadataOps.applyStructChange` converts `newField.getType()` here 
and then calls `updateSchema.addColumn(path, newField.getName(), ...)`. Because 
catalog `StructField.getName()` is lowercase, `STRUCT<..., CamelName: ...>` is 
still committed as `camelname` (also below list/map). Pass `getOriginalName()` 
at that call and add an ALTER test that verifies the remote Iceberg schema 
spelling.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to