mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-29 15:06:59 +00:00
fix!: not allowed to create column name same with keyword without quoted (#1333)
* fix: not allowed to create column name same with keyword without quoted * fix: tests * Update src/sql/src/parsers/create_parser.rs Co-authored-by: Ning Sun <classicning@gmail.com> * fix: tests --------- Co-authored-by: Ning Sun <classicning@gmail.com>
This commit is contained in:
@@ -349,7 +349,12 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_table_with_options() {
|
||||
let sql = r#"CREATE TABLE demo_table (timestamp BIGINT TIME INDEX, value DOUBLE, host STRING PRIMARY KEY) engine=mito with(regions=1, ttl='7days',write_buffer_size='32MB',some='other');"#;
|
||||
let sql = r#"
|
||||
CREATE TABLE demo_table (
|
||||
"timestamp" BIGINT TIME INDEX,
|
||||
"value" DOUBLE,
|
||||
host STRING PRIMARY KEY
|
||||
) engine=mito with(regions=1, ttl='7days',write_buffer_size='32MB',some='other');"#;
|
||||
let parsed_stmt = sql_to_statement(sql);
|
||||
let handler = create_mock_sql_handler().await;
|
||||
let c = handler
|
||||
@@ -368,7 +373,12 @@ mod tests {
|
||||
pub async fn test_create_with_inline_primary_key() {
|
||||
let handler = create_mock_sql_handler().await;
|
||||
let parsed_stmt = sql_to_statement(
|
||||
r#"CREATE TABLE demo_table (timestamp BIGINT TIME INDEX, value DOUBLE, host STRING PRIMARY KEY) engine=mito with(regions=1);"#,
|
||||
r#"
|
||||
CREATE TABLE demo_table(
|
||||
"timestamp" BIGINT TIME INDEX,
|
||||
"value" DOUBLE,
|
||||
host STRING PRIMARY KEY
|
||||
) engine=mito with(regions=1);"#,
|
||||
);
|
||||
let c = handler
|
||||
.create_to_request(42, parsed_stmt, &TableReference::bare("demo_table"))
|
||||
@@ -407,8 +417,8 @@ mod tests {
|
||||
let handler = create_mock_sql_handler().await;
|
||||
let parsed_stmt = sql_to_statement(
|
||||
r#"create table demo_table (
|
||||
timestamp BIGINT TIME INDEX,
|
||||
value DOUBLE,
|
||||
"timestamp" BIGINT TIME INDEX,
|
||||
"value" DOUBLE,
|
||||
host STRING PRIMARY KEY,
|
||||
PRIMARY KEY(host)) engine=mito with(regions=1);"#,
|
||||
);
|
||||
@@ -423,8 +433,8 @@ mod tests {
|
||||
let handler = create_mock_sql_handler().await;
|
||||
let parsed_stmt = sql_to_statement(
|
||||
r#"create table demo_table (
|
||||
timestamp BIGINT TIME INDEX,
|
||||
value DOUBLE PRIMARY KEY,
|
||||
"timestamp" BIGINT TIME INDEX,
|
||||
"value" DOUBLE PRIMARY KEY,
|
||||
host STRING PRIMARY KEY) engine=mito with(regions=1);"#,
|
||||
);
|
||||
let error = handler
|
||||
|
||||
@@ -176,8 +176,8 @@ async fn sql_insert_promql_query_ceil(instance: Arc<dyn MockInstance>) {
|
||||
const AGGREGATORS_CREATE_TABLE: &str = r#"create table http_requests (
|
||||
job string,
|
||||
instance string,
|
||||
group string,
|
||||
value double,
|
||||
"group" string,
|
||||
"value" double,
|
||||
ts timestamp TIME INDEX,
|
||||
PRIMARY KEY (job, instance, group),
|
||||
);"#;
|
||||
|
||||
@@ -20,6 +20,7 @@ use once_cell::sync::Lazy;
|
||||
use snafu::{ensure, OptionExt, ResultExt};
|
||||
use sqlparser::ast::{ColumnOption, ColumnOptionDef, DataType, Value};
|
||||
use sqlparser::dialect::keywords::Keyword;
|
||||
use sqlparser::keywords::ALL_KEYWORDS;
|
||||
use sqlparser::parser::IsOptional::Mandatory;
|
||||
use sqlparser::parser::{Parser, ParserError};
|
||||
use sqlparser::tokenizer::{Token, TokenWithLocation, Word};
|
||||
@@ -386,6 +387,16 @@ impl<'a> ParserContext<'a> {
|
||||
let parser = &mut self.parser;
|
||||
|
||||
let name = parser.parse_identifier()?;
|
||||
if name.quote_style.is_none() &&
|
||||
// "ALL_KEYWORDS" are sorted.
|
||||
ALL_KEYWORDS.binary_search(&name.value.to_uppercase().as_str()).is_ok()
|
||||
{
|
||||
return Err(ParserError::ParserError(format!(
|
||||
"Cannot use keyword '{}' as column name. Hint: add quotes to the name.",
|
||||
&name.value
|
||||
)));
|
||||
}
|
||||
|
||||
let data_type = parser.parse_data_type()?;
|
||||
let collation = if parser.parse_keyword(Keyword::COLLATE) {
|
||||
Some(parser.parse_object_name()?)
|
||||
@@ -1441,4 +1452,21 @@ ENGINE=mito";
|
||||
assert!(result.is_err());
|
||||
assert_matches!(result, Err(crate::error::Error::InvalidTimeIndex { .. }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_column_name() {
|
||||
let sql = "create table foo(user string, i bigint time index)";
|
||||
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("Cannot use keyword 'user' as column name"));
|
||||
|
||||
// If column name is quoted, it's valid even same with keyword.
|
||||
let sql = r#"
|
||||
create table foo("user" string, i bigint time index)
|
||||
"#;
|
||||
let result = ParserContext::create_with_dialect(sql, &GenericDialect {});
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ DROP TABLE test2;
|
||||
|
||||
Affected Rows: 1
|
||||
|
||||
CREATE TABLE test_pk (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE);
|
||||
CREATE TABLE test_pk ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
@@ -106,15 +106,15 @@ DROP TABLE test_pk;
|
||||
|
||||
Affected Rows: 1
|
||||
|
||||
CREATE TABLE test_multiple_pk_definitions (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE, PRIMARY KEY(host));
|
||||
CREATE TABLE test_multiple_pk_definitions ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE, PRIMARY KEY(host));
|
||||
|
||||
Error: 1004(InvalidArguments), Illegal primary keys definition: found definitions of primary keys in multiple places
|
||||
|
||||
CREATE TABLE test_multiple_pk_definitions (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE, PRIMARY KEY(host), PRIMARY KEY(host));
|
||||
CREATE TABLE test_multiple_pk_definitions ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE, PRIMARY KEY(host), PRIMARY KEY(host));
|
||||
|
||||
Error: 1004(InvalidArguments), Illegal primary keys definition: found definitions of primary keys in multiple places
|
||||
|
||||
CREATE TABLE test_multiple_inline_pk_definitions (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE PRIMARY KEY);
|
||||
CREATE TABLE test_multiple_inline_pk_definitions ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE PRIMARY KEY);
|
||||
|
||||
Error: 1004(InvalidArguments), Illegal primary keys definition: not allowed to inline multiple primary keys in columns options
|
||||
|
||||
|
||||
@@ -36,15 +36,15 @@ DROP TABLE test1;
|
||||
|
||||
DROP TABLE test2;
|
||||
|
||||
CREATE TABLE test_pk (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE);
|
||||
CREATE TABLE test_pk ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE);
|
||||
|
||||
DESC TABLE test_pk;
|
||||
|
||||
DROP TABLE test_pk;
|
||||
|
||||
CREATE TABLE test_multiple_pk_definitions (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE, PRIMARY KEY(host));
|
||||
CREATE TABLE test_multiple_pk_definitions ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE, PRIMARY KEY(host));
|
||||
|
||||
CREATE TABLE test_multiple_pk_definitions (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE, PRIMARY KEY(host), PRIMARY KEY(host));
|
||||
CREATE TABLE test_multiple_pk_definitions ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE, PRIMARY KEY(host), PRIMARY KEY(host));
|
||||
|
||||
CREATE TABLE test_multiple_inline_pk_definitions (timestamp BIGINT TIME INDEX, host STRING PRIMARY KEY, value DOUBLE PRIMARY KEY);
|
||||
CREATE TABLE test_multiple_inline_pk_definitions ("timestamp" BIGINT TIME INDEX, host STRING PRIMARY KEY, "value" DOUBLE PRIMARY KEY);
|
||||
|
||||
|
||||
@@ -352,8 +352,8 @@ CREATE TABLE DirectReports
|
||||
Name varchar NOT NULL,
|
||||
Title varchar NOT NULL,
|
||||
EmployeeLevel int NOT NULL,
|
||||
Sort varchar NOT NULL,
|
||||
Timestamp BIGINT TIME INDEX,
|
||||
"Sort" varchar NOT NULL,
|
||||
"Timestamp" BIGINT TIME INDEX,
|
||||
);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
@@ -87,8 +87,8 @@ CREATE TABLE DirectReports
|
||||
Name varchar NOT NULL,
|
||||
Title varchar NOT NULL,
|
||||
EmployeeLevel int NOT NULL,
|
||||
Sort varchar NOT NULL,
|
||||
Timestamp BIGINT TIME INDEX,
|
||||
"Sort" varchar NOT NULL,
|
||||
"Timestamp" BIGINT TIME INDEX,
|
||||
);
|
||||
|
||||
INSERT INTO DirectReports VALUES
|
||||
|
||||
Reference in New Issue
Block a user