This is an automated email from the ASF dual-hosted git repository.

jianliangqi 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 b839353c2d [fix](inverted index) fix BE coredump because of not ignore 
case ensitivity for column name when create index (#17276)
b839353c2d is described below

commit b839353c2dd2f8f72b15eea82e4a86f486ba58ae
Author: YueW <[email protected]>
AuthorDate: Wed Mar 1 19:32:39 2023 +0800

    [fix](inverted index) fix BE coredump because of not ignore case ensitivity 
for column name when create index (#17276)
---
 be/src/olap/schema_change.cpp                      |  30 +++-
 be/src/olap/tablet_schema.cpp                      |   7 +-
 .../apache/doris/alter/SchemaChangeHandler.java    |  10 +-
 .../java/org/apache/doris/analysis/IndexDef.java   |   8 +
 .../test_add_drop_index_ignore_case_column.groovy  | 194 +++++++++++++++++++++
 5 files changed, 243 insertions(+), 6 deletions(-)

diff --git a/be/src/olap/schema_change.cpp b/be/src/olap/schema_change.cpp
index af254038bc..1735c3debc 100644
--- a/be/src/olap/schema_change.cpp
+++ b/be/src/olap/schema_change.cpp
@@ -627,8 +627,14 @@ Status 
SchemaChangeForInvertedIndex::process(RowsetReaderSharedPtr rowset_reader
             DCHECK_EQ(inverted_index.columns.size(), 1);
             auto index_id = inverted_index.index_id;
             auto column_name = inverted_index.columns[0];
-            auto column = _tablet_schema->column(column_name);
             auto column_idx = _tablet_schema->field_index(column_name);
+            if (column_idx < 0) {
+                LOG(WARNING) << "referenced column was missing. "
+                             << "[column=" << column_name << " 
referenced_column=" << column_idx
+                             << "]";
+                return Status::Error<CE_CMD_PARAMS_ERROR>();
+            }
+            auto column = _tablet_schema->column(column_idx);
             return_columns.emplace_back(column_idx);
             _olap_data_convertor->add_column_data_convertor(column);
 
@@ -782,7 +788,13 @@ Status 
SchemaChangeForInvertedIndex::_write_inverted_index(int32_t segment_idx,
     int idx = 0;
     for (auto& inverted_index : _alter_inverted_indexs) {
         auto column_name = inverted_index.columns[0];
-        auto column = _tablet_schema->column(column_name);
+        auto column_idx = _tablet_schema->field_index(column_name);
+        if (column_idx < 0) {
+            LOG(WARNING) << "referenced column was missing. "
+                         << "[column=" << column_name << " referenced_column=" 
<< column_idx << "]";
+            return Status::Error<CE_CMD_PARAMS_ERROR>();
+        }
+        auto column = _tablet_schema->column(column_idx);
         auto index_id = inverted_index.index_id;
 
         auto converted_result = 
_olap_data_convertor->convert_column_data(idx++);
@@ -1275,6 +1287,11 @@ Status 
SchemaChangeHandler::_get_rowset_readers(TabletSharedPtr tablet,
         DCHECK_EQ(inverted_index.columns.size(), 1);
         auto column_name = inverted_index.columns[0];
         auto idx = tablet_schema->field_index(column_name);
+        if (idx < 0) {
+            LOG(WARNING) << "referenced column was missing. "
+                         << "[column=" << column_name << " referenced_column=" 
<< idx << "]";
+            return Status::Error<CE_CMD_PARAMS_ERROR>();
+        }
         return_columns.emplace_back(idx);
     }
 
@@ -1382,7 +1399,14 @@ Status 
SchemaChangeHandler::_drop_inverted_index(std::vector<RowsetReaderSharedP
                                                                      
rowset_meta->rowset_id(), i);
             for (auto& inverted_index : alter_inverted_indexs) {
                 auto column_name = inverted_index.columns[0];
-                auto column = tablet_schema->column(column_name);
+                auto column_idx = tablet_schema->field_index(column_name);
+                if (column_idx < 0) {
+                    LOG(WARNING) << "referenced column was missing. "
+                                 << "[column=" << column_name << " 
referenced_column=" << column_idx
+                                 << "]";
+                    return Status::Error<CE_CMD_PARAMS_ERROR>();
+                }
+                auto column = tablet_schema->column(column_idx);
                 auto index_id = inverted_index.index_id;
 
                 std::string inverted_index_file =
diff --git a/be/src/olap/tablet_schema.cpp b/be/src/olap/tablet_schema.cpp
index 1c77ac3234..dcfac6ef7e 100644
--- a/be/src/olap/tablet_schema.cpp
+++ b/be/src/olap/tablet_schema.cpp
@@ -503,7 +503,12 @@ void TabletIndex::init_from_thrift(const TOlapTableIndex& 
index,
     // get column unique id by name
     std::vector<int32_t> col_unique_ids(index.columns.size());
     for (size_t i = 0; i < index.columns.size(); i++) {
-        col_unique_ids[i] = tablet_schema.column(index.columns[i]).unique_id();
+        auto column_idx = tablet_schema.field_index(index.columns[i]);
+        if (column_idx >= 0) {
+            col_unique_ids[i] = tablet_schema.column(column_idx).unique_id();
+        } else {
+            col_unique_ids[i] = -1;
+        }
     }
     _col_unique_ids = std::move(col_unique_ids);
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
index 3bfee997fd..11fb77c3ee 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
@@ -2128,7 +2128,8 @@ public class SchemaChangeHandler extends AlterHandler {
      */
     private boolean processAddIndex(CreateIndexClause alterClause, OlapTable 
olapTable, List<Index> newIndexes)
             throws UserException {
-        if (alterClause.getIndex() == null) {
+        Index alterIndex = alterClause.getIndex();
+        if (alterIndex == null) {
             return false;
         }
 
@@ -2166,7 +2167,12 @@ public class SchemaChangeHandler extends AlterHandler {
             }
         }
 
-        newIndexes.add(alterClause.getIndex());
+        // the column name in CreateIndexClause is not check case sensitivity,
+        // when send index description to BE, there maybe cannot find column 
by name,
+        // so here update column name in CreateIndexClause after checkColumn 
for indexDef,
+        // there will use the column name in olapTable insead of the column 
name in CreateIndexClause.
+        alterIndex.setColumns(indexDef.getColumns());
+        newIndexes.add(alterIndex);
         return false;
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/IndexDef.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/IndexDef.java
index d1c21b5d37..711a83496b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IndexDef.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IndexDef.java
@@ -24,6 +24,7 @@ import org.apache.doris.catalog.PrimitiveType;
 import org.apache.doris.common.AnalysisException;
 
 import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
 
 import java.util.HashMap;
 import java.util.List;
@@ -34,6 +35,9 @@ public class IndexDef {
     private String indexName;
     private boolean ifNotExists;
     private List<String> columns;
+    // add the column name of olapTable column into caseSensitivityColumns
+    // instead of the column name which from sql_parser analyze
+    private List<String> caseSensitivityColumns = Lists.newArrayList();
     private IndexType indexType;
     private String comment;
     private Map<String, String> properties;
@@ -142,6 +146,9 @@ public class IndexDef {
     }
 
     public List<String> getColumns() {
+        if (caseSensitivityColumns.size() > 0) {
+            return caseSensitivityColumns;
+        }
         return columns;
     }
 
@@ -176,6 +183,7 @@ public class IndexDef {
         if (indexType == IndexType.BITMAP || indexType == IndexType.INVERTED 
|| indexType == IndexType.BLOOMFILTER
                 || indexType == IndexType.NGRAM_BF) {
             String indexColName = column.getName();
+            caseSensitivityColumns.add(indexColName);
             PrimitiveType colType = column.getDataType();
             if (indexType == IndexType.INVERTED && colType.isArrayType()) {
                 colType = ((ArrayType) 
column.getType()).getItemType().getPrimitiveType();
diff --git 
a/regression-test/suites/inverted_index_p0/test_add_drop_index_ignore_case_column.groovy
 
b/regression-test/suites/inverted_index_p0/test_add_drop_index_ignore_case_column.groovy
new file mode 100644
index 0000000000..ca8e390f67
--- /dev/null
+++ 
b/regression-test/suites/inverted_index_p0/test_add_drop_index_ignore_case_column.groovy
@@ -0,0 +1,194 @@
+// 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.
+
+
+suite("test_add_drop_index_with_ignore_case_column", "inverted_index"){
+    // prepare test table
+    def timeout = 60000
+    def delta_time = 1000
+    def alter_res = "null"
+    def useTime = 0
+    def wait_for_latest_op_on_table_finish = { table_name, OpTimeout ->
+        for(int t = delta_time; t <= OpTimeout; t += delta_time){
+            alter_res = sql """SHOW ALTER TABLE COLUMN WHERE TableName = 
"${table_name}" ORDER BY CreateTime DESC LIMIT 1;"""
+            alter_res = alter_res.toString()
+            if(alter_res.contains("FINISHED")) {
+                 break
+            }
+            useTime = t
+            sleep(delta_time)
+        }
+        assertTrue(useTime <= OpTimeout)
+    }
+
+    def indexTbName1 = "test_add_drop_inverted_index4"
+
+    sql "DROP TABLE IF EXISTS ${indexTbName1}"
+    // create 1 replica table
+    sql """
+            CREATE TABLE IF NOT EXISTS ${indexTbName1} (
+                `id` int(11) NULL,
+                `Name` text NULL,
+                `Description` text NULL,
+                INDEX idx_id (`id`) USING INVERTED COMMENT '',
+                INDEX idx_name (`name`) USING INVERTED 
PROPERTIES("parser"="none") COMMENT ''
+            )
+            DUPLICATE KEY(`id`)
+            DISTRIBUTED BY HASH(`id`) BUCKETS 10
+            properties("replication_num" = "1");
+    """
+
+    // set enable_vectorized_engine=true
+    sql """ SET enable_vectorized_engine=true; """
+    def var_result = sql "show variables"
+    logger.info("show variales result: " + var_result )
+
+    // show index of create table
+    def show_result = sql "show index from ${indexTbName1}"
+    logger.info("show index from " + indexTbName1 + " result: " + show_result)
+    assertEquals(show_result[0][2], "idx_id")
+    assertEquals(show_result[1][2], "idx_name")
+
+    // insert data
+    sql "insert into ${indexTbName1} values (1, 'name1', 'desc 1'), (2, 
'name2', 'desc 2')"
+
+    // query all rows
+    def select_result = sql "select * from ${indexTbName1} order by id"
+    assertEquals(select_result.size(), 2)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+    assertEquals(select_result[1][0], 2)
+    assertEquals(select_result[1][1], "name2")
+    assertEquals(select_result[1][2], "desc 2")
+
+    // query rows where name='name1'
+    select_result = sql "select * from ${indexTbName1} where name='name1'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+
+    // query rows where name match 'name2'
+    select_result = sql "select * from ${indexTbName1} where name match 
'name2'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 2)
+    assertEquals(select_result[0][1], "name2")
+    assertEquals(select_result[0][2], "desc 2")
+
+    // query rows where description match 'desc', should fail without index
+    def success = false
+    try {
+        sql "select * from ${indexTbName1} where description match 'desc'"
+        success = true
+    } catch(Exception ex) {
+        logger.info("sql exception: " + ex)
+    }
+    assertEquals(success, false)
+
+    // add index on column description
+    sql "create index idx_desc on ${indexTbName1}(description) USING INVERTED 
PROPERTIES(\"parser\"=\"standard\");"
+    wait_for_latest_op_on_table_finish(indexTbName1, timeout)
+
+    // show index after add index
+    show_result = sql "show index from ${indexTbName1}"
+    logger.info("show index from " + indexTbName1 + " result: " + show_result)
+    assertEquals(show_result[0][2], "idx_id")
+    assertEquals(show_result[1][2], "idx_name")
+    assertEquals(show_result[2][2], "idx_desc")
+
+    // query rows where description match 'desc'
+    select_result = sql "select * from ${indexTbName1} where description match 
'desc' order by id"
+    assertEquals(select_result.size(), 2)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+    assertEquals(select_result[1][0], 2)
+    assertEquals(select_result[1][1], "name2")
+    assertEquals(select_result[1][2], "desc 2")
+
+    // query rows where description match_all 'desc 1'
+    select_result = sql "select * from ${indexTbName1} where description 
match_all 'desc 1'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+
+    // query rows where description match_all 'desc 2'
+    select_result = sql "select * from ${indexTbName1} where description 
match_all 'desc 2'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 2)
+    assertEquals(select_result[0][1], "name2")
+    assertEquals(select_result[0][2], "desc 2")
+
+    // drop index
+    // add index on column description
+    sql "drop index idx_desc on ${indexTbName1}"
+    wait_for_latest_op_on_table_finish(indexTbName1, timeout)
+
+    // query rows where description match 'desc', should fail without index
+    success = false
+    try {
+        sql "select * from ${indexTbName1} where description match 'desc'"
+        success = true
+    } catch(Exception ex) {
+        logger.info("sql exception: " + ex)
+    }
+    assertEquals(success, false)
+
+    // query rows where name='name1'
+    select_result = sql "select * from ${indexTbName1} where name='name1'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+
+    // query rows where name='name2'
+    select_result = sql "select * from ${indexTbName1} where name='name2'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 2)
+    assertEquals(select_result[0][1], "name2")
+    assertEquals(select_result[0][2], "desc 2")
+
+    // add index on column description
+    sql "create index idx_desc on ${indexTbName1}(DESCRIPTION) USING INVERTED 
PROPERTIES(\"parser\"=\"standard\");"
+    wait_for_latest_op_on_table_finish(indexTbName1, timeout)
+
+    // query rows where description match 'desc'
+    select_result = sql "select * from ${indexTbName1} where description match 
'desc' order by id"
+    assertEquals(select_result.size(), 2)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+    assertEquals(select_result[1][0], 2)
+    assertEquals(select_result[1][1], "name2")
+    assertEquals(select_result[1][2], "desc 2")
+
+    // query rows where description match_all 'desc 1'
+    select_result = sql "select * from ${indexTbName1} where description 
match_all 'desc 1'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 1)
+    assertEquals(select_result[0][1], "name1")
+    assertEquals(select_result[0][2], "desc 1")
+
+    // query rows where description match_all 'desc 2'
+    select_result = sql "select * from ${indexTbName1} where description 
match_all 'desc 2'"
+    assertEquals(select_result.size(), 1)
+    assertEquals(select_result[0][0], 2)
+    assertEquals(select_result[0][1], "name2")
+    assertEquals(select_result[0][2], "desc 2")
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to