mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-05 21:02:58 +00:00
feat: improve error message for typo in IF NOT EXISTS (#3817)
* refactor: improve error message for typo in IF NOT EXISTS Signed-off-by: tison <wander4096@gmail.com> * support table name 'if' Signed-off-by: tison <wander4096@gmail.com> * add sqlness cases Signed-off-by: tison <wander4096@gmail.com> --------- Signed-off-by: tison <wander4096@gmail.com>
This commit is contained in:
@@ -28,7 +28,7 @@ use table::requests::validate_table_option;
|
||||
use crate::ast::{ColumnDef, Ident, TableConstraint};
|
||||
use crate::error::{
|
||||
self, InvalidColumnOptionSnafu, InvalidTableOptionSnafu, InvalidTimeIndexSnafu,
|
||||
MissingTimeIndexSnafu, Result, SyntaxSnafu,
|
||||
MissingTimeIndexSnafu, Result, SyntaxSnafu, UnexpectedSnafu, UnsupportedSnafu,
|
||||
};
|
||||
use crate::parser::ParserContext;
|
||||
use crate::statements::create::{
|
||||
@@ -63,9 +63,7 @@ impl<'a> ParserContext<'a> {
|
||||
self.parser
|
||||
.expect_keyword(Keyword::TABLE)
|
||||
.context(SyntaxSnafu)?;
|
||||
let if_not_exists =
|
||||
self.parser
|
||||
.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
|
||||
let if_not_exists = self.parse_if_not_exist()?;
|
||||
let table_name = self.intern_parse_table_name()?;
|
||||
let (columns, constraints) = self.parse_columns()?;
|
||||
if !columns.is_empty() {
|
||||
@@ -86,11 +84,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
fn parse_create_database(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
|
||||
let if_not_exists =
|
||||
self.parser
|
||||
.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
|
||||
|
||||
let if_not_exists = self.parse_if_not_exist()?;
|
||||
let database_name = self.parse_object_name().context(error::UnexpectedSnafu {
|
||||
sql: self.sql,
|
||||
expected: "a database name",
|
||||
@@ -105,9 +99,8 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
fn parse_create_table(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
let if_not_exists =
|
||||
self.parser
|
||||
.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
|
||||
|
||||
let if_not_exists = self.parse_if_not_exist()?;
|
||||
|
||||
let table_name = self.intern_parse_table_name()?;
|
||||
|
||||
@@ -144,6 +137,35 @@ impl<'a> ParserContext<'a> {
|
||||
Ok(Statement::CreateTable(create_table))
|
||||
}
|
||||
|
||||
fn parse_if_not_exist(&mut self) -> Result<bool> {
|
||||
match self.parser.peek_token().token {
|
||||
Token::Word(w) if Keyword::IF != w.keyword => return Ok(false),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.parser.parse_keywords(&[Keyword::IF, Keyword::NOT]) {
|
||||
return self
|
||||
.parser
|
||||
.expect_keyword(Keyword::EXISTS)
|
||||
.map(|_| true)
|
||||
.context(UnexpectedSnafu {
|
||||
sql: self.sql,
|
||||
expected: "EXISTS",
|
||||
actual: self.peek_token_as_string(),
|
||||
});
|
||||
}
|
||||
|
||||
if self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]) {
|
||||
return UnsupportedSnafu {
|
||||
sql: self.sql,
|
||||
keyword: "EXISTS",
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn parse_create_table_options(&mut self) -> Result<OptionMap> {
|
||||
let options = self
|
||||
.parser
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE IF NOT EXIST t();
|
||||
|
||||
Error: 2000(InvalidSyntax), Unexpected token while parsing SQL statement: CREATE TABLE IF NOT EXIST t();, expected: 'EXISTS', found: EXIST: sql parser error: Expected EXISTS, found: EXIST at Line: 1, Column 21
|
||||
|
||||
CREATE TABLE IF NOT t();
|
||||
|
||||
Error: 2000(InvalidSyntax), Unexpected token while parsing SQL statement: CREATE TABLE IF NOT t();, expected: 'EXISTS', found: t: sql parser error: Expected EXISTS, found: t at Line: 1, Column 21
|
||||
|
||||
CREATE TABLE IF EXISTS t();
|
||||
|
||||
Error: 1001(Unsupported), SQL statement is not supported: CREATE TABLE IF EXISTS t();, keyword: EXISTS
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t();
|
||||
|
||||
Error: 2000(InvalidSyntax), Missing time index constraint
|
||||
|
||||
CREATE TABLE t();
|
||||
|
||||
Error: 2000(InvalidSyntax), Missing time index constraint
|
||||
|
||||
CREATE TABLE t(ts TIMESTAMP TIME INDEX);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
CREATE TABLE IF();
|
||||
|
||||
Error: 2000(InvalidSyntax), Missing time index constraint
|
||||
|
||||
CREATE TABLE IF(ts TIMESTAMP TIME INDEX);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
DROP TABLE t;
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
DROP TABLE IF;
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE IF NOT EXIST t();
|
||||
|
||||
CREATE TABLE IF NOT t();
|
||||
|
||||
CREATE TABLE IF EXISTS t();
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t();
|
||||
|
||||
CREATE TABLE t();
|
||||
|
||||
CREATE TABLE t(ts TIMESTAMP TIME INDEX);
|
||||
|
||||
CREATE TABLE IF();
|
||||
|
||||
CREATE TABLE IF(ts TIMESTAMP TIME INDEX);
|
||||
|
||||
DROP TABLE t;
|
||||
|
||||
DROP TABLE IF;
|
||||
Reference in New Issue
Block a user