Copilot commented on code in PR #12884:
URL: https://github.com/apache/gluten/pull/12884#discussion_r3882153241


##########
cpp/velox/compute/VeloxPlanConverter.cc:
##########
@@ -89,6 +92,14 @@ std::optional<std::string> unpackMetadataValue(const 
google::protobuf::Any& valu
   return std::nullopt;
 }
 
+std::optional<velox::dwio::common::ColumnMappingMode> 
parseColumnMappingMode(const google::protobuf::Any& value) {
+  auto unpacked = unpackMetadataValue(value);
+  if (!unpacked.has_value()) {
+    return std::nullopt;
+  }
+  return 
velox::dwio::common::ColumnMappingModeName::tryToColumnMappingMode(*unpacked);
+}

Review Comment:
   `LocalFilesNode` encodes `column_mapping_mode` using 
`google.protobuf.StringValue` (see updated JSON test data), but 
`unpackMetadataValue` never tries to unpack `StringValue`. This will make 
`parseColumnMappingMode` return `nullopt` and trip 
`VELOX_CHECK(mode.has_value(), ...)` for any split carrying the new metadata. 
Add `google::protobuf::StringValue` handling in `unpackMetadataValue` (or 
handle it directly in `parseColumnMappingMode`).



##########
gluten-delta/src-delta40/main/scala/org/apache/gluten/delta/DeltaDeletionVectorScanInfo.scala:
##########
@@ -108,6 +147,65 @@ object DeltaDeletionVectorScanInfo {
     PartitionFileScanInfo(normalizedMetadata, dvInfo)
   }
 
+  private def extract(
+      file: PartitionedFile,
+      hadoopConf: Configuration,
+      tablePath: Path,
+      addFile: AddFile): PartitionFileScanInfo = {
+    val metadata = otherMetadataColumns(file)
+    val normalizedMetadata = metadata -- Seq(RowIndexFilterIdEncoded, 
RowIndexFilterTypeKey)
+    val dvInfo = Option(addFile.deletionVector) match {
+      case Some(descriptor) =>
+        DeletionVectorInfo(
+          true,
+          IF_CONTAINED,
+          descriptor.cardinality,
+          serializePayload(hadoopConf, tablePath, descriptor))
+      case None =>
+        DeletionVectorInfo(false, KEEP_ALL, 0L, Array.emptyByteArray)
+    }
+    PartitionFileScanInfo(normalizedMetadata, dvInfo)
+  }
+
+  private def findAddFile(
+      file: PartitionedFile,
+      tablePath: Path,
+      addFiles: Seq[AddFile]): AddFile = {
+    val partitionedFilePath = new Path(file.filePath.toString)
+    addFiles
+      .find {
+        addFile =>
+          val addFilePath = 
DeltaFileOperations.absolutePath(tablePath.toString, addFile.path)
+          samePath(partitionedFilePath, addFilePath)
+      }
+      .getOrElse {
+        throw new IllegalStateException(
+          s"Unable to find Delta AddFile metadata for split ${file.filePath}")
+      }
+  }

Review Comment:
   `normalizeFromAddFiles` calls `findAddFile` for each `PartitionedFile`, and 
`findAddFile` does a linear scan over `addFiles`. For large scans this can 
become O(N*M). Consider pre-indexing `addFiles` once per call (e.g., Map keyed 
by a normalized absolute-path representation compatible with `samePath`) and 
then doing O(1) lookups per `PartitionedFile`.



##########
backends-velox/src-iceberg/test/scala/org/apache/gluten/execution/VeloxIcebergSuite.scala:
##########
@@ -27,6 +27,32 @@ import org.apache.iceberg.spark.source.SparkTable
 import org.apache.iceberg.types.{Type, Types}
 
 class VeloxIcebergSuite extends IcebergSuite {
+  test("iceberg parquet split uses name mapping for projected columns") {
+    withTable("iceberg_parquet_name_mapping") {
+      withSQLConf(VeloxConfig.PARQUET_USE_COLUMN_NAMES.key -> "false") {
+        spark.sql("""
+                    |CREATE TABLE iceberg_parquet_name_mapping (
+                    |  id BIGINT,
+                    |  amount DECIMAL(12, 2),
+                    |  note STRING
+                    |)
+                    |USING iceberg
+                    |TBLPROPERTIES ('write.format.default' = 'parquet')
+                    |""".stripMargin)
+        spark.sql("""
+                    |INSERT INTO iceberg_parquet_name_mapping
+                    |VALUES (CAST(1 AS BIGINT), CAST(10.50 AS DECIMAL(12, 2)), 
'a')
+                    |""".stripMargin)
+
+        runQueryAndCompare("SELECT amount FROM iceberg_parquet_name_mapping") {
+          df =>
+            checkAnswer(df, Seq(Row(BigDecimal("10.50"))))
+            checkGlutenPlan[IcebergScanTransformer](df)
+        }
+      }
+    }
+  }

Review Comment:
   This test name claims the split 'uses name mapping', but the assertions only 
validate the result and that an `IcebergScanTransformer` exists. Since 
projecting a single column can succeed under both position- and name-based 
matching, this may not catch regressions in the column-mapping-mode 
propagation. Consider making the test sensitive to the mapping mode (e.g., 
enforce a schema evolution/reorder scenario that would fail under position 
mapping, or assert the emitted split metadata contains the expected 
`__gluten.column_mapping_mode`).



##########
gluten-substrait/src/main/java/org/apache/gluten/substrait/rel/LocalFilesNode.java:
##########
@@ -55,10 +57,28 @@ public enum ReadFileFormat {
     UnknownFormat()
   }
 
+  public enum ColumnMappingMode {
+    POSITION("POSITION"),
+    NAME("NAME"),
+    PARQUET_FIELD_ID("PARQUET_FIELD_ID"),
+    FIELD_ID("FIELD_ID");
+

Review Comment:
   Adding both `PARQUET_FIELD_ID` and `FIELD_ID` introduces 
ambiguous/overlapping API surface for what appears to be the same concept. If 
both are required for compatibility, consider documenting which engines/files 
require which value; otherwise, prefer a single canonical enum value that 
matches the native Velox `ColumnMappingModeName` strings to avoid mismatches.



##########
ep/build-velox/src/get-velox.sh:
##########
@@ -17,9 +17,9 @@
 set -exu
 
 CURRENT_DIR=$(cd "$(dirname "$BASH_SOURCE")"; pwd)
-VELOX_REPO=https://github.com/IBM/velox.git
-VELOX_BRANCH=dft-2026_08_21
-VELOX_ENHANCED_BRANCH=ibm-2026_08_21
+VELOX_REPO=https://github.com/rui-mo/velox-dev.git
+VELOX_BRANCH=test
+VELOX_ENHANCED_BRANCH=test

Review Comment:
   The build script now pulls Velox from a personal fork and a non-versioned 
`test` branch, which breaks reproducibility and is risky for CI/release builds. 
Please revert to an official/upstream repo+pin (commit SHA or release branch), 
or make these overrideable via environment variables while keeping a stable, 
upstream default.



##########
gluten-ut/spark35/src/test/scala/org/apache/spark/sql/hive/execution/GlutenHiveSQLQuerySuite.scala:
##########
@@ -149,6 +149,48 @@ class GlutenHiveSQLQuerySuite extends 
GlutenHiveSQLQuerySuiteBase {
     }
   }
 
+  testGluten("ORC positional and Parquet name mapping can coexist in one Velox 
query") {
+    val hiveClient: HiveClient =
+      
spark.sharedState.externalCatalog.unwrapped.asInstanceOf[HiveExternalCatalog].client
+
+    withSQLConf(
+      "spark.sql.hive.convertMetastoreOrc" -> "false",
+      "spark.sql.hive.convertMetastoreParquet" -> "false",
+      "spark.hadoop.orc.force.positional.evolution" -> "true"

Review Comment:
   This test asserts 'ORC positional and Parquet name mapping can coexist', but 
it only explicitly forces ORC positional evolution and relies on Parquet's 
mapping default. To avoid future default/config drift making the test flaky, 
set the Parquet split mapping explicitly (e.g., the Velox Parquet mapping conf 
that drives name-vs-position on the Spark side) within `withSQLConf`.



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