Skip to content

Commit

Permalink
fix(parser): fix parsing timestamp number (#17080)
Browse files Browse the repository at this point in the history
Signed-off-by: Runji Wang <[email protected]>
  • Loading branch information
wangrunji0408 authored Jun 4, 2024
1 parent d764ef3 commit 4001aba
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
40 changes: 23 additions & 17 deletions src/sqlparser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use winnow::{PResult, Parser as _};
use crate::ast::*;
use crate::keywords::{self, Keyword};
use crate::parser_v2;
use crate::parser_v2::{keyword, literal_i64, literal_uint, ParserExt as _};
use crate::parser_v2::{keyword, literal_i64, literal_uint, single_quoted_string, ParserExt as _};
use crate::tokenizer::*;

pub(crate) const UPSTREAM_SOURCE_KEY: &str = "connector";
Expand Down Expand Up @@ -3722,25 +3722,31 @@ impl Parser<'_> {
alt((
preceded(
(Keyword::SYSTEM_TIME, Keyword::AS, Keyword::OF),
alt((
(
Self::parse_identifier.verify(|ident| {
ident.real_value() == "proctime" || ident.real_value() == "now"
}),
Token::LParen,
Token::RParen,
)
.value(AsOf::ProcessTime),
literal_i64.map(AsOf::VersionNum),
Self::parse_literal_string.map(AsOf::TimestampString),
)),
cut_err(
alt((
(
Self::parse_identifier.verify(|ident| {
ident.real_value() == "proctime" || ident.real_value() == "now"
}),
cut_err(Token::LParen),
cut_err(Token::RParen),
)
.value(AsOf::ProcessTime),
literal_i64.map(AsOf::TimestampNum),
single_quoted_string.map(AsOf::TimestampString),
))
.expect("proctime(), now(), number or string"),
),
),
preceded(
(Keyword::SYSTEM_VERSION, Keyword::AS, Keyword::OF),
alt((
literal_i64.map(AsOf::VersionNum),
Self::parse_literal_string.map(AsOf::VersionString),
)),
cut_err(
alt((
literal_i64.map(AsOf::VersionNum),
single_quoted_string.map(AsOf::VersionString),
))
.expect("number or string"),
),
),
))
.parse_next(self)
Expand Down
13 changes: 13 additions & 0 deletions src/sqlparser/src/parser_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,19 @@ where
.parse_next(input)
}

/// Consume an 'single-quoted string'.
pub fn single_quoted_string<S>(input: &mut S) -> PResult<String>
where
S: TokenStream,
{
token
.verify_map(|t| match &t.token {
Token::SingleQuotedString(s) => Some(s.clone()),
_ => None,
})
.parse_next(input)
}

/// Consume an object name.
///
/// FIXME: Object name is extremely complex, we only handle a subset here.
Expand Down
23 changes: 23 additions & 0 deletions src/sqlparser/tests/testdata/as_of.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This file is automatically generated by `src/sqlparser/tests/parser_test.rs`.
- input: select * from t1 left join t2 FOR SYSTEM_TIME AS OF PROCTIME() on a1 = a2;
formatted_sql: SELECT * FROM t1 LEFT JOIN t2 FOR SYSTEM_TIME AS OF PROCTIME() ON a1 = a2
- input: select * from t1 left join t2 FOR SYSTEM_TIME AS OF NOW() on a1 = a2;
formatted_sql: SELECT * FROM t1 LEFT JOIN t2 FOR SYSTEM_TIME AS OF PROCTIME() ON a1 = a2
- input: select * from t1 left join t2 FOR SYSTEM_TIME AS OF 1 on a1 = a2;
formatted_sql: SELECT * FROM t1 LEFT JOIN t2 FOR SYSTEM_TIME AS OF 1 ON a1 = a2
- input: select * from t1 left join t2 FOR SYSTEM_TIME AS OF 'string' on a1 = a2;
formatted_sql: SELECT * FROM t1 LEFT JOIN t2 FOR SYSTEM_TIME AS OF 'string' ON a1 = a2
- input: select * from t1 left join t2 FOR SYSTEM_TIME AS OF PROCTIME on a1 = a2;
error_msg: |-
sql parser error: expected proctime(), now(), number or string
LINE 1: select * from t1 left join t2 FOR SYSTEM_TIME AS OF PROCTIME on a1 = a2;
^
- input: select * from t1 left join t2 FOR SYSTEM_VERSION AS OF 1 on a1 = a2;
formatted_sql: SELECT * FROM t1 LEFT JOIN t2 FOR SYSTEM_VERSION AS OF 1 ON a1 = a2
- input: select * from t1 left join t2 FOR SYSTEM_VERSION AS OF 'string' on a1 = a2;
formatted_sql: SELECT * FROM t1 LEFT JOIN t2 FOR SYSTEM_VERSION AS OF 'string' ON a1 = a2
- input: select * from t1 left join t2 FOR SYSTEM_VERSION AS OF PROCTIME() on a1 = a2;
error_msg: |-
sql parser error: expected number or string
LINE 1: select * from t1 left join t2 FOR SYSTEM_VERSION AS OF PROCTIME() on a1 = a2;
^

0 comments on commit 4001aba

Please sign in to comment.