This is an automated email from the ASF dual-hosted git repository.
Jackie-Jiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 7ecf65743e6 Harden schema case-collision validation with Locale.ROOT
(#19089)
7ecf65743e6 is described below
commit 7ecf65743e676497d4fad4de0a0fd6098715764c
Author: deepinsight coder <[email protected]>
AuthorDate: Tue Jul 28 14:30:24 2026 -0700
Harden schema case-collision validation with Locale.ROOT (#19089)
---
.../apache/pinot/core/util/SchemaUtilsTest.java | 29 ++++++++++++++++++++++
.../pinot/segment/local/utils/SchemaUtils.java | 8 +++---
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/util/SchemaUtilsTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/util/SchemaUtilsTest.java
index a335a66fe36..f2d4f07df81 100644
--- a/pinot-core/src/test/java/org/apache/pinot/core/util/SchemaUtilsTest.java
+++ b/pinot-core/src/test/java/org/apache/pinot/core/util/SchemaUtilsTest.java
@@ -331,6 +331,35 @@ public class SchemaUtilsTest {
checkValidationFails(pinotSchema, true);
}
+ /**
+ * Case-only column collisions (e.g. memberId / MemberID) are rejected when
case-insensitive mode is on.
+ * Cluster default is enable.case.insensitive=true, so new schemas on
default clusters are already protected.
+ * When case-insensitive mode is off, collisions are allowed (always-on
rejection needs validation levels #6645).
+ */
+ @Test
+ public void testValidateCaseOnlyColumnCollision() {
+ Schema collidingSchema = new
Schema.SchemaBuilder().setSchemaName(TABLE_NAME)
+ .addSingleValueDimension("memberId", DataType.STRING)
+ .addSingleValueDimension("MemberID", DataType.STRING)
+ .addDateTime(TIME_COLUMN, DataType.LONG, "1:MILLISECONDS:EPOCH",
"1:MILLISECONDS")
+ .build();
+
+ // Default cluster path: enable.case.insensitive=true rejects case-only
collisions
+ checkValidationFails(collidingSchema, true);
+
+ // Case-sensitive mode still allows collisions (compat; do not force
always-on without #6645)
+ SchemaUtils.validate(collidingSchema, false);
+
+ // Distinct after lowercasing is fine even when case-insensitive
+ Schema distinctSchema = new
Schema.SchemaBuilder().setSchemaName(TABLE_NAME)
+ .addSingleValueDimension("memberId", DataType.STRING)
+ .addSingleValueDimension("memberName", DataType.STRING)
+ .addDateTime(TIME_COLUMN, DataType.LONG, "1:MILLISECONDS:EPOCH",
"1:MILLISECONDS")
+ .build();
+ SchemaUtils.validate(distinctSchema, true);
+ SchemaUtils.validate(distinctSchema, false);
+ }
+
@Test
public void testValidatePrimaryKeyColumns() {
Schema pinotSchema;
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/SchemaUtils.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/SchemaUtils.java
index 7bcfbc053b6..99ec4d9ddc2 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/SchemaUtils.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/SchemaUtils.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
@@ -121,9 +122,10 @@ public class SchemaUtils {
if (isIgnoreCase) {
Set<String> lowerCaseColumnNames = new HashSet<>();
for (String column : schema.getColumnNames()) {
-
Preconditions.checkState(lowerCaseColumnNames.add(column.toLowerCase()),
- "When enable case insensitive, you can't use the same lowercase
column name: %s",
- column.toLowerCase());
+ // Locale.ROOT avoids locale-dependent lowercasing (e.g. Turkish
dotted/dotless I)
+ String lowerCaseColumn = column.toLowerCase(Locale.ROOT);
+ Preconditions.checkState(lowerCaseColumnNames.add(lowerCaseColumn),
+ "When enable case insensitive, you can't use the same lowercase
column name: %s", lowerCaseColumn);
}
}
Set<String> transformedColumns = new HashSet<>();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]