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

yiguolei pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new 8928bf91222 branch-3.0: [fix](schema-change) fix array/map/struct in 
schema-change not-null to null will make core #45305 (#45481)
8928bf91222 is described below

commit 8928bf9122293593616c73ffe61727daa985226e
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Dec 17 17:06:24 2024 +0800

    branch-3.0: [fix](schema-change) fix array/map/struct in schema-change 
not-null to null will make core #45305 (#45481)
    
    Cherry-picked from #45305
    
    Co-authored-by: amory <wangqian...@selectdb.com>
---
 be/src/olap/rowset/segment_v2/column_reader.cpp    | 42 +++++++++--
 .../ddl/create_nestedtypes_with_schemachange.out   | 84 ++++++++++++++++++++++
 .../create_nestedtypes_with_schemachange.groovy    | 57 +++++++++++++++
 3 files changed, 177 insertions(+), 6 deletions(-)

diff --git a/be/src/olap/rowset/segment_v2/column_reader.cpp 
b/be/src/olap/rowset/segment_v2/column_reader.cpp
index 66e24fc105e..f44885325e4 100644
--- a/be/src/olap/rowset/segment_v2/column_reader.cpp
+++ b/be/src/olap/rowset/segment_v2/column_reader.cpp
@@ -860,8 +860,18 @@ Status MapFileColumnIterator::next_batch(size_t* n, 
vectorized::MutableColumnPtr
         size_t num_read = *n;
         auto null_map_ptr =
                 
static_cast<vectorized::ColumnNullable&>(*dst).get_null_map_column_ptr();
-        bool null_signs_has_null = false;
-        RETURN_IF_ERROR(_null_iterator->next_batch(&num_read, null_map_ptr, 
&null_signs_has_null));
+        // in not-null to null linked-schemachange mode,
+        // actually we do not change dat data include meta in footer,
+        // so may dst from changed meta which is nullable but old data is not 
nullable,
+        // if so, we should set null_map to all null by default
+        if (_null_iterator) {
+            bool null_signs_has_null = false;
+            RETURN_IF_ERROR(
+                    _null_iterator->next_batch(&num_read, null_map_ptr, 
&null_signs_has_null));
+        } else {
+            auto& null_map = 
assert_cast<vectorized::ColumnUInt8&>(*null_map_ptr);
+            null_map.insert_many_vals(0, num_read);
+        }
         DCHECK(num_read == *n);
     }
     return Status::OK();
@@ -921,8 +931,18 @@ Status StructFileColumnIterator::next_batch(size_t* n, 
vectorized::MutableColumn
         size_t num_read = *n;
         auto null_map_ptr =
                 
static_cast<vectorized::ColumnNullable&>(*dst).get_null_map_column_ptr();
-        bool null_signs_has_null = false;
-        RETURN_IF_ERROR(_null_iterator->next_batch(&num_read, null_map_ptr, 
&null_signs_has_null));
+        // in not-null to null linked-schemachange mode,
+        // actually we do not change dat data include meta in footer,
+        // so may dst from changed meta which is nullable but old data is not 
nullable,
+        // if so, we should set null_map to all null by default
+        if (_null_iterator) {
+            bool null_signs_has_null = false;
+            RETURN_IF_ERROR(
+                    _null_iterator->next_batch(&num_read, null_map_ptr, 
&null_signs_has_null));
+        } else {
+            auto& null_map = 
assert_cast<vectorized::ColumnUInt8&>(*null_map_ptr);
+            null_map.insert_many_vals(0, num_read);
+        }
         DCHECK(num_read == *n);
     }
 
@@ -1075,8 +1095,18 @@ Status ArrayFileColumnIterator::next_batch(size_t* n, 
vectorized::MutableColumnP
         auto null_map_ptr =
                 
static_cast<vectorized::ColumnNullable&>(*dst).get_null_map_column_ptr();
         size_t num_read = *n;
-        bool null_signs_has_null = false;
-        RETURN_IF_ERROR(_null_iterator->next_batch(&num_read, null_map_ptr, 
&null_signs_has_null));
+        // in not-null to null linked-schemachange mode,
+        // actually we do not change dat data include meta in footer,
+        // so may dst from changed meta which is nullable but old data is not 
nullable,
+        // if so, we should set null_map to all null by default
+        if (_null_iterator) {
+            bool null_signs_has_null = false;
+            RETURN_IF_ERROR(
+                    _null_iterator->next_batch(&num_read, null_map_ptr, 
&null_signs_has_null));
+        } else {
+            auto& null_map = 
assert_cast<vectorized::ColumnUInt8&>(*null_map_ptr);
+            null_map.insert_many_vals(0, num_read);
+        }
         DCHECK(num_read == *n);
     }
 
diff --git 
a/regression-test/data/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.out
 
b/regression-test/data/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.out
index af88eb6b9bb..5b811095fcb 100644
--- 
a/regression-test/data/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.out
+++ 
b/regression-test/data/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.out
@@ -44,3 +44,87 @@ col3 array<int>      Yes     false   \N      NONE
 col4   map<int,int>    Yes     false   \N      NONE
 col5   struct<f1:int>  Yes     false   \N      NONE
 
+-- !sql_before --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql --
+col0   bigint  No      true    \N      
+col2   int     No      false   \N      NONE
+col3   array<int>      Yes     false   \N      NONE
+col4   map<int,int>    Yes     false   \N      NONE
+col5   struct<f1:int>  Yes     false   \N      NONE
+col6   variant Yes     false   \N      NONE
+
+-- !sql_after --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql_before --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql --
+col0   bigint  No      true    \N      
+col2   int     No      false   \N      NONE
+col3   array<int>      Yes     false   \N      NONE
+col4   map<int,int>    No      false   \N      NONE
+col5   struct<f1:int>  No      false   \N      NONE
+col6   variant No      false   \N      NONE
+
+-- !sql_after --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql_before --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql --
+col0   bigint  No      true    \N      
+col2   int     No      false   \N      NONE
+col3   array<int>      Yes     false   \N      NONE
+col4   map<int,int>    Yes     false   \N      NONE
+col5   struct<f1:int>  Yes     false   \N      NONE
+col6   variant Yes     false   \N      NONE
+
+-- !sql_after --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql_before --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql --
+col0   bigint  No      true    \N      
+col2   int     No      false   \N      NONE
+col3   array<int>      No      false   \N      NONE
+col4   map<int,int>    Yes     false   \N      NONE
+col5   struct<f1:int>  No      false   \N      NONE
+col6   variant No      false   \N      NONE
+
+-- !sql_after --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql_before --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql --
+col0   bigint  No      true    \N      
+col2   int     No      false   \N      NONE
+col3   array<int>      Yes     false   \N      NONE
+col4   map<int,int>    Yes     false   \N      NONE
+col5   struct<f1:int>  Yes     false   \N      NONE
+col6   variant Yes     false   \N      NONE
+
+-- !sql_after --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql_before --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
+-- !sql --
+col0   bigint  No      true    \N      
+col2   int     No      false   \N      NONE
+col3   array<int>      No      false   \N      NONE
+col4   map<int,int>    No      false   \N      NONE
+col5   struct<f1:int>  Yes     false   \N      NONE
+col6   variant No      false   \N      NONE
+
+-- !sql_after --
+1      2       [1, 2]  {1:2}   {"f1":1}        {"a":[1,2,3]}
+
diff --git 
a/regression-test/suites/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.groovy
 
b/regression-test/suites/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.groovy
index ec0f163821d..62b9ab3bb56 100644
--- 
a/regression-test/suites/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.groovy
+++ 
b/regression-test/suites/datatype_p0/nested_types/ddl/create_nestedtypes_with_schemachange.groovy
@@ -62,4 +62,61 @@ suite("create_nestedtypes_with_schemachange", "p0") {
     // struct with other type
     create_nested_table_and_schema_change.call("test_struct_schemachange_1", 
"STRUCT<f1: varchar(1)>", "col5", "errCode = 2");
 
+    def create_nested_table_and_schema_change_null_trans = {testTablex, 
nested_type, column_name, notNull2Null ->
+        def null_define = "NULL"
+        if (notNull2Null) {
+            null_define = "NOT NULL"
+        }
+        // create basic type
+        sql "DROP TABLE IF EXISTS $testTablex"
+        sql """ CREATE TABLE IF NOT EXISTS $testTablex (
+                     col0 BIGINT NOT NULL,
+                     col2 int NOT NULL,
+                     col3 array<int> $null_define,
+                     col4 map<int, int> $null_define,
+                     col5 struct<f1: int> $null_define,
+                     col6 variant $null_define
+                )
+                /* mow */
+                UNIQUE KEY(col0) DISTRIBUTED BY HASH(col0) BUCKETS 4 
PROPERTIES (
+                  "enable_unique_key_merge_on_write" = "true",
+                  "replication_num" = "1",
+                  'light_schema_change' = 'true', 
'disable_auto_compaction'='true'
+                ); """
+        // insert data
+        sql """ INSERT INTO $testTablex VALUES (1, 2, array(1, 2), map(1, 2), 
named_struct('f1', 1), '{"a": [1,2,3]}')"""
+        // select
+        qt_sql_before "select * from $testTablex"
+
+        if (notNull2Null) {
+            sql "ALTER TABLE $testTablex MODIFY COLUMN $column_name 
$nested_type NULL"
+            waitForSchemaChangeDone {
+                sql """ SHOW ALTER TABLE COLUMN WHERE IndexName='$testTablex' 
ORDER BY createtime DESC LIMIT 1 """
+                time 600
+            }
+        } else {
+            // schema change from null to non-nullable is not supported
+            test {
+               sql "ALTER TABLE $testTablex MODIFY COLUMN $column_name 
$nested_type NOT NULL"
+               exception "Can not change from nullable to non-nullable"
+            }
+        }
+        // desc table
+        qt_sql "DESC $testTablex"
+        qt_sql_after "select * from $testTablex"
+    }
+
+    // array
+    
create_nested_table_and_schema_change_null_trans.call("test_array_schemachange_null",
 "ARRAY<INT>", "col3", false)
+    
create_nested_table_and_schema_change_null_trans.call("test_array_schemachange_null1",
 "ARRAY<INT>", "col3", true)
+    // map
+    
create_nested_table_and_schema_change_null_trans.call("test_map_schemachange_null",
 "Map<INT, INT>", "col4", false)
+    
create_nested_table_and_schema_change_null_trans.call("test_map_schemachange_null1",
 "Map<INT, INT>", "col4", true)
+    // struct
+    
create_nested_table_and_schema_change_null_trans.call("test_struct_schemachange_null",
 "struct<f1: int>", "col5", false)
+    
create_nested_table_and_schema_change_null_trans.call("test_struct_schemachange_null1",
 "struct<f1: int>", "col5", true)
+    // variant
+    // 
create_nested_table_and_schema_change_null_trans.call("test_v_schemachange_null",
 "variant", "col6", false)
+    // 
create_nested_table_and_schema_change_null_trans.call("test_v_schemachange_null1",
 "variant", "col6", true)
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to