Skip to content

Commit 5474eb9

Browse files
committed
create table parsing - centralized plain option parsing
1 parent f1cacd2 commit 5474eb9

File tree

4 files changed

+177
-381
lines changed

4 files changed

+177
-381
lines changed

Diff for: src/dialect/mod.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub use self::postgresql::PostgreSqlDialect;
4949
pub use self::redshift::RedshiftSqlDialect;
5050
pub use self::snowflake::SnowflakeDialect;
5151
pub use self::sqlite::SQLiteDialect;
52-
use crate::ast::{ColumnOption, Expr, SqlOption, Statement};
52+
use crate::ast::{ColumnOption, Expr, Statement};
5353
pub use crate::keywords;
5454
use crate::keywords::Keyword;
5555
use crate::parser::{Parser, ParserError};
@@ -703,16 +703,6 @@ pub trait Dialect: Debug + Any {
703703
Ok(None)
704704
}
705705

706-
/// Dialect-specific table/view option parser override
707-
///
708-
/// This method is called to parse the next table/view option.
709-
///
710-
/// If `None` is returned, falls back to the default behavior.
711-
fn parse_plain_option(&self, _parser: &mut Parser) -> Result<Option<SqlOption>, ParserError> {
712-
// return None to fall back to the default behavior
713-
Ok(None)
714-
}
715-
716706
/// Decide the lexical Precedence of operators.
717707
///
718708
/// Uses (APPROXIMATELY) <https://www.postgresql.org/docs/7.0/operators.htm#AEN2026> as a reference

Diff for: src/dialect/mysql.rs

+1-283
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,12 @@
1717

1818
#[cfg(not(feature = "std"))]
1919
use alloc::boxed::Box;
20-
#[cfg(not(feature = "std"))]
21-
use alloc::format;
22-
#[cfg(not(feature = "std"))]
23-
use alloc::vec::Vec;
2420

2521
use crate::{
26-
ast::{
27-
BinaryOperator, Expr, Ident, LockTable, LockTableType, SqlOption, Statement, StorageType,
28-
TablespaceOption, Value,
29-
},
22+
ast::{BinaryOperator, Expr, LockTable, LockTableType, Statement},
3023
dialect::Dialect,
3124
keywords::Keyword,
3225
parser::{Parser, ParserError},
33-
tokenizer::{Token, Word},
3426
};
3527

3628
use super::keywords;
@@ -153,280 +145,6 @@ impl Dialect for MySqlDialect {
153145
fn supports_comma_separated_set_assignments(&self) -> bool {
154146
true
155147
}
156-
/// Dialect-specific table/view option parser override
157-
///
158-
/// This method is called to parse the next table/view option.
159-
///
160-
/// If `None` is returned, falls back to the default behavior.
161-
/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
162-
fn parse_plain_option(&self, parser: &mut Parser) -> Result<Option<SqlOption>, ParserError> {
163-
//Some consts
164-
const COMPRESSION_OPTS: [&str; 3] = ["ZLIB", "LZ4", "NONE"];
165-
const INSERT_METHODS_OPTS: [&str; 3] = ["NO", "FIRST", "LAST"];
166-
167-
let keyword = match parser.parse_one_of_keywords(&[
168-
Keyword::INSERT_METHOD,
169-
Keyword::KEY_BLOCK_SIZE,
170-
Keyword::ROW_FORMAT,
171-
Keyword::DATA,
172-
Keyword::INDEX,
173-
Keyword::PACK_KEYS,
174-
Keyword::STATS_AUTO_RECALC,
175-
Keyword::STATS_PERSISTENT,
176-
Keyword::STATS_SAMPLE_PAGES,
177-
Keyword::DELAY_KEY_WRITE,
178-
Keyword::COMPRESSION,
179-
Keyword::ENCRYPTION,
180-
Keyword::MAX_ROWS,
181-
Keyword::MIN_ROWS,
182-
Keyword::AUTOEXTEND_SIZE,
183-
Keyword::AVG_ROW_LENGTH,
184-
Keyword::CHECKSUM,
185-
Keyword::CONNECTION,
186-
Keyword::ENGINE_ATTRIBUTE,
187-
Keyword::PASSWORD,
188-
Keyword::SECONDARY_ENGINE_ATTRIBUTE,
189-
Keyword::START,
190-
Keyword::TABLESPACE,
191-
Keyword::UNION,
192-
]) {
193-
Some(keyword) => keyword,
194-
None => return Ok(None),
195-
};
196-
197-
//Optional equal sign
198-
let _ = parser.consume_token(&Token::Eq);
199-
let value = parser.next_token();
200-
let span = value.span;
201-
202-
match (keyword, value.token) {
203-
//Handled in common code
204-
// ENGINE [=] engine_name
205-
// AUTO_INCREMENT [=] value
206-
// [DEFAULT] CHARACTER SET [=] charset_name
207-
// [DEFAULT] COLLATE [=] collation_name
208-
209-
// KEY_BLOCK_SIZE [=] value
210-
(Keyword::KEY_BLOCK_SIZE, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
211-
key: Ident::new("KEY_BLOCK_SIZE"),
212-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
213-
})),
214-
215-
// ROW_FORMAT [=] {DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT}
216-
(Keyword::ROW_FORMAT, Token::Word(w)) => Ok(Some(SqlOption::KeyValue {
217-
key: Ident::new("ROW_FORMAT"),
218-
value: Expr::Identifier(Ident::with_span(span, w.value)),
219-
})),
220-
221-
// {DATA | INDEX} DIRECTORY [=] 'absolute path to directory'
222-
(Keyword::DATA, Token::Word(w)) if w.keyword == Keyword::DIRECTORY => {
223-
let _ = parser.consume_token(&Token::Eq);
224-
225-
let next_token = parser.next_token();
226-
227-
if let Token::SingleQuotedString(s) = next_token.token {
228-
Ok(Some(SqlOption::KeyValue {
229-
key: Ident::new("DATA DIRECTORY"),
230-
value: Expr::value(Value::SingleQuotedString(s)),
231-
}))
232-
} else {
233-
parser.expected("Token::SingleQuotedString", next_token)?
234-
}
235-
}
236-
(Keyword::INDEX, Token::Word(w)) if w.keyword == Keyword::DIRECTORY => {
237-
let _ = parser.consume_token(&Token::Eq);
238-
let next_token = parser.next_token();
239-
240-
if let Token::SingleQuotedString(s) = next_token.token {
241-
Ok(Some(SqlOption::KeyValue {
242-
key: Ident::new("INDEX DIRECTORY"),
243-
value: Expr::value(Value::SingleQuotedString(s)),
244-
}))
245-
} else {
246-
parser.expected("Token::SingleQuotedString", next_token)?
247-
}
248-
}
249-
250-
// PACK_KEYS [=] {0 | 1 | DEFAULT}
251-
(Keyword::PACK_KEYS, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
252-
key: Ident::new("PACK_KEYS"),
253-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
254-
})),
255-
256-
(Keyword::PACK_KEYS, Token::Word(s)) if s.value.to_uppercase() == "DEFAULT" => {
257-
Ok(Some(SqlOption::KeyValue {
258-
key: Ident::new("PACK_KEYS"),
259-
value: Expr::value(Value::SingleQuotedString(s.value)),
260-
}))
261-
}
262-
263-
// STATS_AUTO_RECALC [=] {DEFAULT | 0 | 1}
264-
(Keyword::STATS_AUTO_RECALC, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
265-
key: Ident::new("STATS_AUTO_RECALC"),
266-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
267-
})),
268-
269-
(Keyword::STATS_AUTO_RECALC, Token::Word(s)) if s.value.to_uppercase() == "DEFAULT" => {
270-
Ok(Some(SqlOption::KeyValue {
271-
key: Ident::new("STATS_AUTO_RECALC"),
272-
value: Expr::value(Value::SingleQuotedString(s.value)),
273-
}))
274-
}
275-
276-
//STATS_PERSISTENT [=] {DEFAULT | 0 | 1}
277-
(Keyword::STATS_PERSISTENT, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
278-
key: Ident::new("STATS_PERSISTENT"),
279-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
280-
})),
281-
282-
(Keyword::STATS_PERSISTENT, Token::Word(s)) if s.value.to_uppercase() == "DEFAULT" => {
283-
Ok(Some(SqlOption::KeyValue {
284-
key: Ident::new("STATS_PERSISTENT"),
285-
value: Expr::value(Value::SingleQuotedString(s.value)),
286-
}))
287-
}
288-
289-
// STATS_SAMPLE_PAGES [=] value
290-
(Keyword::STATS_SAMPLE_PAGES, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
291-
key: Ident::new("STATS_SAMPLE_PAGES"),
292-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
293-
})),
294-
295-
// DELAY_KEY_WRITE [=] {0 | 1}
296-
(Keyword::DELAY_KEY_WRITE, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
297-
key: Ident::new("DELAY_KEY_WRITE"),
298-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
299-
})),
300-
301-
// COMPRESSION [=] {'ZLIB' | 'LZ4' | 'NONE'}
302-
(Keyword::COMPRESSION, Token::SingleQuotedString(s))
303-
if COMPRESSION_OPTS.contains(&s.to_uppercase().as_str()) =>
304-
{
305-
Ok(Some(SqlOption::KeyValue {
306-
key: Ident::new("COMPRESSION"),
307-
value: Expr::value(Value::SingleQuotedString(s)),
308-
}))
309-
}
310-
311-
// ENCRYPTION [=] {'Y' | 'N'}
312-
(Keyword::ENCRYPTION, Token::SingleQuotedString(s)) => Ok(Some(SqlOption::KeyValue {
313-
key: Ident::new("ENCRYPTION"),
314-
value: Expr::value(Value::SingleQuotedString(s)),
315-
})),
316-
317-
// MAX_ROWS [=] value
318-
(Keyword::MAX_ROWS, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
319-
key: Ident::new("MAX_ROWS"),
320-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
321-
})),
322-
323-
// MIN_ROWS [=] value
324-
(Keyword::MIN_ROWS, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
325-
key: Ident::new("MIN_ROWS"),
326-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
327-
})),
328-
329-
// AUTOEXTEND_SIZE [=] value
330-
(Keyword::AUTOEXTEND_SIZE, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
331-
key: Ident::new("AUTOEXTEND_SIZE"),
332-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
333-
})),
334-
335-
// AVG_ROW_LENGTH [=] value
336-
(Keyword::AVG_ROW_LENGTH, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
337-
key: Ident::new("AVG_ROW_LENGTH"),
338-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
339-
})),
340-
341-
// CHECKSUM [=] {0 | 1}
342-
(Keyword::CHECKSUM, Token::Number(n, l)) => Ok(Some(SqlOption::KeyValue {
343-
key: Ident::new("CHECKSUM"),
344-
value: Expr::value(Value::Number(Parser::parse(n, value.span.start)?, l)),
345-
})),
346-
347-
// CONNECTION [=] 'connect_string'
348-
(Keyword::CONNECTION, Token::SingleQuotedString(s)) => Ok(Some(SqlOption::KeyValue {
349-
key: Ident::new("CONNECTION"),
350-
value: Expr::value(Value::SingleQuotedString(s)),
351-
})),
352-
353-
// ENGINE_ATTRIBUTE [=] 'string'
354-
(Keyword::ENGINE_ATTRIBUTE, Token::SingleQuotedString(s)) => {
355-
Ok(Some(SqlOption::KeyValue {
356-
key: Ident::new("ENGINE_ATTRIBUTE"),
357-
value: Expr::value(Value::SingleQuotedString(s)),
358-
}))
359-
}
360-
361-
// PASSWORD [=] 'string'
362-
(Keyword::PASSWORD, Token::SingleQuotedString(s)) => Ok(Some(SqlOption::KeyValue {
363-
key: Ident::new("PASSWORD"),
364-
value: Expr::value(Value::SingleQuotedString(s)),
365-
})),
366-
367-
// SECONDARY_ENGINE_ATTRIBUTE [=] 'string'
368-
(Keyword::SECONDARY_ENGINE_ATTRIBUTE, Token::SingleQuotedString(s)) => {
369-
Ok(Some(SqlOption::KeyValue {
370-
key: Ident::new("SECONDARY_ENGINE_ATTRIBUTE"),
371-
value: Expr::value(Value::SingleQuotedString(s)),
372-
}))
373-
}
374-
375-
// START TRANSACTION
376-
(Keyword::START, Token::Word(w)) if w.keyword == Keyword::TRANSACTION => {
377-
Ok(Some(SqlOption::Ident(Ident::new("START TRANSACTION"))))
378-
}
379-
380-
// INSERT_METHOD [=] { NO | FIRST | LAST }
381-
(Keyword::INSERT_METHOD, Token::Word(w))
382-
if INSERT_METHODS_OPTS.contains(&w.value.to_uppercase().as_ref()) =>
383-
{
384-
Ok(Some(SqlOption::KeyValue {
385-
key: Ident::new("INSERT_METHOD"),
386-
value: Expr::Identifier(Ident::new(w.value)),
387-
}))
388-
}
389-
390-
// TABLESPACE tablespace_name [STORAGE DISK] | [TABLESPACE tablespace_name] STORAGE MEMORY
391-
(Keyword::TABLESPACE, Token::Word(Word { value: name, .. }))
392-
| (Keyword::TABLESPACE, Token::SingleQuotedString(name)) => {
393-
let storage = match parser.parse_keyword(Keyword::STORAGE) {
394-
true => {
395-
let _ = parser.consume_token(&Token::Eq);
396-
let storage_token = parser.next_token();
397-
match &storage_token.token {
398-
Token::Word(w) => match w.value.to_uppercase().as_str() {
399-
"DISK" => Some(StorageType::Disk),
400-
"MEMORY" => Some(StorageType::Memory),
401-
_ => parser
402-
.expected("Storage type (DISK or MEMORY)", storage_token)?,
403-
},
404-
_ => parser.expected("Token::Word", storage_token)?,
405-
}
406-
}
407-
false => None,
408-
};
409-
410-
Ok(Some(SqlOption::TableSpace(TablespaceOption {
411-
name,
412-
storage,
413-
})))
414-
}
415-
416-
// UNION [=] (tbl_name[,tbl_name]...)
417-
(Keyword::UNION, Token::LParen) => {
418-
let tables: Vec<Ident> =
419-
parser.parse_comma_separated0(Parser::parse_identifier, Token::RParen)?;
420-
parser.expect_token(&Token::RParen)?;
421-
422-
Ok(Some(SqlOption::Union(tables)))
423-
}
424-
425-
_ => Err(ParserError::ParserError(format!(
426-
"Table option {keyword:?} does not have a matching value"
427-
))),
428-
}
429-
}
430148
}
431149

432150
/// `LOCK TABLES`

0 commit comments

Comments
 (0)