github-actions[bot] commented on code in PR #67918:
URL: https://github.com/apache/doris/pull/67918#discussion_r4081551206


##########
fe/fe-core/src/main/java/org/apache/doris/analysis/invertedindex/AnalyzerIdentityBuilder.java:
##########
@@ -45,14 +113,61 @@ public static String buildAnalyzerIdentity(
         }
 
         if (!Strings.isNullOrEmpty(preferredAnalyzer)) {
+            String builtinIkIdentity = 
resolveBuiltinIkAnalyzerIdentity(properties, preferredAnalyzer);
+            if (builtinIkIdentity != null) {
+                return appendOuterCharFilterIdentity(
+                        builtinIkIdentity, properties, 
builtinIkFoldContext(builtinIkIdentity));
+            }
             // For custom analyzer/normalizer, resolve to underlying config to 
build identity
-            return resolveAnalyzerIdentity(preferredAnalyzer, 
defaultAnalyzerKey, log);
+            return appendOuterCharFilterIdentity(
+                    resolveAnalyzerIdentity(preferredAnalyzer, 
defaultAnalyzerKey, log), properties,
+                    customAnalyzerFoldContext(preferredAnalyzer));
         }
 
         if (Strings.isNullOrEmpty(parser) || 
parserNone.equalsIgnoreCase(parser)) {
             return defaultAnalyzerKey;
         }
-        return parser;
+        String legacyIkIdentity = resolveLegacyIkIdentity(properties, parser);
+        if (legacyIkIdentity != null) {
+            return appendOuterCharFilterIdentity(
+                    legacyIkIdentity, properties, 
builtinIkFoldContext(legacyIkIdentity));
+        }
+        return appendOuterCharFilterIdentity(parser, properties, null);

Review Comment:
   [P2] Canonicalize the standard/unicode analyzer alias. This branch preserves 
the parser spelling, so an otherwise-identical standard/unicode pair gets 
different identities and selectors and passes both CREATE and ALTER duplicate 
fences. BE handles PARSER_STANDARD and PARSER_UNICODE in the same 
create_builtin_analyzer branch and constructs StandardAnalyzer for both, while 
this feature otherwise rejects analyzers with the same effective configuration. 
Please map these aliases to one identity and cover both DDL paths.



##########
regression-test/suites/inverted_index_p0/analyzer/test_analyzer_malformed_utf8_write.groovy:
##########
@@ -0,0 +1,110 @@
+// 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.
+
+// A string column may hold bytes that are not valid UTF-8. Indexing them must 
keep working:
+// the malformed bytes are skipped and the valid text around them stays 
searchable.
+suite("test_analyzer_malformed_utf8_write", "p0") {
+    def ngramTable = "test_malformed_utf8_ngram"
+    def icuTable = "test_malformed_utf8_icu"
+
+    sql "DROP TABLE IF EXISTS ${ngramTable}"
+    sql "DROP TABLE IF EXISTS ${icuTable}"
+
+    sql """
+        CREATE INVERTED INDEX TOKENIZER IF NOT EXISTS 
malformed_utf8_ngram_tokenizer
+        PROPERTIES
+        (
+            "type" = "ngram",
+            "min_gram" = "2",
+            "max_gram" = "2"
+        );
+    """
+
+    sql """
+        CREATE INVERTED INDEX ANALYZER IF NOT EXISTS 
malformed_utf8_ngram_analyzer
+        PROPERTIES
+        (
+            "tokenizer" = "malformed_utf8_ngram_tokenizer"
+        );
+    """
+
+    sql """
+        CREATE INVERTED INDEX ANALYZER IF NOT EXISTS 
malformed_utf8_icu_analyzer
+        PROPERTIES
+        (
+            "tokenizer" = "icu"
+        );
+    """
+
+    for (String analyzer : ["malformed_utf8_ngram_analyzer", 
"malformed_utf8_icu_analyzer"]) {
+        Exception lastException = null
+        boolean ready = false
+        for (int attempt = 0; attempt < 30; attempt++) {
+            try {
+                sql """SELECT TOKENIZE('probe', '"analyzer"="${analyzer}"')"""
+                ready = true
+                break
+            } catch (Exception e) {
+                lastException = e
+                sleep(1000)
+            }
+        }
+        assertTrue(ready, "Analyzer ${analyzer} was not ready: 
${lastException?.message}")
+    }
+
+    sql """
+        CREATE TABLE ${ngramTable} (
+            `id` int NOT NULL,
+            `ch` text NULL,
+            INDEX idx_ch (`ch`) USING INVERTED PROPERTIES("analyzer" = 
"malformed_utf8_ngram_analyzer")
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`id`)
+        DISTRIBUTED BY HASH(`id`) BUCKETS 1
+        PROPERTIES ("replication_allocation" = "tag.location.default: 1");
+    """
+
+    sql """
+        CREATE TABLE ${icuTable} (
+            `id` int NOT NULL,
+            `ch` text NULL,
+            INDEX idx_ch (`ch`) USING INVERTED PROPERTIES("analyzer" = 
"malformed_utf8_icu_analyzer")
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`id`)
+        DISTRIBUTED BY HASH(`id`) BUCKETS 1
+        PROPERTIES ("replication_allocation" = "tag.location.default: 1");
+    """
+
+    // An overlong encoding and a byte that can never start a sequence.
+    sql """ INSERT INTO ${ngramTable} VALUES (1, CONCAT('abcd', UNHEX('C0AF'), 
'efgh')) """
+    sql """ INSERT INTO ${ngramTable} VALUES (2, CONCAT('wxyz', UNHEX('FF'))) 
"""
+    sql """ INSERT INTO ${ngramTable} VALUES (3, 'plain') """
+    sql """ INSERT INTO ${icuTable} VALUES (1, CONCAT('alpha ', UNHEX('FF'), ' 
beta')) """
+    sql """ INSERT INTO ${icuTable} VALUES (2, 'gamma delta') """
+
+    sql "sync"
+
+    // Every row was written, so the malformed bytes did not fail the index 
write.
+    assertEquals(3, sql("SELECT COUNT(*) FROM ${ngramTable}")[0][0])

Review Comment:
   [P2] Record these deterministic results as golden queries. The stable row 
and MATCH counts on lines 101-109 are checked only with assertEquals, and this 
change adds no corresponding regression-test data .out file. The repository 
test contract requires determined results to use qt_sql/order_qt_sql (or 
similar) so the runner generates and reviews the expected output. Please 
convert these checks and add the generated .out.



##########
fe/fe-core/src/main/java/org/apache/doris/analysis/invertedindex/AnalyzerIdentityBuilder.java:
##########
@@ -45,14 +113,61 @@ public static String buildAnalyzerIdentity(
         }
 
         if (!Strings.isNullOrEmpty(preferredAnalyzer)) {
+            String builtinIkIdentity = 
resolveBuiltinIkAnalyzerIdentity(properties, preferredAnalyzer);
+            if (builtinIkIdentity != null) {
+                return appendOuterCharFilterIdentity(
+                        builtinIkIdentity, properties, 
builtinIkFoldContext(builtinIkIdentity));
+            }
             // For custom analyzer/normalizer, resolve to underlying config to 
build identity
-            return resolveAnalyzerIdentity(preferredAnalyzer, 
defaultAnalyzerKey, log);
+            return appendOuterCharFilterIdentity(
+                    resolveAnalyzerIdentity(preferredAnalyzer, 
defaultAnalyzerKey, log), properties,

Review Comment:
   [P2] Canonicalize built-ins against their effective component graphs. The 
built-in fast path in resolveAnalyzerIdentity returns bare names, while named 
custom analyzers with tokenizer=basic/icu plus token_filter=lowercase get 
component identities; their distinct selectors then let both CREATE and ALTER 
accept each pair. BE's BasicAnalyzer and ICUAnalyzer are exactly those 
tokenizer-plus-LowerCaseFilter pipelines under default settings (including 
ICU's same dictionary path). Please give these built-ins the matching effective 
identities and cover both DDL paths.



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