This is an automated email from the ASF dual-hosted git repository.
hellostephen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 47ffca97696 [enhancement](inverted index) ensure consistent ordering
of properties for inverted index show (#51467)
47ffca97696 is described below
commit 47ffca97696aff67cfcfcd961c4933e4699fff29
Author: airborne12 <[email protected]>
AuthorDate: Thu Jun 5 14:40:07 2025 +0800
[enhancement](inverted index) ensure consistent ordering of properties for
inverted index show (#51467)
Problem Summary:
This PR enhances the inverted index implementation to always output its
properties in a consistent, alphabetical order and adds tests to verify
this behavior.
---
.../main/java/org/apache/doris/catalog/Index.java | 3 +-
.../doris/analysis/ShowCreateTableStmtTest.java | 39 +++++++++++
.../doris/catalog/IndexPropertiesOrderTest.java | 78 ++++++++++++++++++++++
.../doris/common/proc/IndexesProcNodeTest.java | 2 +-
.../test_backup_restore_inverted_index.groovy | 2 +-
.../suites/index_p0/test_index_meta.groovy | 10 +--
6 files changed, 126 insertions(+), 8 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Index.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Index.java
index af4ff1501d6..d55aedb97af 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Index.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Index.java
@@ -145,7 +145,8 @@ public class Index implements Writable {
return "";
}
- return "(" + new PrintableMap(properties, "=", true, false,
",").toString() + ")";
+ // Use TreeMap to ensure consistent ordering of properties
+ return "(" + new PrintableMap(new java.util.TreeMap<>(properties),
"=", true, false, ",").toString() + ")";
}
public String getInvertedIndexParser() {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowCreateTableStmtTest.java
b/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowCreateTableStmtTest.java
index 0faf4a8f34e..7294398ea4c 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowCreateTableStmtTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowCreateTableStmtTest.java
@@ -40,6 +40,15 @@ public class ShowCreateTableStmtTest extends
TestWithFeService {
+ ") "
+ "distributed by hash(k1) buckets 1\n"
+ "properties(\"replication_num\" = \"1\");");
+
+ // Create a table with inverted index for testing index properties
order
+ createTable("create table table_with_index\n"
+ + "(id int, name varchar(100), description text, "
+ + "INDEX index_name(name) USING INVERTED
PROPERTIES(\"parser\"=\"english\", \"lower_case\"=\"true\",
\"support_phrase\"=\"true\") COMMENT 'name index', "
+ + "INDEX index_description(description) USING INVERTED
PROPERTIES(\"support_phrase\"=\"true\", \"parser\"=\"standard\",
\"lower_case\"=\"true\") COMMENT 'description index') "
+ + "DUPLICATE KEY(id) "
+ + "distributed by hash(id) buckets 1\n"
+ + "properties(\"replication_num\" = \"1\");");
}
@@ -70,4 +79,34 @@ public class ShowCreateTableStmtTest extends
TestWithFeService {
Assertions.assertTrue(!showSql.contains("PARTITION BY"));
Assertions.assertTrue(!showSql.contains("PARTITION `p01`"));
}
+
+ @Test
+ public void testIndexPropertiesOrder() throws Exception {
+ String sql = "show create table table_with_index";
+
+ // Execute the same query multiple times to check consistency
+ ShowResultSet showResultSet1 = showCreateTable(sql);
+ ShowResultSet showResultSet2 = showCreateTable(sql);
+ ShowResultSet showResultSet3 = showCreateTable(sql);
+
+ String showSql1 = showResultSet1.getResultRows().get(0).get(1);
+ String showSql2 = showResultSet2.getResultRows().get(0).get(1);
+ String showSql3 = showResultSet3.getResultRows().get(0).get(1);
+
+ // All show create table results should be identical
+ Assertions.assertEquals(showSql1, showSql2, "Show create table results
should be consistent across multiple executions");
+ Assertions.assertEquals(showSql2, showSql3, "Show create table results
should be consistent across multiple executions");
+
+ // Verify that the index properties are present and in alphabetical
order
+ // The properties should appear as: "lower_case" = "true", "parser" =
"english", "support_phrase" = "true"
+ Assertions.assertTrue(showSql1.contains("INDEX index_name (`name`)
USING INVERTED "
+ + "PROPERTIES(\"lower_case\" = \"true\", \"parser\" =
\"english\", "
+ + "\"support_phrase\" = \"true\")"),
+ "Index properties should be in alphabetical
order");
+ Assertions.assertTrue(showSql1.contains(
+ "INDEX index_description (`description`) USING INVERTED "
+ + "PROPERTIES(\"lower_case\" = \"true\", \"parser\" =
\"standard\", "
+ + "\"support_phrase\" = \"true\")"),
+ "Index properties should be in alphabetical
order");
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/catalog/IndexPropertiesOrderTest.java
b/fe/fe-core/src/test/java/org/apache/doris/catalog/IndexPropertiesOrderTest.java
new file mode 100644
index 00000000000..19ba0486e26
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/catalog/IndexPropertiesOrderTest.java
@@ -0,0 +1,78 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.catalog;
+
+import org.apache.doris.analysis.IndexDef;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class IndexPropertiesOrderTest {
+
+ @Test
+ public void testIndexPropertiesConsistentOrder() {
+ // Create properties with multiple key-value pairs to test ordering
+ Map<String, String> properties = new HashMap<>();
+ properties.put("parser", "english");
+ properties.put("lower_case", "true");
+ properties.put("support_phrase", "true");
+
+ List<String> columns = Arrays.asList("description");
+
+ // Create multiple Index objects with the same properties
+ Index index1 = new Index(1L, "test_idx", columns,
IndexDef.IndexType.INVERTED,
+ new HashMap<>(properties), "test comment");
+ Index index2 = new Index(2L, "test_idx", columns,
IndexDef.IndexType.INVERTED,
+ new HashMap<>(properties), "test comment");
+ Index index3 = new Index(3L, "test_idx", columns,
IndexDef.IndexType.INVERTED,
+ new HashMap<>(properties), "test comment");
+
+ // The properties part should be consistent across all instances
+ String props1 = index1.getPropertiesString();
+ String props2 = index2.getPropertiesString();
+ String props3 = index3.getPropertiesString();
+
+ // Assert that all properties strings are identical
+ Assertions.assertEquals(props1, props2, "Properties order should be
consistent between index1 and index2");
+ Assertions.assertEquals(props2, props3, "Properties order should be
consistent between index2 and index3");
+ Assertions.assertEquals(props1, props3, "Properties order should be
consistent between index1 and index3");
+
+ // Verify the properties are in alphabetical order
+ Assertions.assertTrue(props1.contains("lower_case"), "Properties
should contain lower_case");
+ Assertions.assertTrue(props1.contains("parser"), "Properties should
contain parser");
+ Assertions.assertTrue(props1.contains("support_phrase"), "Properties
should contain support_phrase");
+
+ // Test with different orderings of the same properties
+ Map<String, String> properties2 = new LinkedHashMap<>();
+ properties2.put("support_phrase", "true");
+ properties2.put("parser", "english");
+ properties2.put("lower_case", "true");
+ Index index4 = new Index(4L, "test_idx", columns,
IndexDef.IndexType.INVERTED,
+ properties2, "test comment");
+ String props4 = index4.getPropertiesString();
+
+ // Should still be the same as the others due to TreeMap sorting
+ Assertions.assertEquals(props1, props4, "Properties order should be
consistent regardless of input order");
+ }
+}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/common/proc/IndexesProcNodeTest.java
b/fe/fe-core/src/test/java/org/apache/doris/common/proc/IndexesProcNodeTest.java
index 6cae36af9f2..48ff245af5c 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/common/proc/IndexesProcNodeTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/common/proc/IndexesProcNodeTest.java
@@ -80,7 +80,7 @@ public class IndexesProcNodeTest {
Assert.assertEquals(procResult.getRows().get(1).get(5), "col_2");
Assert.assertEquals(procResult.getRows().get(1).get(11), "INVERTED");
Assert.assertEquals(procResult.getRows().get(1).get(12), "inverted
index on col_2");
- Assert.assertEquals(procResult.getRows().get(1).get(13), "(\"parser\"
= \"unicode\", \"lower_case\" = \"true\", \"support_phrase\" = \"true\")");
+ Assert.assertEquals(procResult.getRows().get(1).get(13),
"(\"lower_case\" = \"true\", \"parser\" = \"unicode\", \"support_phrase\" =
\"true\")");
Assert.assertEquals(procResult.getRows().get(2).get(0),
"tbl_test_indexes_proc");
Assert.assertEquals(procResult.getRows().get(2).get(1), "3");
diff --git
a/regression-test/suites/backup_restore/test_backup_restore_inverted_index.groovy
b/regression-test/suites/backup_restore/test_backup_restore_inverted_index.groovy
index 6e3ad67c3c1..443c0e80547 100644
---
a/regression-test/suites/backup_restore/test_backup_restore_inverted_index.groovy
+++
b/regression-test/suites/backup_restore/test_backup_restore_inverted_index.groovy
@@ -75,7 +75,7 @@ suite("test_backup_restore_inverted_index", "backup_restore")
{
def restore_index_comment = sql "SHOW CREATE TABLE ${dbName}.${tableName}"
- assertTrue(restore_index_comment[0][1].contains("USING INVERTED
PROPERTIES(\"parser\" = \"english\", \"lower_case\" = \"true\",
\"support_phrase\" = \"true\")"))
+ assertTrue(restore_index_comment[0][1].contains("USING INVERTED
PROPERTIES(\"lower_case\" = \"true\", \"parser\" = \"english\",
\"support_phrase\" = \"true\")"))
result = sql "SELECT id, TOKENIZE(comment,'\"parser\"=\"english\"') as
token FROM ${dbName}.${tableName}"
assertEquals(result.size(), 2)
diff --git a/regression-test/suites/index_p0/test_index_meta.groovy
b/regression-test/suites/index_p0/test_index_meta.groovy
index b38206e7e21..d7647f2a9a3 100644
--- a/regression-test/suites/index_p0/test_index_meta.groovy
+++ b/regression-test/suites/index_p0/test_index_meta.groovy
@@ -71,7 +71,7 @@ suite("index_meta", "p0") {
assertEquals(show_result[1][4], "name")
assertEquals(show_result[1][10], "INVERTED")
assertEquals(show_result[1][11], "index for name")
- assertEquals(show_result[1][12], "(\"parser\" = \"none\", \"lower_case\" =
\"true\", \"support_phrase\" = \"true\")")
+ assertEquals(show_result[1][12], "(\"lower_case\" = \"true\", \"parser\" =
\"none\", \"support_phrase\" = \"true\")")
// add index on column description
sql "create index idx_desc on ${tableName}(description) USING INVERTED
PROPERTIES(\"parser\"=\"standard\") COMMENT 'index for description';"
@@ -90,12 +90,12 @@ suite("index_meta", "p0") {
assertEquals(show_result[1][4], "name")
assertEquals(show_result[1][10], "INVERTED")
assertEquals(show_result[1][11], "index for name")
- assertEquals(show_result[1][12], "(\"parser\" = \"none\", \"lower_case\" =
\"true\", \"support_phrase\" = \"true\")")
+ assertEquals(show_result[1][12], "(\"lower_case\" = \"true\", \"parser\" =
\"none\", \"support_phrase\" = \"true\")")
assertEquals(show_result[2][2], "idx_desc")
assertEquals(show_result[2][4], "description")
assertEquals(show_result[2][10], "INVERTED")
assertEquals(show_result[2][11], "index for description")
- assertEquals(show_result[2][12], "(\"parser\" = \"standard\",
\"lower_case\" = \"true\", \"support_phrase\" = \"true\")")
+ assertEquals(show_result[2][12], "(\"lower_case\" = \"true\", \"parser\" =
\"standard\", \"support_phrase\" = \"true\")")
// drop index
// add index on column description
@@ -114,7 +114,7 @@ suite("index_meta", "p0") {
assertEquals(show_result[1][4], "description")
assertEquals(show_result[1][10], "INVERTED")
assertEquals(show_result[1][11], "index for description")
- assertEquals(show_result[1][12], "(\"parser\" = \"standard\",
\"lower_case\" = \"true\", \"support_phrase\" = \"true\")")
+ assertEquals(show_result[1][12], "(\"lower_case\" = \"true\", \"parser\" =
\"standard\", \"support_phrase\" = \"true\")")
// add index on column description
sql "create index idx_name on ${tableName}(name) USING INVERTED COMMENT
'new index for name';"
@@ -133,7 +133,7 @@ suite("index_meta", "p0") {
assertEquals(show_result[1][4], "description")
assertEquals(show_result[1][10], "INVERTED")
assertEquals(show_result[1][11], "index for description")
- assertEquals(show_result[1][12], "(\"parser\" = \"standard\",
\"lower_case\" = \"true\", \"support_phrase\" = \"true\")")
+ assertEquals(show_result[1][12], "(\"lower_case\" = \"true\", \"parser\" =
\"standard\", \"support_phrase\" = \"true\")")
assertEquals(show_result[2][2], "idx_name")
assertEquals(show_result[2][4], "name")
assertEquals(show_result[2][10], "INVERTED")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]