zhuxiangyi commented on code in PR #8334:
URL: https://github.com/apache/paimon/pull/8334#discussion_r3795042909


##########
paimon-api/src/main/java/org/apache/paimon/types/RowType.java:
##########
@@ -333,6 +334,166 @@ public RowType project(String... names) {
         return project(Arrays.asList(names));
     }
 
+    /**
+     * Project this row type by a list of (possibly nested) dotted paths, e.g. 
{@code ["f0",
+     * "nest.a"]}. A path without a dot selects the whole top-level field 
(same as {@link
+     * #project(List)}); a dotted path selects only the addressed sub-field of 
a nested {@link
+     * RowType}, preserving field ids and nullability of every level. Fields 
are emitted in the
+     * order the paths are given (exactly like {@link #project(List)}), not in 
schema declaration
+     * order. This is used by data evolution to reconstruct the partial nested 
schema of a
+     * column-group file from its {@code writeCols}.
+     */
+    public RowType projectByPaths(List<String> paths) {
+        return projectTypeByPaths(this, paths);
+    }
+
+    private static RowType projectTypeByPaths(RowType type, List<String> 
paths) {
+        // group paths by their immediate child name, keeping the order in 
which the paths are
+        // given; a child appearing without a tail (or also with a tail) is 
selected as a whole
+        // field
+        Map<String, List<String>> childToSubPaths = new LinkedHashMap<>();
+        Set<String> wholeChildren = new HashSet<>();
+        Map<String, DataField> fieldByName = new LinkedHashMap<>();
+        for (DataField field : type.getFields()) {
+            fieldByName.put(field.name(), field);
+        }
+        for (String path : paths) {
+            int dot = path.indexOf('.');
+            // Prefer an exact field-name match so a column whose name itself 
contains a dot (and
+            // any
+            // plain top-level name) is selected whole; only split into 
head.tail for genuine nested
+            // sub-field paths that do not name a field directly. This keeps 
backward compatibility
+            // with the legacy exact-name project(List).
+            if (dot < 0 || fieldByName.containsKey(path)) {

Review Comment:
   Agreed — I confirmed the emitted path resolves to the wrong field id.
   This PR takes the "at minimum, reject" option: leafPaths now refuses a 
nested path whose fh a literal top-level name, and asks the user to rename one 
of the two. The read side isunchanged, so nothing on disk changes meaning.
   I haven't switched to the escaped/versioned encoding here, since that 
changes the persisted writeCols format. Happy to do it in a follow-up, or in 
this PR if you'd rather not merge without it.



-- 
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]

Reply via email to