Skip to content

Commit 06a8870

Browse files
committed
Introduce concept of dialects
1 parent cc72579 commit 06a8870

7 files changed

Lines changed: 184 additions & 92 deletions

File tree

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,3 @@ name = "sqlparser"
1818
path = "src/lib.rs"
1919

2020
[dependencies]
21-
fnv = "1.0.3"
22-
lazy_static = "1.0"

examples/parse_select.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
extern crate sqlparser;
22

3+
use sqlparser::dialect::AnsiSqlDialect;
34
use sqlparser::sqlparser::*;
45

56
fn main() {
@@ -8,7 +9,9 @@ fn main() {
89
WHERE a > b AND b < 100 \
910
ORDER BY a DESC, b";
1011

11-
let ast = Parser::parse_sql(sql.to_string()).unwrap();
12+
let dialect = AnsiSqlDialect{};
13+
14+
let ast = Parser::parse_sql(&dialect,sql.to_string()).unwrap();
1215

1316
println!("AST: {:?}", ast);
1417
}

src/.sqlparser.rs.swo

-44 KB
Binary file not shown.

src/dialect.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Copyright 2018 Grove Enterprises LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//! Support for custom dialects
16+
17+
pub trait Dialect {
18+
/// Get a list of keywords for this dialect
19+
fn keywords(&self) -> Vec<&'static str>;
20+
}
21+
22+
pub struct AnsiSqlDialect {
23+
}
24+
25+
impl Dialect for AnsiSqlDialect {
26+
fn keywords(&self) -> Vec<&'static str> {
27+
return vec!["ABS", "ALL", "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "ARRAY", "ARRAY_AGG",
28+
"ARRAY_MAX_CARDINALITY", "AS", "ASENSITIVE", "ASYMMETRIC", "AT", "ATOMIC", "AUTHORIZATION",
29+
"AVG", "BEGIN", "BEGIN_FRAME", "BEGIN_PARTITION", "BETWEEN", "BIGINT", "BINARY", "BLOB",
30+
"BOOLEAN", "BOTH", "BY", "CALL", "CALLED", "CARDINALITY", "CASCADED", "CASE", "CAST", "CEIL",
31+
"CEILING", "CHAR", "CHAR_LENGTH", "CHARACTER", "CHARACTER_LENGTH", "CHECK", "CLOB", "CLOSE",
32+
"COALESCE", "COLLATE", "COLLECT", "COLUMN", "COMMIT", "CONDITION", "CONNECT", "CONSTRAINT",
33+
"CONTAINS", "CONVERT", "CORR", "CORRESPONDING", "COUNT", "COVAR_POP", "COVAR_SAMP", "CREATE",
34+
"CROSS", "CUBE", "CUME_DIST", "CURRENT", "CURRENT_CATALOG", "CURRENT_DATE",
35+
"CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_PATH", "CURRENT_ROLE", "CURRENT_ROW",
36+
"CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_TRANSFORM_GROUP_FOR_TYPE",
37+
"CURRENT_USER", "CURSOR", "CYCLE", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE",
38+
"DEFAULT", "DELETE", "DENSE_RANK", "DEREF", "DESCRIBE", "DETERMINISTIC", "DISCONNECT",
39+
"DISTINCT", "DOUBLE", "DROP", "DYNAMIC", "EACH", "ELEMENT", "ELSE", "END", "END_FRAME",
40+
"END_PARTITION", "END-EXEC", "EQUALS", "ESCAPE", "EVERY", "EXCEPT", "EXEC", "EXECUTE",
41+
"EXISTS", "EXP", "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FILTER", "FIRST_VALUE", "FLOAT",
42+
"FLOOR", "FOR", "FOREIGN", "FRAME_ROW", "FREE", "FROM", "FULL", "FUNCTION", "FUSION",
43+
"GET", "GLOBAL", "GRANT", "GROUP", "GROUPING", "GROUPS", "HAVING", "HOLD", "HOUR", "IDENTITY",
44+
"IN", "INDICATOR", "INNER", "INOUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERSECT",
45+
"INTERSECTION", "INTERVAL", "INTO", "IS", "JOIN", "LAG", "LANGUAGE", "LARGE", "LAST_VALUE",
46+
"LATERAL", "LEAD", "LEADING", "LEFT", "LIKE", "LIKE_REGEX", "LN", "LOCAL", "LOCALTIME",
47+
"LOCALTIMESTAMP", "LOWER", "MATCH", "MAX", "MEMBER", "MERGE", "METHOD", "MIN", "MINUTE",
48+
"MOD", "MODIFIES", "MODULE", "MONTH", "MULTISET", "NATIONAL", "NATURAL", "NCHAR", "NCLOB",
49+
"NEW", "NO", "NONE", "NORMALIZE", "NOT", "NTH_VALUE", "NTILE", "NULL", "NULLIF", "NUMERIC",
50+
"OCTET_LENGTH", "OCCURRENCES_REGEX", "OF", "OFFSET", "OLD", "ON", "ONLY", "OPEN", "OR",
51+
"ORDER", "OUT", "OUTER", "OVER", "OVERLAPS", "OVERLAY", "PARAMETER", "PARTITION", "PERCENT",
52+
"PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "PERIOD", "PORTION", "POSITION",
53+
"POSITION_REGEX", "POWER", "PRECEDES", "PRECISION", "PREPARE", "PRIMARY",
54+
"PROCEDURE", "RANGE", "RANK", "READS", "REAL", "RECURSIVE", "REF", "REFERENCES",
55+
"REFERENCING", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2",
56+
"REGR_SLOPE", "REGR_SXX", "REGR_SXY", "REGR_SYY", "RELEASE", "RESULT", "RETURN", "RETURNS",
57+
"REVOKE", "RIGHT", "ROLLBACK", "ROLLUP", "ROW", "ROW_NUMBER", "ROWS", "SAVEPOINT",
58+
"SCOPE", "SCROLL", "SEARCH", "SECOND", "SELECT", "SENSITIVE", "SESSION_USER", "SET",
59+
"SIMILAR", "SMALLINT", "SOME", "SPECIFIC", "SPECIFICTYPE", "SQL", "SQLEXCEPTION", "SQLSTATE",
60+
"SQLWARNING", "SQRT", "START", "STATIC", "STDDEV_POP", "STDDEV_SAMP", "SUBMULTISET",
61+
"SUBSTRING", "SUBSTRING_REGEX", "SUCCEEDS", "SUM", "SYMMETRIC", "SYSTEM", "SYSTEM_TIME",
62+
"SYSTEM_USER", "TABLE", "TABLESAMPLE", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR",
63+
"TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSLATE", "TRANSLATE_REGEX", "TRANSLATION",
64+
"TREAT", "TRIGGER", "TRUNCATE", "TRIM", "TRIM_ARRAY", "TRUE", "UESCAPE", "UNION", "UNIQUE",
65+
"UNKNOWN", "UNNEST", "UPDATE", "UPPER", "USER", "USING", "VALUE", "VALUES", "VALUE_OF",
66+
"VAR_POP", "VAR_SAMP", "VARBINARY", "VARCHAR", "VARYING", "VERSIONING", "WHEN", "WHENEVER",
67+
"WHERE", "WIDTH_BUCKET", "WINDOW", "WITH", "WITHIN", "WITHOUT", "YEAR"];
68+
}
69+
}
70+
71+
pub struct GenericSqlDialect {}
72+
73+
impl Dialect for GenericSqlDialect {
74+
fn keywords(&self) -> Vec<&'static str> {
75+
return vec![
76+
"SELECT",
77+
"FROM",
78+
"WHERE",
79+
"LIMIT",
80+
"ORDER",
81+
"GROUP",
82+
"BY",
83+
"HAVING",
84+
"UNION",
85+
"ALL",
86+
"INSERT",
87+
"UPDATE",
88+
"DELETE",
89+
"IN",
90+
"IS",
91+
"NULL",
92+
"SET",
93+
"CREATE",
94+
"EXTERNAL",
95+
"TABLE",
96+
"ASC",
97+
"DESC",
98+
"AND",
99+
"OR",
100+
"NOT",
101+
"AS",
102+
"STORED",
103+
"CSV",
104+
"PARQUET",
105+
"LOCATION",
106+
"WITH",
107+
"WITHOUT",
108+
"HEADER",
109+
"ROW",
110+
111+
// SQL types
112+
"CHAR",
113+
"CHARACTER",
114+
"VARYING",
115+
"LARGE",
116+
"OBJECT",
117+
"VARCHAR",
118+
"CLOB",
119+
"BINARY",
120+
"VARBINARY",
121+
"BLOB",
122+
"FLOAT",
123+
"REAL",
124+
"DOUBLE",
125+
"PRECISION",
126+
"INT",
127+
"INTEGER",
128+
"SMALLINT",
129+
"BIGINT",
130+
"NUMERIC",
131+
"DECIMAL",
132+
"DEC",
133+
"BOOLEAN",
134+
"DATE",
135+
"TIME",
136+
"TIMESTAMP",
137+
138+
];
139+
}
140+
}
141+

src/lib.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,22 @@
2020
//! Syntax Tree (AST).
2121
//!
2222
//! ```
23+
//! use sqlparser::dialect::GenericSqlDialect;
2324
//! use sqlparser::sqlparser::Parser;
2425
//!
26+
//! let dialect = GenericSqlDialect {}; // or AnsiSqlDialect
27+
//!
2528
//! let sql = "SELECT a, b, 123, myfunc(b) \
2629
//! FROM table_1 \
2730
//! WHERE a > b AND b < 100 \
2831
//! ORDER BY a DESC, b";
2932
//!
30-
//! let ast = Parser::parse_sql(sql.to_string()).unwrap();
33+
//! let ast = Parser::parse_sql(&dialect, sql.to_string()).unwrap();
3134
//!
3235
//! println!("AST: {:?}", ast);
3336
//! ```
3437
35-
extern crate fnv;
36-
37-
#[macro_use]
38-
extern crate lazy_static;
39-
38+
pub mod dialect;
4039
pub mod sqlast;
4140
pub mod sqlparser;
4241
pub mod sqltokenizer;

src/sqlparser.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
//! SQL Parser
1616
17+
use super::dialect::Dialect;
1718
use super::sqlast::*;
1819
use super::sqltokenizer::*;
1920

@@ -51,8 +52,8 @@ impl Parser {
5152
}
5253

5354
/// Parse a SQL statement and produce an Abstract Syntax Tree (AST)
54-
pub fn parse_sql(sql: String) -> Result<ASTNode, ParserError> {
55-
let mut tokenizer = Tokenizer::new(&sql);
55+
pub fn parse_sql(dialect: &Dialect, sql: String) -> Result<ASTNode, ParserError> {
56+
let mut tokenizer = Tokenizer::new(dialect, &sql);
5657
let tokens = tokenizer.tokenize()?;
5758
let mut parser = Parser::new(tokens);
5859
parser.parse()
@@ -619,6 +620,7 @@ impl Parser {
619620
mod tests {
620621

621622
use super::*;
623+
use super::super::dialect::GenericSqlDialect;
622624

623625
#[test]
624626
fn parse_delete_statement() {
@@ -949,7 +951,8 @@ mod tests {
949951
}
950952

951953
fn parse_sql(sql: &str) -> ASTNode {
952-
let mut tokenizer = Tokenizer::new(&sql);
954+
let dialect = GenericSqlDialect {};
955+
let mut tokenizer = Tokenizer::new(&dialect,&sql, );
953956
let tokens = tokenizer.tokenize().unwrap();
954957
let mut parser = Parser::new(tokens);
955958
let ast = parser.parse().unwrap();

0 commit comments

Comments
 (0)