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

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

commit 3121ea3dd7ecb43ef79fe796a102111ab9f63742
Author: Mingyu Chen <[email protected]>
AuthorDate: Fri Aug 23 11:35:47 2024 +0800

    [fix](ctas) fix NPE when ctas with old planner and varchar issue (#39744)
    
    Fix 2 bugs:
    1.
    introduced from #35489
    When the target table is unpartitioned with text type column from
    external table,
    NPE will be thrown.
    Only happen when using old planner.
    The new planner works well.
    
    2.
    If first column is varchar type, the new planner will change it to
    string type
    and then failed because first column can not be string type.
---
 .../apache/doris/datasource/InternalCatalog.java   |  5 +++--
 .../trees/plans/commands/CreateTableCommand.java   | 17 ++++++++++++---
 .../jdbc/test_mysql_jdbc_catalog.out               | 18 ++++++++++++++++
 .../jdbc/test_mysql_jdbc_catalog.groovy            | 25 ++++++++++++++++++++++
 4 files changed, 60 insertions(+), 5 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index eb982c4e742..61d783fa6a6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -1369,8 +1369,9 @@ public class InternalCatalog implements 
CatalogIf<Database> {
                     if (resultExpr.getSrcSlotRef() != null
                             && resultExpr.getSrcSlotRef().getTable() != null
                             && 
!resultExpr.getSrcSlotRef().getTable().isManagedTable()) {
-                        if 
(createTableStmt.getPartitionDesc().inIdentifierPartitions(
-                                resultExpr.getSrcSlotRef().getColumnName())
+                        if ((createTableStmt.getPartitionDesc() != null
+                                && 
createTableStmt.getPartitionDesc().inIdentifierPartitions(
+                                resultExpr.getSrcSlotRef().getColumnName()))
                                 || (createTableStmt.getDistributionDesc() != 
null
                                 && 
createTableStmt.getDistributionDesc().inDistributionColumns(
                                         
resultExpr.getSrcSlotRef().getColumnName()))) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java
index 9f54b858d68..ad39513c83d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java
@@ -124,6 +124,8 @@ public class CreateTableCommand extends Command implements 
ForwardWithSync {
             Slot s = slots.get(i);
             DataType dataType = s.getDataType().conversion();
             if (i == 0 && dataType.isStringType()) {
+                // first column of olap table can not be string type.
+                // So change it to varchar type.
                 dataType = 
VarcharType.createVarcharType(ScalarType.MAX_VARCHAR_LENGTH);
             } else {
                 dataType = TypeCoercionUtils.replaceSpecifiedType(dataType,
@@ -136,13 +138,21 @@ public class CreateTableCommand extends Command 
implements ForwardWithSync {
                         if 
(createTableInfo.getPartitionTableInfo().inIdentifierPartitions(s.getName())
                                 || (createTableInfo.getDistribution() != null
                                 && 
createTableInfo.getDistribution().inDistributionColumns(s.getName()))) {
-                            // String type can not be used in 
partition/distributed column
+                            // String type can not be used in 
partition/distributed column,
                             // so we replace it to varchar
                             dataType = 
TypeCoercionUtils.replaceSpecifiedType(dataType,
                                     StringType.class, 
VarcharType.MAX_VARCHAR_TYPE);
                         } else {
-                            dataType = 
TypeCoercionUtils.replaceSpecifiedType(dataType,
-                                    CharacterType.class, StringType.INSTANCE);
+                            if (i == 0) {
+                                // first column of olap table can not be 
string type.
+                                // So change it to varchar type.
+                                dataType = 
TypeCoercionUtils.replaceSpecifiedType(dataType,
+                                        CharacterType.class, 
VarcharType.MAX_VARCHAR_TYPE);
+                            } else {
+                                // change varchar/char column from external 
table to string type
+                                dataType = 
TypeCoercionUtils.replaceSpecifiedType(dataType,
+                                        CharacterType.class, 
StringType.INSTANCE);
+                            }
                         }
                     }
                 } else {
@@ -218,3 +228,4 @@ public class CreateTableCommand extends Command implements 
ForwardWithSync {
         return StmtType.CREATE;
     }
 }
+
diff --git 
a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out 
b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
index c9448cb3bca..2be6d4a141f 100644
--- a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
+++ b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
@@ -468,3 +468,21 @@ doris
 
 -- !sql --
 
+-- !sql --
+int_u  bigint  Yes     true    \N      
+text   varchar(65533)  Yes     true    \N      
+t2     text    Yes     false   \N      NONE
+
+-- !sql --
+varchar        varchar(65533)  Yes     true    \N      
+int_u  bigint  Yes     false   \N      NONE
+
+-- !sql --
+int_u  bigint  Yes     true    \N      
+text   varchar(65533)  Yes     true    \N      
+t2     varchar(65533)  Yes     false   \N      NONE
+
+-- !sql --
+varchar        varchar(65533)  Yes     true    \N      
+int_u  bigint  Yes     false   \N      NONE
+
diff --git 
a/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy 
b/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
index 888edcc0fcd..d30d7fe9150 100644
--- 
a/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
+++ 
b/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
@@ -23,6 +23,7 @@ suite("test_mysql_jdbc_catalog", 
"p0,external,mysql,external_docker,external_doc
     String s3_endpoint = getS3Endpoint()
     String bucket = getS3BucketName()
     String driver_url = 
"https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-8.0.25.jar";
+    // String driver_url = "mysql-connector-java-8.0.25.jar"
     if (enabled != null && enabled.equalsIgnoreCase("true")) {
         String user = "test_jdbc_user";
         String pwd = '123456';
@@ -612,6 +613,30 @@ suite("test_mysql_jdbc_catalog", 
"p0,external,mysql,external_docker,external_doc
 
         order_qt_sql """select * from mysql_conjuncts.doris_test.text_push 
where pk <=7;"""
 
+        // test create table as select
+        sql """use internal.${internal_db_name}"""
+        sql """drop table if exists ctas_partition_text_1"""
+        sql """drop table if exists ctas_partition_text_2"""
+        sql """drop table if exists ctas_partition_text_3"""
+        sql """drop table if exists ctas_partition_text_4"""
+        sql """set enable_nereids_planner=true"""
+        // 1. test text type column as distribution col
+        sql """create table ctas_partition_text_1 distributed by hash(text) 
buckets 1 properties("replication_num" = "1") as select int_u, text, text as t2 
from mysql_conjuncts.doris_test.all_types;"""
+        qt_sql """desc ctas_partition_text_1"""
+        // 2. test varchar type column as first col
+        sql """create table ctas_partition_text_2 distributed by hash(int_u) 
buckets 1 properties("replication_num" = "1") as select varchar, int_u from 
mysql_conjuncts.doris_test.all_types;"""
+        qt_sql """desc ctas_partition_text_2"""
+        // ctas logic is different between new and old planner.
+        // so need to test both.
+        // the old planner's test can be removed once the old planner is 
removed.
+        sql """set enable_nereids_planner=false"""
+        // 1. test text type column as distribution col
+        sql """create table ctas_partition_text_3 distributed by hash(text) 
buckets 1 properties("replication_num" = "1") as select int_u, text, text as t2 
from mysql_conjuncts.doris_test.all_types;"""
+        qt_sql """desc ctas_partition_text_3"""
+        // 2. test varchar type column as first col
+        sql """create table ctas_partition_text_4 distributed by hash(int_u) 
buckets 1 properties("replication_num" = "1") as select varchar, int_u from 
mysql_conjuncts.doris_test.all_types;"""
+        qt_sql """desc ctas_partition_text_4"""
+
         sql """drop catalog if exists mysql_conjuncts;"""
     }
 }


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

Reply via email to