mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-18 13:10:15 +00:00
Change Word::keyword to a enum (#193)
This improves performance and paves the way to future API enhancements as discussed in the PR https://github.com/andygrove/sqlparser-rs/pull/193
This commit is contained in:
parent
0fe3a8ec39
commit
34548e890b
5 changed files with 395 additions and 342 deletions
|
@ -388,22 +388,6 @@ impl fmt::Display for WindowFrameUnits {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromStr for WindowFrameUnits {
|
||||
type Err = ParserError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"ROWS" => Ok(WindowFrameUnits::Rows),
|
||||
"RANGE" => Ok(WindowFrameUnits::Range),
|
||||
"GROUPS" => Ok(WindowFrameUnits::Groups),
|
||||
_ => Err(ParserError::ParserError(format!(
|
||||
"Expected ROWS, RANGE, or GROUPS, found: {}",
|
||||
s
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
|
|
@ -41,12 +41,24 @@ macro_rules! define_keywords {
|
|||
($(
|
||||
$ident:ident $(= $string_keyword:expr)?
|
||||
),*) => {
|
||||
$(kw_def!($ident $(= $string_keyword)?);)*
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Keyword {
|
||||
NoKeyword,
|
||||
$($ident),*
|
||||
}
|
||||
|
||||
pub const ALL_KEYWORDS_INDEX: &[Keyword] = &[
|
||||
$(Keyword::$ident),*
|
||||
];
|
||||
|
||||
$(kw_def!($ident $(= $string_keyword)?);)*
|
||||
pub const ALL_KEYWORDS: &[&str] = &[
|
||||
$($ident),*
|
||||
];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// The following keywords should be sorted to be able to match using binary search
|
||||
|
@ -434,20 +446,52 @@ define_keywords!(
|
|||
|
||||
/// These keywords can't be used as a table alias, so that `FROM table_name alias`
|
||||
/// can be parsed unambiguously without looking ahead.
|
||||
pub const RESERVED_FOR_TABLE_ALIAS: &[&str] = &[
|
||||
pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
|
||||
// Reserved as both a table and a column alias:
|
||||
WITH, SELECT, WHERE, GROUP, HAVING, ORDER, TOP, LIMIT, OFFSET, FETCH, UNION, EXCEPT, INTERSECT,
|
||||
Keyword::WITH,
|
||||
Keyword::SELECT,
|
||||
Keyword::WHERE,
|
||||
Keyword::GROUP,
|
||||
Keyword::HAVING,
|
||||
Keyword::ORDER,
|
||||
Keyword::TOP,
|
||||
Keyword::LIMIT,
|
||||
Keyword::OFFSET,
|
||||
Keyword::FETCH,
|
||||
Keyword::UNION,
|
||||
Keyword::EXCEPT,
|
||||
Keyword::INTERSECT,
|
||||
// Reserved only as a table alias in the `FROM`/`JOIN` clauses:
|
||||
ON, JOIN, INNER, CROSS, FULL, LEFT, RIGHT, NATURAL, USING,
|
||||
Keyword::ON,
|
||||
Keyword::JOIN,
|
||||
Keyword::INNER,
|
||||
Keyword::CROSS,
|
||||
Keyword::FULL,
|
||||
Keyword::LEFT,
|
||||
Keyword::RIGHT,
|
||||
Keyword::NATURAL,
|
||||
Keyword::USING,
|
||||
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
|
||||
OUTER,
|
||||
Keyword::OUTER,
|
||||
];
|
||||
|
||||
/// Can't be used as a column alias, so that `SELECT <expr> alias`
|
||||
/// can be parsed unambiguously without looking ahead.
|
||||
pub const RESERVED_FOR_COLUMN_ALIAS: &[&str] = &[
|
||||
pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
|
||||
// Reserved as both a table and a column alias:
|
||||
WITH, SELECT, WHERE, GROUP, HAVING, ORDER, LIMIT, OFFSET, FETCH, UNION, EXCEPT, INTERSECT,
|
||||
// Reserved only as a column alias in the `SELECT` clause:
|
||||
FROM,
|
||||
Keyword::WITH,
|
||||
Keyword::SELECT,
|
||||
Keyword::WHERE,
|
||||
Keyword::GROUP,
|
||||
Keyword::HAVING,
|
||||
Keyword::ORDER,
|
||||
Keyword::TOP,
|
||||
Keyword::LIMIT,
|
||||
Keyword::OFFSET,
|
||||
Keyword::FETCH,
|
||||
Keyword::UNION,
|
||||
Keyword::EXCEPT,
|
||||
Keyword::INTERSECT,
|
||||
// Reserved only as a column alias in the `SELECT` clause
|
||||
Keyword::FROM,
|
||||
];
|
||||
|
|
634
src/parser.rs
634
src/parser.rs
File diff suppressed because it is too large
Load diff
|
@ -19,7 +19,7 @@
|
|||
use std::iter::Peekable;
|
||||
use std::str::Chars;
|
||||
|
||||
use super::dialect::keywords::ALL_KEYWORDS;
|
||||
use super::dialect::keywords::{Keyword, ALL_KEYWORDS, ALL_KEYWORDS_INDEX};
|
||||
use super::dialect::Dialect;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -146,15 +146,14 @@ impl Token {
|
|||
}
|
||||
pub fn make_word(word: &str, quote_style: Option<char>) -> Self {
|
||||
let word_uppercase = word.to_uppercase();
|
||||
let is_keyword =
|
||||
quote_style == None && ALL_KEYWORDS.binary_search(&word_uppercase.as_str()).is_ok();
|
||||
Token::Word(Word {
|
||||
value: word.to_string(),
|
||||
quote_style,
|
||||
keyword: if is_keyword {
|
||||
word_uppercase
|
||||
keyword: if quote_style == None {
|
||||
let keyword = ALL_KEYWORDS.binary_search(&word_uppercase.as_str());
|
||||
keyword.map_or(Keyword::NoKeyword, |x| ALL_KEYWORDS_INDEX[x])
|
||||
} else {
|
||||
"".to_string()
|
||||
Keyword::NoKeyword
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -172,7 +171,7 @@ pub struct Word {
|
|||
pub quote_style: Option<char>,
|
||||
/// If the word was not quoted and it matched one of the known keywords,
|
||||
/// this will have one of the values from dialect::keywords, otherwise empty
|
||||
pub keyword: String,
|
||||
pub keyword: Keyword,
|
||||
}
|
||||
|
||||
impl fmt::Display for Word {
|
||||
|
|
|
@ -22,7 +22,7 @@ use matches::assert_matches;
|
|||
|
||||
use sqlparser::ast::*;
|
||||
use sqlparser::dialect::keywords::ALL_KEYWORDS;
|
||||
use sqlparser::parser::*;
|
||||
use sqlparser::parser::{Parser, ParserError};
|
||||
use sqlparser::test_utils::{all_dialects, expr_from_projection, number, only};
|
||||
|
||||
#[test]
|
||||
|
@ -1354,10 +1354,12 @@ fn parse_window_functions() {
|
|||
avg(bar) OVER (ORDER BY a \
|
||||
RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING), \
|
||||
max(baz) OVER (ORDER BY a \
|
||||
ROWS UNBOUNDED PRECEDING) \
|
||||
ROWS UNBOUNDED PRECEDING), \
|
||||
sum(qux) OVER (ORDER BY a \
|
||||
GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING) \
|
||||
FROM foo";
|
||||
let select = verified_only_select(sql);
|
||||
assert_eq!(4, select.projection.len());
|
||||
assert_eq!(5, select.projection.len());
|
||||
assert_eq!(
|
||||
&Expr::Function(Function {
|
||||
name: ObjectName(vec![Ident::new("row_number")]),
|
||||
|
@ -2872,7 +2874,7 @@ fn parse_drop_index() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn keywords_sorted() {
|
||||
fn all_keywords_sorted() {
|
||||
// assert!(ALL_KEYWORDS.is_sorted())
|
||||
let mut copy = Vec::from(ALL_KEYWORDS);
|
||||
copy.sort();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue