diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java index 760783359d083e..5cd0c1663294ad 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSink.java @@ -252,6 +252,9 @@ private LogicalProject getOutputProjectByCoercion(List tableSchema, L // add cast project List castExprs = Lists.newArrayList(); + ConnectContext connCtx = ConnectContext.get(); + final boolean truncateString = needTruncateStringWhenInsert + && (connCtx == null || connCtx.getSessionVariable().enableInsertValueAutoCast); for (int i = 0; i < tableSchema.size(); ++i) { Column col = tableSchema.get(i); NamedExpression expr = columnToOutput.get(col.getName()); @@ -271,7 +274,7 @@ private LogicalProject getOutputProjectByCoercion(List tableSchema, L int targetLength = ((CharacterType) targetType).getLen(); if (sourceLength == targetLength) { castExpr = TypeCoercionUtils.castIfNotSameType(castExpr, targetType); - } else if (needTruncateStringWhenInsert && sourceLength > targetLength && targetLength >= 0) { + } else if (truncateString && sourceLength > targetLength && targetLength >= 0) { castExpr = new Substring(castExpr, Literal.of(1), Literal.of(targetLength)); } else if (targetType.isStringType()) { castExpr = new Cast(castExpr, StringType.INSTANCE); diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java index 89ec74518f6272..c625573a4abc53 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java @@ -140,6 +140,7 @@ public class SessionVariable implements Serializable, Writable { public static final String MAX_INSTANCE_NUM = "max_instance_num"; public static final String DML_PLAN_RETRY_TIMES = "DML_PLAN_RETRY_TIMES"; public static final String ENABLE_INSERT_STRICT = "enable_insert_strict"; + public static final String ENABLE_INSERT_VALUE_AUTO_CAST = "enable_insert_value_auto_cast"; public static final String INSERT_MAX_FILTER_RATIO = "insert_max_filter_ratio"; public static final String ENABLE_SERVER_SIDE_PREPARED_STATEMENT = "enable_server_side_prepared_statement"; @@ -1064,6 +1065,13 @@ public enum IgnoreSplitType { @VariableMgr.VarAttr(name = ENABLE_INSERT_STRICT, needForward = true) public boolean enableInsertStrict = true; + @VariableMgr.VarAttr(name = ENABLE_INSERT_VALUE_AUTO_CAST, needForward = true, description = { + "INSERT VALUE 语句是否自动类型转换。当前只针对长字符串自动截短。默认开。", + "INSERT VALUE statement whether to automatically type cast. Only use for truncate long string. " + + "ON by default." + }) + public boolean enableInsertValueAutoCast = true; + @VariableMgr.VarAttr(name = INSERT_MAX_FILTER_RATIO, needForward = true) public double insertMaxFilterRatio = 1.0; @@ -3289,6 +3297,10 @@ public void setEnableInsertStrict(boolean enableInsertStrict) { this.enableInsertStrict = enableInsertStrict; } + public boolean getEnableInsertValueAutoCast() { + return enableInsertValueAutoCast; + } + public double getInsertMaxFilterRatio() { return insertMaxFilterRatio; } diff --git a/regression-test/data/nereids_p0/insert_into_table/insert_values.out b/regression-test/data/nereids_p0/insert_into_table/insert_values.out index 62d824e5e6f8cc..59ba6ff19ac53e 100644 --- a/regression-test/data/nereids_p0/insert_into_table/insert_values.out +++ b/regression-test/data/nereids_p0/insert_into_table/insert_values.out @@ -56,5 +56,7 @@ true 10 10000 10000000 92233720368547758 19223372036854775807 3.14159 hello worl 1 2020-02-02 -- !select_test_insert_more_string -- -3 akljalkjbalkjsldkrjewokjf aa +1 ab +2 abcd +5 o diff --git a/regression-test/suites/nereids_p0/insert_into_table/insert_values.groovy b/regression-test/suites/nereids_p0/insert_into_table/insert_values.groovy index d6da58ea4fddad..42aa9bd711118b 100644 --- a/regression-test/suites/nereids_p0/insert_into_table/insert_values.groovy +++ b/regression-test/suites/nereids_p0/insert_into_table/insert_values.groovy @@ -21,8 +21,6 @@ suite('nereids_insert_into_values') { sql 'set enable_nereids_dml=true' sql 'set enable_strict_consistency_dml=true' - sql 'use nereids_insert_into_table_test' - def t1 = 'value_t1' def t2 = 'value_t2' def t3 = 'value_t3' @@ -165,16 +163,32 @@ suite('nereids_insert_into_values') { drop table if exists test_insert_more_string; CREATE TABLE test_insert_more_string ( `r_regionkey` int NULL, - `r_name` varchar(25) NULL, - `r_comment` varchar(152) NULL + `r_name` varchar(4) NULL ) DUPLICATE KEY(`r_regionkey`) DISTRIBUTED BY HASH(`r_regionkey`) BUCKETS 1 PROPERTIES ( "replication_allocation" = "tag.location.default: 1" ); - insert into test_insert_more_string values (3, "akljalkjbalkjsldkrjewokjfalksdjflaksjfdlaskjfalsdkfjalsdfjkasfdl", "aa") """ - qt_select_test_insert_more_string "select * from test_insert_more_string" -} \ No newline at end of file + // shorter varchar is ok + sql "insert into test_insert_more_string values (1, 'ab')" + + // set enable_insert_value_auto_cast = true + // longer varchar will truncate + sql "insert into test_insert_more_string values (2, 'abcdefg')" + + // when disable string auto cast and in insert strict mode, insert will failed + sql 'set enable_insert_value_auto_cast = false' + test { + sql "insert into test_insert_more_string values (3, 'hi'), (4, 'jklmn')" + exception 'Insert has filtered data in strict mode' + } + + // when disable insert strict, the longer varchar row will be filtered, other rows will succ + sql 'set enable_insert_strict = false' + sql "insert into test_insert_more_string values (5, 'o'), (6, 'pqrst')" + + order_qt_select_test_insert_more_string "select * from test_insert_more_string" +}