Skip to content

Commit 1c23641

Browse files
committed
WIP: parse true and false as identifiers in mssql
fixes apache#1508
1 parent 334a5bf commit 1c23641

File tree

5 files changed

+41
-7
lines changed

5 files changed

+41
-7
lines changed

src/dialect/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,12 @@ pub trait Dialect: Debug + Any {
606606
fn supports_top_before_distinct(&self) -> bool {
607607
false
608608
}
609+
610+
/// Returns true if the dialect supports boolean literals (`true` and `false`).
611+
/// For example, in MSSQL these are treated as identifiers rather than boolean literals.
612+
fn supports_boolean_literals(&self) -> bool {
613+
true
614+
}
609615
}
610616

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

src/dialect/mssql.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,9 @@ impl Dialect for MsSqlDialect {
5757
fn supports_try_convert(&self) -> bool {
5858
true
5959
}
60+
61+
/// In MSSQL, there is no boolean type, and `true` and `false` are valid column names
62+
fn supports_boolean_literals(&self) -> bool {
63+
false
64+
}
6065
}

src/parser/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,11 @@ impl<'a> Parser<'a> {
10141014
let next_token = self.next_token();
10151015
let expr = match next_token.token {
10161016
Token::Word(w) => match w.keyword {
1017-
Keyword::TRUE | Keyword::FALSE | Keyword::NULL => {
1017+
Keyword::TRUE | Keyword::FALSE if self.dialect.supports_boolean_literals() => {
1018+
self.prev_token();
1019+
Ok(Expr::Value(self.parse_value()?))
1020+
}
1021+
Keyword::NULL => {
10181022
self.prev_token();
10191023
Ok(Expr::Value(self.parse_value()?))
10201024
}
@@ -7571,8 +7575,12 @@ impl<'a> Parser<'a> {
75717575
let location = next_token.location;
75727576
match next_token.token {
75737577
Token::Word(w) => match w.keyword {
7574-
Keyword::TRUE => Ok(Value::Boolean(true)),
7575-
Keyword::FALSE => Ok(Value::Boolean(false)),
7578+
Keyword::TRUE if self.dialect.supports_boolean_literals() => {
7579+
Ok(Value::Boolean(true))
7580+
}
7581+
Keyword::FALSE if self.dialect.supports_boolean_literals() => {
7582+
Ok(Value::Boolean(false))
7583+
}
75767584
Keyword::NULL => Ok(Value::Null),
75777585
Keyword::NoKeyword if w.quote_style.is_some() => match w.quote_style {
75787586
Some('"') => Ok(Value::DoubleQuotedString(w.value)),

tests/sqlparser_common.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7321,15 +7321,18 @@ fn lateral_derived() {
73217321
let lateral_str = if lateral_in { "LATERAL " } else { "" };
73227322
let sql = format!(
73237323
"SELECT * FROM customer LEFT JOIN {lateral_str}\
7324-
(SELECT * FROM order WHERE order.customer = customer.id LIMIT 3) AS order ON true"
7324+
(SELECT * FROM orders WHERE orders.customer = customer.id LIMIT 3) AS orders ON 1"
73257325
);
73267326
let select = verified_only_select(&sql);
73277327
let from = only(select.from);
73287328
assert_eq!(from.joins.len(), 1);
73297329
let join = &from.joins[0];
73307330
assert_eq!(
73317331
join.join_operator,
7332-
JoinOperator::LeftOuter(JoinConstraint::On(Expr::Value(Value::Boolean(true))))
7332+
JoinOperator::LeftOuter(JoinConstraint::On(Expr::Value(Value::Number(
7333+
"1".to_string(),
7334+
false
7335+
))))
73337336
);
73347337
if let TableFactor::Derived {
73357338
lateral,
@@ -7338,10 +7341,10 @@ fn lateral_derived() {
73387341
} = join.relation
73397342
{
73407343
assert_eq!(lateral_in, lateral);
7341-
assert_eq!(Ident::new("order"), alias.name);
7344+
assert_eq!(Ident::new("orders"), alias.name);
73427345
assert_eq!(
73437346
subquery.to_string(),
7344-
"SELECT * FROM order WHERE order.customer = customer.id LIMIT 3"
7347+
"SELECT * FROM orders WHERE orders.customer = customer.id LIMIT 3"
73457348
);
73467349
} else {
73477350
unreachable!()

tests/sqlparser_mssql.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,18 @@ fn parse_create_table_with_identity_column() {
10311031
}
10321032
}
10331033

1034+
#[test]
1035+
fn parse_true_false_as_identifiers() {
1036+
assert_eq!(
1037+
ms().verified_expr("true"),
1038+
Expr::Identifier(Ident::new("true"))
1039+
);
1040+
assert_eq!(
1041+
ms().verified_expr("false"),
1042+
Expr::Identifier(Ident::new("false"))
1043+
);
1044+
}
1045+
10341046
fn ms() -> TestedDialects {
10351047
TestedDialects::new(vec![Box::new(MsSqlDialect {})])
10361048
}

0 commit comments

Comments
 (0)