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]