Skip to content

Commit 4e894ae

Browse files
authored
fix(query): tuple field name can not contain special char (#15126)
1 parent 3f47a2a commit 4e894ae

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

src/query/ast/src/parser/expr.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,15 +1611,23 @@ pub fn type_name(i: Input) -> IResult<TypeName> {
16111611
fields_type,
16121612
},
16131613
);
1614-
let ty_named_tuple = map(
1614+
let ty_named_tuple = map_res(
16151615
rule! { TUPLE ~ "(" ~ #comma_separated_list1(rule! { #ident ~ #type_name }) ~ ")" },
16161616
|(_, _, fields, _)| {
1617-
let (fields_name, fields_type) =
1617+
let (fields_name, fields_type): (Vec<String>, Vec<TypeName>) =
16181618
fields.into_iter().map(|(name, ty)| (name.name, ty)).unzip();
1619-
TypeName::Tuple {
1619+
if fields_name
1620+
.iter()
1621+
.any(|field_name| !field_name.chars().all(|c| c.is_ascii_alphanumeric()))
1622+
{
1623+
return Err(nom::Err::Error(ErrorKind::Other(
1624+
"Invalid tuple field name, only support alphanumeric characters",
1625+
)));
1626+
}
1627+
Ok(TypeName::Tuple {
16201628
fields_name: Some(fields_name),
16211629
fields_type,
1622-
}
1630+
})
16231631
},
16241632
);
16251633
let ty_date = value(TypeName::Date, rule! { DATE });

src/query/ast/tests/it/parser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ fn test_statement_error() {
699699
r#"create table a (c tuple())"#,
700700
r#"create table a (c decimal)"#,
701701
r#"create table a (b tuple(c int, uint64));"#,
702+
r#"create table a (b tuple("c-1" int, "c-2" uint64));"#,
702703
r#"CREATE TABLE t(c1 NULLABLE(int) NOT NULL);"#,
703704
r#"drop table if a.b"#,
704705
r#"truncate table a.b.c.d"#,

src/query/ast/tests/it/testdata/statement-error.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ error:
7878
| while parsing `CREATE [OR REPLACE] TABLE [IF NOT EXISTS] [<database>.]<table> [<source>] [<table_options>]`
7979

8080

81+
---------- Input ----------
82+
create table a (b tuple("c-1" int, "c-2" uint64));
83+
---------- Output ---------
84+
error:
85+
--> SQL:1:48
86+
|
87+
1 | create table a (b tuple("c-1" int, "c-2" uint64));
88+
| ------ - ----- ^ unexpected `)`, expecting `BOOLEAN`, `BOOL`, `UINT8`, `TINYINT`, `UINT16`, `SMALLINT`, `UINT32`, `INT`, `INTEGER`, `UINT64`, `UNSIGNED`, `BIGINT`, `INT8`, `INT16`, `INT32`, `INT64`, `SIGNED`, `FLOAT32`, `FLOAT`, `FLOAT64`, `DOUBLE`, `DECIMAL`, `ARRAY`, `MAP`, `BITMAP`, `TUPLE`, `DATE`, `DATETIME`, `TIMESTAMP`, `BINARY`, `VARBINARY`, `LONGBLOB`, `MEDIUMBLOB`, `TINYBLOB`, `BLOB`, `STRING`, `VARCHAR`, `CHAR`, `CHARACTER`, `TEXT`, `VARIANT`, `JSON`, `GEOMETRY`, `NULLABLE`, `(`, `NULL`, `NOT`, or `,`
89+
| | | |
90+
| | | while parsing TUPLE(<type>, ...)
91+
| | | while parsing type name
92+
| | while parsing `<column name> <type> [DEFAULT <expr>] [AS (<expr>) VIRTUAL] [AS (<expr>) STORED] [COMMENT '<comment>']`
93+
| while parsing `CREATE [OR REPLACE] TABLE [IF NOT EXISTS] [<database>.]<table> [<source>] [<table_options>]`
94+
95+
8196
---------- Input ----------
8297
CREATE TABLE t(c1 NULLABLE(int) NOT NULL);
8398
---------- Output ---------

0 commit comments

Comments
 (0)