Skip to content

Commit 81b6c50

Browse files
committed
Add the option for the parser to try and parse an expression as identifier if the expression parsing fails
1 parent fad2ddd commit 81b6c50

File tree

8 files changed

+248
-189
lines changed

8 files changed

+248
-189
lines changed

src/ast/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ pub enum Expr {
695695
// https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
696696
format: Option<CastFormat>,
697697
},
698+
/// `DEFAULT` value of a column e.g. INSERT INTO tbl (a, b) VALUES ('foo', DEFAULT)
699+
Default,
698700
/// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'`
699701
AtTimeZone {
700702
timestamp: Box<Expr>,
@@ -1449,6 +1451,7 @@ impl fmt::Display for Expr {
14491451
write!(f, "{expr}::{data_type}")
14501452
}
14511453
},
1454+
Expr::Default => write!(f, "DEFAULT"),
14521455
Expr::Extract {
14531456
field,
14541457
syntax,

src/dialect/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,12 @@ pub trait Dialect: Debug + Any {
675675
fn supports_create_table_select(&self) -> bool {
676676
false
677677
}
678+
679+
/// Returns true if the specified keyword is reserved and cannot be
680+
/// used as an identifier without special handling like quoting.
681+
fn is_reserved_for_identifier(&self, kw: Keyword) -> bool {
682+
keywords::RESERVED_FOR_IDENTIFIER.contains(&kw)
683+
}
678684
}
679685

680686
/// This represents the operators for which precedence must be defined

src/dialect/snowflake.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ use alloc::vec::Vec;
3838
#[cfg(not(feature = "std"))]
3939
use alloc::{format, vec};
4040

41+
use super::keywords::RESERVED_FOR_IDENTIFIER;
42+
4143
/// A [`Dialect`] for [Snowflake](https://www.snowflake.com/)
4244
#[derive(Debug, Default)]
4345
pub struct SnowflakeDialect;
@@ -214,6 +216,16 @@ impl Dialect for SnowflakeDialect {
214216
fn supports_show_like_before_in(&self) -> bool {
215217
true
216218
}
219+
220+
fn is_reserved_for_identifier(&self, kw: Keyword) -> bool {
221+
// Unreserve some keywords that Snowflake accepts as identifiers
222+
// See: https://docs.snowflake.com/en/sql-reference/reserved-keywords
223+
if matches!(kw, Keyword::INTERVAL) {
224+
false
225+
} else {
226+
RESERVED_FOR_IDENTIFIER.contains(&kw)
227+
}
228+
}
217229
}
218230

219231
/// Parse snowflake create table statement.

src/keywords.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,3 +948,13 @@ pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
948948
Keyword::INTO,
949949
Keyword::END,
950950
];
951+
952+
/// Global list of reserved keywords that cannot be parsed as identifiers
953+
/// without special handling like quoting. Parser should call `Dialect::is_reserved_for_identifier`
954+
/// to allow for each dialect to customize the list.
955+
pub const RESERVED_FOR_IDENTIFIER: &[Keyword] = &[
956+
Keyword::EXISTS,
957+
Keyword::INTERVAL,
958+
Keyword::STRUCT,
959+
Keyword::TRIM,
960+
];

src/parser/mod.rs

Lines changed: 208 additions & 167 deletions
Large diffs are not rendered by default.

tests/sqlparser_bigquery.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,10 +1744,7 @@ fn parse_merge() {
17441744
columns: vec![Ident::new("a"), Ident::new("b"),],
17451745
kind: MergeInsertKind::Values(Values {
17461746
explicit_row: false,
1747-
rows: vec![vec![
1748-
Expr::Value(number("1")),
1749-
Expr::Identifier(Ident::new("DEFAULT")),
1750-
]]
1747+
rows: vec![vec![Expr::Value(number("1")), Expr::Default,]]
17511748
})
17521749
})
17531750
},
@@ -1758,10 +1755,7 @@ fn parse_merge() {
17581755
columns: vec![],
17591756
kind: MergeInsertKind::Values(Values {
17601757
explicit_row: false,
1761-
rows: vec![vec![
1762-
Expr::Value(number("1")),
1763-
Expr::Identifier(Ident::new("DEFAULT")),
1764-
]]
1758+
rows: vec![vec![Expr::Value(number("1")), Expr::Default,]]
17651759
})
17661760
})
17671761
},

tests/sqlparser_common.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use sqlparser::dialect::{
3434
GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, PostgreSqlDialect, RedshiftSqlDialect,
3535
SQLiteDialect, SnowflakeDialect,
3636
};
37-
use sqlparser::keywords::ALL_KEYWORDS;
37+
use sqlparser::keywords::{Keyword, ALL_KEYWORDS};
3838
use sqlparser::parser::{Parser, ParserError, ParserOptions};
3939
use sqlparser::tokenizer::Tokenizer;
4040
use test_utils::{
@@ -5097,7 +5097,9 @@ fn parse_interval_dont_require_unit() {
50975097

50985098
#[test]
50995099
fn parse_interval_require_unit() {
5100-
let dialects = all_dialects_where(|d| d.require_interval_qualifier());
5100+
let dialects = all_dialects_where(|d| {
5101+
d.require_interval_qualifier() && d.is_reserved_for_identifier(Keyword::INTERVAL)
5102+
});
51015103

51025104
let sql = "SELECT INTERVAL '1 DAY'";
51035105
let err = dialects.parse_sql_statements(sql).unwrap_err();

tests/sqlparser_postgres.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,10 +1352,7 @@ fn parse_set() {
13521352
local: false,
13531353
hivevar: false,
13541354
variables: OneOrManyWithParens::One(ObjectName(vec![Ident::new("a")])),
1355-
value: vec![Expr::Identifier(Ident {
1356-
value: "DEFAULT".into(),
1357-
quote_style: None
1358-
})],
1355+
value: vec![Expr::Default],
13591356
}
13601357
);
13611358

@@ -4228,10 +4225,7 @@ fn test_simple_postgres_insert_with_alias() {
42284225
body: Box::new(SetExpr::Values(Values {
42294226
explicit_row: false,
42304227
rows: vec![vec![
4231-
Expr::Identifier(Ident {
4232-
value: "DEFAULT".to_string(),
4233-
quote_style: None
4234-
}),
4228+
Expr::Default,
42354229
Expr::Value(Value::Number("123".to_string(), false))
42364230
]]
42374231
})),
@@ -4362,10 +4356,7 @@ fn test_simple_insert_with_quoted_alias() {
43624356
body: Box::new(SetExpr::Values(Values {
43634357
explicit_row: false,
43644358
rows: vec![vec![
4365-
Expr::Identifier(Ident {
4366-
value: "DEFAULT".to_string(),
4367-
quote_style: None
4368-
}),
4359+
Expr::Default,
43694360
Expr::Value(Value::SingleQuotedString("0123".to_string()))
43704361
]]
43714362
})),

0 commit comments

Comments
 (0)