slachiewicz commented on code in PR #908:
URL: https://github.com/apache/incubator-xtable/pull/908#discussion_r4055088898


##########
xtable-core/src/test/java/org/apache/xtable/delta/TestDeltaHelper.java:
##########
@@ -169,8 +180,17 @@ public void createTable(SparkSession sparkSession, String 
tableName, String base
     }
     if (enableColumnMapping) {
       tableBuilder.property("delta.minReaderVersion", "2");
-      tableBuilder.property("delta.minWriterVersion", "5");
       tableBuilder.property("delta.columnMapping.mode", "name");
+      // Delta 3.x writes parquet field ids for the top level columns but 
assigns none to a map
+      // key, a map value or a list element. Iceberg reads a file that carries 
any id by id
+      // alone and ignores the name mapping, so those children become 
unresolvable.
+      // IcebergCompatV2 is what makes Delta assign and record them.
+      if (enableIcebergCompatV2) {
+        tableBuilder.property("delta.minWriterVersion", "7");

Review Comment:
   The ordering you describe is right, but the cause is in the Delta writer, 
not in what XTable links. Delta 2.4 strips `parquet.field.id` for name-mode 
tables (`DeltaColumnMapping.scala`, `case NameMapping` removes it), so those 
files carry no ids and Iceberg resolves them through the name mapping we set. 
Delta 3.0+ writes the id for every struct field ("Delta spec requires writer to 
always write field_id"), and only IcebergCompatV2 assigns and writes ids for 
list elements and map keys/values (`rewriteFieldIdsForIceberg`, 
`DeltaParquetWriteSupport`). Iceberg's `ReadConf` uses file ids as soon as any 
field has one and never falls back to the name mapping for the rest, so a map 
or list column without IcebergCompatV2 is unresolvable.
   
   XTable does not write the source table's parquet files, so a name-mode table 
with map/list columns written by any Delta 3.x engine produces exactly this 
unreadable Iceberg table on main today; the bump only makes our test harness 
write files the way production writers have since Delta 3.0. Writer version 5 
vs 7 is not the lever: 5 is what column mapping needs, 7 is what any table 
feature (IcebergCompatV2 included) needs, and what decides readability is 
whether the files carry nested ids. There is no reader-side fix in Iceberg 
1.9.2 (name mapping is only applied when the file has no ids at all).
   
   I'd keep the helper on IcebergCompatV2 for the readable path, keep 
`testColumnMappingWithoutIcebergCompatIsNotReadableAsIceberg` pinning the other 
one, and decide in #911 whether the source should warn or refuse such tables; a 
hard fail would also hit tables written by Delta 2.x, which still convert fine.



##########
xtable-core/src/test/java/org/apache/xtable/delta/TestDeltaSync.java:
##########
@@ -358,7 +358,7 @@ public void 
testTimestampPartitioning(PartitionTransformType transformType) thro
             .expr();
     org.apache.spark.sql.delta.DeltaLog deltaLog =
         org.apache.spark.sql.delta.DeltaLog.forTable(sparkSession, 
basePath.toString());
-    org.apache.spark.sql.delta.Snapshot snapshot = 
deltaLog.getSnapshotAtInit().snapshot();
+    org.apache.spark.sql.delta.Snapshot snapshot = deltaLog.snapshot();

Review Comment:
   Same `DeltaLog` instance (the cache key is the qualified log path) and 
`OptimisticTransaction.commit` runs `updateAfterCommit` on it, so `snapshot()` 
already reflected the sync here; `getSnapshotAtInit` was a fresh load from disk 
in 2.4 and has no 3.x counterpart. Switched to `deltaLog.update(false, 
Option.empty(), Option.empty())` since that is the documented way to get the 
latest snapshot and the cost is one log listing.



##########
xtable-core/src/test/java/org/apache/xtable/delta/ITDeltaConversionSource.java:
##########
@@ -984,10 +982,11 @@ public void 
reuseMetadataDisabledReconstructsSnapshotPerCommit() {
 
     ValidationTestHelper.validateTableChanges(allActiveFiles, allTableChanges);
     // With reuse disabled the pre-optimization behaviour is restored in full: 
one snapshot
-    // reconstruction per commit, and no second listing of the log for 
commit-file mtimes.
+    // reconstruction per commit. The absence of the extra mtime listing is no 
longer assertable
+    // here, because DeltaLog.getChanges itself delegates to getChangeLogFiles 
as of Delta 3.x,
+    // so the spy cannot tell that call apart from one this class makes.
     verify(spiedDeltaLog, times(commitsBacklog.getCommitsToProcess().size()))
-        .getSnapshotAt(anyLong(), any());
-    verify(spiedDeltaLog, never()).getChangeLogFiles(anyLong(), anyBoolean());
+        .getSnapshotAt(anyLong(), any(), any());

Review Comment:
   The count is stable: `getChanges(start, failOnDataLoss)` calls the two-arg 
`getChangeLogFiles` exactly once (`DeltaLog.scala:298` in 3.3.3), so `times(1)` 
pins the delegation and would still catch an extra listing from 
`DeltaIncrementalChangesState`.



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