Skip to content

Commit 7969d36

Browse files
authored
fix(query): RawValueSource::parse_fallback fully parse input (#17340)
* test * update * fix test * fix * add test
1 parent f6c0c63 commit 7969d36

File tree

8 files changed

+139
-47
lines changed

8 files changed

+139
-47
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/query/formats/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ base64 = { workspace = true }
2929
bstr = { workspace = true }
3030
chrono-tz = { workspace = true }
3131
geozero = { workspace = true }
32+
goldenfile = { workspace = true }
3233
hex = { workspace = true }
3334
jiff = { workspace = true }
3435
jsonb = { workspace = true }

src/query/formats/tests/it/field_decoder/fast_values.rs

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::io::Write;
16+
1517
use databend_common_exception::ErrorCode;
1618
use databend_common_exception::Result;
1719
use databend_common_expression::types::DataType;
@@ -23,6 +25,7 @@ use databend_common_formats::FastFieldDecoderValues;
2325
use databend_common_formats::FastValuesDecodeFallback;
2426
use databend_common_formats::FastValuesDecoder;
2527
use databend_common_io::prelude::FormatSettings;
28+
use goldenfile::Mint;
2629

2730
struct DummyFastValuesDecodeFallback {}
2831

@@ -35,23 +38,22 @@ impl FastValuesDecodeFallback for DummyFastValuesDecodeFallback {
3538

3639
#[tokio::test]
3740
async fn test_fast_values_decoder_multi() -> Result<()> {
41+
let mut mint = Mint::new("tests/it/testdata");
42+
let file = &mut mint.new_goldenfile("fast_values.txt").unwrap();
43+
3844
struct Test {
3945
data: &'static str,
4046
column_types: Vec<DataType>,
41-
output: Result<&'static str>,
4247
}
4348

44-
let tests = vec![
49+
let cases = vec![
4550
Test {
4651
data: "(0, 1, 2), (3,4,5)",
4752
column_types: vec![
4853
DataType::Number(NumberDataType::Int16),
4954
DataType::Number(NumberDataType::Int16),
5055
DataType::Number(NumberDataType::Int16),
5156
],
52-
output: Ok(
53-
"+----------+----------+----------+\n| Column 0 | Column 1 | Column 2 |\n+----------+----------+----------+\n| 0 | 1 | 2 |\n| 3 | 4 | 5 |\n+----------+----------+----------+",
54-
),
5557
},
5658
Test {
5759
data: "(0, 1, 2), (3,4,5), ",
@@ -60,9 +62,6 @@ async fn test_fast_values_decoder_multi() -> Result<()> {
6062
DataType::Number(NumberDataType::Int16),
6163
DataType::Number(NumberDataType::Int16),
6264
],
63-
output: Err(ErrorCode::BadDataValueType(
64-
"Must start with parentheses".to_string(),
65-
)),
6665
},
6766
Test {
6867
data: "('', '', '')",
@@ -71,7 +70,6 @@ async fn test_fast_values_decoder_multi() -> Result<()> {
7170
DataType::Number(NumberDataType::Int16),
7271
DataType::Number(NumberDataType::Int16),
7372
],
74-
output: Err(ErrorCode::Unimplemented("fallback".to_string())),
7573
},
7674
Test {
7775
data: "( 1, '', '2022-10-01')",
@@ -80,9 +78,6 @@ async fn test_fast_values_decoder_multi() -> Result<()> {
8078
DataType::String,
8179
DataType::Date,
8280
],
83-
output: Ok(
84-
"+----------+----------+--------------+\n| Column 0 | Column 1 | Column 2 |\n+----------+----------+--------------+\n| 1 | '' | '2022-10-01' |\n+----------+----------+--------------+",
85-
),
8681
},
8782
Test {
8883
data: "(1, 2, 3), (1, 1, 1), (1, 1, 1);",
@@ -91,9 +86,6 @@ async fn test_fast_values_decoder_multi() -> Result<()> {
9186
DataType::Number(NumberDataType::Int16),
9287
DataType::Number(NumberDataType::Int16),
9388
],
94-
output: Ok(
95-
"+----------+----------+----------+\n| Column 0 | Column 1 | Column 2 |\n+----------+----------+----------+\n| 1 | 2 | 3 |\n| 1 | 1 | 1 |\n| 1 | 1 | 1 |\n+----------+----------+----------+",
96-
),
9789
},
9890
Test {
9991
data: "(1, 2, 3), (1, 1, 1), (1, 1, 1); ",
@@ -102,9 +94,6 @@ async fn test_fast_values_decoder_multi() -> Result<()> {
10294
DataType::Number(NumberDataType::Int16),
10395
DataType::Number(NumberDataType::Int16),
10496
],
105-
output: Ok(
106-
"+----------+----------+----------+\n| Column 0 | Column 1 | Column 2 |\n+----------+----------+----------+\n| 1 | 2 | 3 |\n| 1 | 1 | 1 |\n| 1 | 1 | 1 |\n+----------+----------+----------+",
107-
),
10897
},
10998
Test {
11099
data: "(1.2, -2.9, 3.55), (3.12e2, 3.45e+3, -1.9e-3);",
@@ -113,35 +102,38 @@ async fn test_fast_values_decoder_multi() -> Result<()> {
113102
DataType::Number(NumberDataType::Int16),
114103
DataType::Number(NumberDataType::Int16),
115104
],
116-
output: Ok(
117-
"+----------+----------+----------+\n| Column 0 | Column 1 | Column 2 |\n+----------+----------+----------+\n| 1 | -3 | 4 |\n| 312 | 3450 | 0 |\n+----------+----------+----------+",
118-
),
119105
},
120106
];
121107

122-
for tt in tests {
108+
for case in cases {
109+
writeln!(file, "---------- Input Data ----------")?;
110+
writeln!(file, "{:?}", case.data)?;
111+
112+
writeln!(file, "---------- Input Column Types ----------")?;
113+
writeln!(file, "{:?}", case.column_types)?;
114+
123115
let field_decoder =
124116
FastFieldDecoderValues::create_for_insert(FormatSettings::default(), true);
125-
let mut values_decoder = FastValuesDecoder::new(tt.data, &field_decoder);
117+
let mut values_decoder = FastValuesDecoder::new(case.data, &field_decoder);
126118
let fallback = DummyFastValuesDecodeFallback {};
127-
let mut columns = tt
119+
let mut columns = case
128120
.column_types
129121
.into_iter()
130122
.map(|dt| ColumnBuilder::with_capacity(&dt, values_decoder.estimated_rows()))
131123
.collect::<Vec<_>>();
132124
let result = values_decoder.parse(&mut columns, &fallback).await;
133-
match tt.output {
134-
Err(err) => {
135-
assert!(result.is_err());
136-
assert_eq!(err.to_string(), result.unwrap_err().to_string())
137-
}
138-
Ok(want) => {
139-
let columns = columns.into_iter().map(|cb| cb.build()).collect::<Vec<_>>();
140-
let got = DataBlock::new_from_columns(columns);
141-
assert!(result.is_ok(), "{:?}", result);
142-
assert_eq!(got.to_string(), want.to_string())
143-
}
125+
126+
writeln!(file, "---------- Output ---------")?;
127+
128+
if let Err(err) = result {
129+
writeln!(file, "{}", err)?;
130+
} else {
131+
let columns = columns.into_iter().map(|cb| cb.build()).collect::<Vec<_>>();
132+
let got = DataBlock::new_from_columns(columns);
133+
writeln!(file, "{}", got)?;
144134
}
135+
writeln!(file, "\n")?;
145136
}
137+
146138
Ok(())
147139
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---------- Input Data ----------
2+
"(0, 1, 2), (3,4,5)"
3+
---------- Input Column Types ----------
4+
[Number(Int16), Number(Int16), Number(Int16)]
5+
---------- Output ---------
6+
+----------+----------+----------+
7+
| Column 0 | Column 1 | Column 2 |
8+
+----------+----------+----------+
9+
| 0 | 1 | 2 |
10+
| 3 | 4 | 5 |
11+
+----------+----------+----------+
12+
13+
14+
---------- Input Data ----------
15+
"(0, 1, 2), (3,4,5), "
16+
---------- Input Column Types ----------
17+
[Number(Int16), Number(Int16), Number(Int16)]
18+
---------- Output ---------
19+
BadDataValueType. Code: 1010, Text = Must start with parentheses.
20+
21+
22+
---------- Input Data ----------
23+
"('', '', '')"
24+
---------- Input Column Types ----------
25+
[Number(Int16), Number(Int16), Number(Int16)]
26+
---------- Output ---------
27+
Unimplemented. Code: 1002, Text = fallback.
28+
29+
30+
---------- Input Data ----------
31+
"( 1, '', '2022-10-01')"
32+
---------- Input Column Types ----------
33+
[Number(Int16), String, Date]
34+
---------- Output ---------
35+
+----------+----------+--------------+
36+
| Column 0 | Column 1 | Column 2 |
37+
+----------+----------+--------------+
38+
| 1 | '' | '2022-10-01' |
39+
+----------+----------+--------------+
40+
41+
42+
---------- Input Data ----------
43+
"(1, 2, 3), (1, 1, 1), (1, 1, 1);"
44+
---------- Input Column Types ----------
45+
[Number(Int16), Number(Int16), Number(Int16)]
46+
---------- Output ---------
47+
+----------+----------+----------+
48+
| Column 0 | Column 1 | Column 2 |
49+
+----------+----------+----------+
50+
| 1 | 2 | 3 |
51+
| 1 | 1 | 1 |
52+
| 1 | 1 | 1 |
53+
+----------+----------+----------+
54+
55+
56+
---------- Input Data ----------
57+
"(1, 2, 3), (1, 1, 1), (1, 1, 1); "
58+
---------- Input Column Types ----------
59+
[Number(Int16), Number(Int16), Number(Int16)]
60+
---------- Output ---------
61+
+----------+----------+----------+
62+
| Column 0 | Column 1 | Column 2 |
63+
+----------+----------+----------+
64+
| 1 | 2 | 3 |
65+
| 1 | 1 | 1 |
66+
| 1 | 1 | 1 |
67+
+----------+----------+----------+
68+
69+
70+
---------- Input Data ----------
71+
"(1.2, -2.9, 3.55), (3.12e2, 3.45e+3, -1.9e-3);"
72+
---------- Input Column Types ----------
73+
[Number(Int16), Number(Int16), Number(Int16)]
74+
---------- Output ---------
75+
+----------+----------+----------+
76+
| Column 0 | Column 1 | Column 2 |
77+
+----------+----------+----------+
78+
| 1 | -3 | 4 |
79+
| 312 | 3450 | 0 |
80+
+----------+----------+----------+
81+
82+

src/query/service/src/pipelines/builders/builder_replace_into.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
use std::sync::Arc;
1616

17-
use databend_common_ast::parser::parse_comma_separated_exprs;
17+
use databend_common_ast::parser::parse_values_with_placeholder;
1818
use databend_common_ast::parser::tokenize_sql;
1919
use databend_common_base::base::tokio::sync::Semaphore;
2020
use databend_common_catalog::table::Table;
@@ -488,12 +488,12 @@ impl AsyncSource for RawValueSource {
488488
}
489489

490490
let format = self.ctx.get_format_settings()?;
491-
let numeric_cast_option = self
491+
let rounding_mode = self
492492
.ctx
493493
.get_settings()
494494
.get_numeric_cast_option()
495-
.unwrap_or("rounding".to_string());
496-
let rounding_mode = numeric_cast_option.as_str() == "rounding";
495+
.map(|s| s == "rounding")
496+
.unwrap_or(true);
497497
let field_decoder = FastFieldDecoderValues::create_for_insert(format, rounding_mode);
498498

499499
let mut values_decoder = FastValuesDecoder::new(&self.data, &field_decoder);
@@ -528,7 +528,13 @@ impl FastValuesDecodeFallback for RawValueSource {
528528
let mut bind_context = self.bind_context.clone();
529529
let metadata = self.metadata.clone();
530530

531-
let exprs = parse_comma_separated_exprs(&tokens[1..tokens.len()], sql_dialect)?;
531+
let exprs = parse_values_with_placeholder(&tokens, sql_dialect)?
532+
.into_iter()
533+
.map(|expr| match expr {
534+
Some(expr) => Ok(expr),
535+
None => Err(ErrorCode::SyntaxException("unexpected placeholder")),
536+
})
537+
.collect::<Result<Vec<_>>>()?;
532538

533539
bind_context
534540
.exprs_to_scalar(

tests/sqllogictests/suites/base/03_common/03_0016_insert_into_values.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ INSERT INTO t_str(a) values( 'a"b\"c\'d')
4646
statement ok
4747
INSERT INTO t_str(a) values( 'a"b\"c\\\'d')
4848

49+
statement error (?s)1005
50+
INSERT INTO t_str values('aaa','bbb'''sssd...);
51+
4952
onlyif mysql
5053
query T
5154
select * from t_str order by a
@@ -113,6 +116,13 @@ select max(column1), max(column2), max(column3), count() from my_table
113116
----
114117
value9_1 value9_2 value9_3 32
115118

119+
statement error (?s)1005(.*)unexpected `AS`
120+
INSERT INTO my_table (column1, column2, column3) VALUES (
121+
Rand() AS string, -- c24
122+
Rand() AS string, -- c25
123+
Rand() AS string -- c26
124+
);
125+
116126
statement ok
117127
drop table my_table
118128

tests/sqllogictests/suites/base/03_common/03_0027_insert_default.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ INSERT INTO t0(c2varchar, c1varchar) VALUES ('diu7Pk', '')
7676
statement error 1065
7777
INSERT INTO t0(c2varchar) VALUES (max('1'))
7878

79-
statement error 1065
79+
statement error 1005
8080
INSERT INTO t0(c2varchar) VALUES (max('1') partition by('1'))
8181

8282
statement error 1065

tests/sqllogictests/suites/base/11_data_type/11_0006_data_type_decimal.test

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ select count(*) from t_decimal_4_2;
522522
----
523523
0
524524

525-
statement error 1303
525+
statement error 1005
526526
insert into t_decimal_4_2 values (.);
527527

528528
statement ok
@@ -533,7 +533,7 @@ select count(*) from t_decimal_4_2;
533533
----
534534
0
535535

536-
statement error 1303
536+
statement error 1005
537537
insert into t_decimal_4_2 values (+);
538538

539539
statement ok
@@ -544,7 +544,7 @@ select count(*) from t_decimal_4_2;
544544
----
545545
0
546546

547-
statement error 1303
547+
statement error 1005
548548
insert into t_decimal_4_2 values (-);
549549

550550
statement ok
@@ -708,13 +708,13 @@ create table t_decimal_76_2(a Decimal(76,2) not null);
708708
statement error 1065
709709
insert into t_decimal_76_2 values (1.1.1);
710710

711-
statement error 1303
711+
statement error 1005
712712
insert into t_decimal_76_2 values (.);
713713

714-
statement error 1303
714+
statement error 1005
715715
insert into t_decimal_76_2 values (+);
716716

717-
statement error 1303
717+
statement error 1005
718718
insert into t_decimal_76_2 values (-);
719719

720720
statement error 1303

0 commit comments

Comments
 (0)