This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new d339a4d056 [lumina] Normalize distance metric to native name in index
metadata (#8676)
d339a4d056 is described below
commit d339a4d0560ba9ff7d784962a388402d29177e2c
Author: Eunbin Son <[email protected]>
AuthorDate: Thu Jul 16 14:17:09 2026 +0900
[lumina] Normalize distance metric to native name in index metadata (#8676)
---
.../lumina/index/LuminaVectorIndexOptions.java | 3 +++
.../lumina/index/LuminaVectorOptionsTest.java | 31 ++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git
a/paimon-lumina/src/main/java/org/apache/paimon/lumina/index/LuminaVectorIndexOptions.java
b/paimon-lumina/src/main/java/org/apache/paimon/lumina/index/LuminaVectorIndexOptions.java
index 3c067ef93b..a7e8facb18 100644
---
a/paimon-lumina/src/main/java/org/apache/paimon/lumina/index/LuminaVectorIndexOptions.java
+++
b/paimon-lumina/src/main/java/org/apache/paimon/lumina/index/LuminaVectorIndexOptions.java
@@ -125,6 +125,9 @@ public class LuminaVectorIndexOptions {
this.indexType = options.get(INDEX_TYPE);
validateEncodingMetricCombination(options.get(ENCODING_TYPE),
this.metric);
this.luminaOptions = buildLuminaOptions(options);
+ // Persist the canonical native metric name so
LuminaIndexMeta.metric() can read it
+ // back, regardless of whether the user configured "L2" (enum) or "l2"
(native).
+ this.luminaOptions.put(toLuminaKey(DISTANCE_METRIC),
metric.getLuminaName());
}
/**
diff --git
a/paimon-lumina/src/test/java/org/apache/paimon/lumina/index/LuminaVectorOptionsTest.java
b/paimon-lumina/src/test/java/org/apache/paimon/lumina/index/LuminaVectorOptionsTest.java
index 326b89fb9b..7403d41dd3 100644
---
a/paimon-lumina/src/test/java/org/apache/paimon/lumina/index/LuminaVectorOptionsTest.java
+++
b/paimon-lumina/src/test/java/org/apache/paimon/lumina/index/LuminaVectorOptionsTest.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
/** Tests for Lumina vector options. */
public class LuminaVectorOptionsTest {
@@ -117,6 +118,36 @@ public class LuminaVectorOptionsTest {
assertThat(meta.metric()).isEqualTo(LuminaVectorMetric.INNER_PRODUCT);
}
+ @Test
+ public void enumFormMetricIsNormalizedToNativeNameInMeta() {
+ // A user may configure the metric using the enum-form name (e.g.
"L2"), which
+ // parseMetric() accepts. The meta must persist the native name ("l2")
so that the read
+ // path LuminaIndexMeta.metric() -> fromLuminaName() can resolve it
without throwing.
+ Map<String, String> enumFormL2 = new HashMap<>();
+ enumFormL2.put("lumina.distance.metric", "L2");
+ enumFormL2.put("lumina.index.dimension", "128");
+
+ Map<String, String> l2Meta =
+ new
LuminaVectorIndexOptions(Options.fromMap(enumFormL2)).toLuminaOptions();
+ assertThat(l2Meta).containsEntry("distance.metric", "l2");
+ assertThatCode(() -> new
LuminaIndexMeta(l2Meta).metric()).doesNotThrowAnyException();
+ assertThat(new
LuminaIndexMeta(l2Meta).metric()).isEqualTo(LuminaVectorMetric.L2);
+
+ // Same normalization for another enum-form metric.
+ Map<String, String> enumFormIp = new HashMap<>();
+ enumFormIp.put("lumina.distance.metric", "INNER_PRODUCT");
+ enumFormIp.put("lumina.index.dimension", "128");
+ assertThat(new
LuminaVectorIndexOptions(Options.fromMap(enumFormIp)).toLuminaOptions())
+ .containsEntry("distance.metric", "inner_product");
+
+ // No regression: a native-form name stays as-is.
+ Map<String, String> nativeFormL2 = new HashMap<>();
+ nativeFormL2.put("lumina.distance.metric", "l2");
+ nativeFormL2.put("lumina.index.dimension", "128");
+ assertThat(new
LuminaVectorIndexOptions(Options.fromMap(nativeFormL2)).toLuminaOptions())
+ .containsEntry("distance.metric", "l2");
+ }
+
/** Builds the native lumina meta map (what gets serialized into the index
file) for a field. */
private static Map<String, String> metaFor(String fieldName, Map<String,
String> tableOptions) {
Options resolved =