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 5bf20d7069586b..a2d7decee123f8 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 @@ -239,6 +239,8 @@ private LogicalProject getOutputProjectByCoercion(List tableSchema, L // add cast project List castExprs = Lists.newArrayList(); + ConnectContext connCtx = ConnectContext.get(); + final boolean truncateString = connCtx == null || connCtx.getSessionVariable().enableInsertValueAutoCast; for (int i = 0; i < tableSchema.size(); ++i) { Column col = tableSchema.get(i); NamedExpression expr = columnToOutput.get(col.getName()); @@ -258,7 +260,7 @@ private LogicalProject getOutputProjectByCoercion(List tableSchema, L int targetLength = ((CharacterType) targetType).getLen(); if (sourceLength == targetLength) { castExpr = TypeCoercionUtils.castIfNotSameType(castExpr, targetType); - } else if (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 e05ca844f58960..449ad12f00c151 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 @@ -139,6 +139,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"; @@ -1047,6 +1048,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; @@ -3197,6 +3205,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 36d51ffcb2a6fc..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 @@ -47,8 +47,16 @@ 3 30 3 3 3.0 2000-01-03 5 5 5 5.0 2000-01-05 5 -- !select_all_default -- -true 10 10000 10000000 92233720368547758 19223372036854775807 3.142 hello world, today is 15/06/2023 2023-06-15 2023-06-15T16:10:15 +true 10 10000 10000000 92233720368547758 19223372036854775807 3.14159 hello world, today is 15/06/2023 2023-06-15 2023-06-15T16:10:15 -- !mv -- -4 -4 -4 d +-- !select_test_insert_cast_interval -- +1 2020-02-02 + +-- !select_test_insert_more_string -- +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 84461ca2ba8476..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' @@ -143,4 +141,54 @@ suite('nereids_insert_into_values') { sql "insert into agg_have_dup_base_value values (-4, -4, -4, 'd')" sql "sync" qt_mv "select * from agg_have_dup_base_value" -} \ No newline at end of file + + multi_sql """ + DROP TABLE IF EXISTS test_insert_cast_interval; + CREATE TABLE test_insert_cast_interval ( + `id` int NULL, + `dt` date NULL + ) ENGINE=OLAP + DUPLICATE KEY(`id`, `dt`) + DISTRIBUTED BY HASH(`id`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + + INSERT INTO test_insert_cast_interval values(1, date_floor('2020-02-02', interval 1 second)); + """ + + qt_select_test_insert_cast_interval "select * from test_insert_cast_interval" + + multi_sql """ + drop table if exists test_insert_more_string; + CREATE TABLE test_insert_more_string ( + `r_regionkey` int NULL, + `r_name` varchar(4) NULL + ) + DUPLICATE KEY(`r_regionkey`) + DISTRIBUTED BY HASH(`r_regionkey`) + BUCKETS 1 PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + """ + + // 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" +}