@@ -195,9 +195,52 @@ impl std::error::Error for ParserError {}
195
195
// By default, allow expressions up to this deep before erroring
196
196
const DEFAULT_REMAINING_DEPTH : usize = 50 ;
197
197
198
- #[ derive( Debug , Default , Clone , PartialEq , Eq ) ]
198
+ /// Options that control how the [`Parser`] parses SQL text
199
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
199
200
pub struct ParserOptions {
200
201
pub trailing_commas : bool ,
202
+ /// Controls how literal values are unescaped. See
203
+ /// [`Tokenizer::with_unescape`] for more details.
204
+ pub unescape : bool ,
205
+ }
206
+
207
+ impl Default for ParserOptions {
208
+ fn default ( ) -> Self {
209
+ Self {
210
+ trailing_commas : false ,
211
+ unescape : true ,
212
+ }
213
+ }
214
+ }
215
+
216
+ impl ParserOptions {
217
+ /// Create a new [`ParserOptions`]
218
+ pub fn new ( ) -> Self {
219
+ Default :: default ( )
220
+ }
221
+
222
+ /// Set if trailing commas are allowed.
223
+ ///
224
+ /// If this option is `false` (the default), the following SQL will
225
+ /// not parse. If the option is `true`, the SQL will parse.
226
+ ///
227
+ /// ```sql
228
+ /// SELECT
229
+ /// foo,
230
+ /// bar,
231
+ /// FROM baz
232
+ /// ```
233
+ pub fn with_trailing_commas ( mut self , trailing_commas : bool ) -> Self {
234
+ self . trailing_commas = trailing_commas;
235
+ self
236
+ }
237
+
238
+ /// Set if literal values are unescaped. Defaults to true. See
239
+ /// [`Tokenizer::with_unescape`] for more details.
240
+ pub fn with_unescape ( mut self , unescape : bool ) -> Self {
241
+ self . unescape = unescape;
242
+ self
243
+ }
201
244
}
202
245
203
246
pub struct Parser < ' a > {
@@ -206,8 +249,9 @@ pub struct Parser<'a> {
206
249
index : usize ,
207
250
/// The current dialect to use
208
251
dialect : & ' a dyn Dialect ,
209
- /// Additional options that allow you to mix & match behavior otherwise
210
- /// constrained to certain dialects (e.g. trailing commas)
252
+ /// Additional options that allow you to mix & match behavior
253
+ /// otherwise constrained to certain dialects (e.g. trailing
254
+ /// commas) and/or format of parse (e.g. unescaping)
211
255
options : ParserOptions ,
212
256
/// ensure the stack does not overflow by limiting recursion depth
213
257
recursion_counter : RecursionCounter ,
@@ -267,17 +311,20 @@ impl<'a> Parser<'a> {
267
311
/// Specify additional parser options
268
312
///
269
313
///
270
- /// [`Parser`] supports additional options ([`ParserOptions`]) that allow you to
271
- /// mix & match behavior otherwise constrained to certain dialects (e.g. trailing
272
- /// commas).
314
+ /// [`Parser`] supports additional options ([`ParserOptions`])
315
+ /// that allow you to mix & match behavior otherwise constrained
316
+ /// to certain dialects (e.g. trailing commas).
273
317
///
274
318
/// Example:
275
319
/// ```
276
320
/// # use sqlparser::{parser::{Parser, ParserError, ParserOptions}, dialect::GenericDialect};
277
321
/// # fn main() -> Result<(), ParserError> {
278
322
/// let dialect = GenericDialect{};
323
+ /// let options = ParserOptions::new()
324
+ /// .with_trailing_commas(true)
325
+ /// .with_unescape(false);
279
326
/// let result = Parser::new(&dialect)
280
- /// .with_options(ParserOptions { trailing_commas: true } )
327
+ /// .with_options(options )
281
328
/// .try_with_sql("SELECT a, b, COUNT(*), FROM foo GROUP BY a, b,")?
282
329
/// .parse_statements();
283
330
/// assert!(matches!(result, Ok(_)));
@@ -317,8 +364,9 @@ impl<'a> Parser<'a> {
317
364
/// See example on [`Parser::new()`] for an example
318
365
pub fn try_with_sql ( self , sql : & str ) -> Result < Self , ParserError > {
319
366
debug ! ( "Parsing sql '{}'..." , sql) ;
320
- let mut tokenizer = Tokenizer :: new ( self . dialect , sql) ;
321
- let tokens = tokenizer. tokenize ( ) ?;
367
+ let tokens = Tokenizer :: new ( self . dialect , sql)
368
+ . with_unescape ( self . options . unescape )
369
+ . tokenize ( ) ?;
322
370
Ok ( self . with_tokens ( tokens) )
323
371
}
324
372
@@ -3654,7 +3702,7 @@ impl<'a> Parser<'a> {
3654
3702
self . expect_token ( & Token :: RParen ) ?;
3655
3703
Ok ( Some ( ColumnOption :: Check ( expr) ) )
3656
3704
} else if self . parse_keyword ( Keyword :: AUTO_INCREMENT )
3657
- && dialect_of ! ( self is MySqlDialect | GenericDialect )
3705
+ && dialect_of ! ( self is MySqlDialect | GenericDialect )
3658
3706
{
3659
3707
// Support AUTO_INCREMENT for MySQL
3660
3708
Ok ( Some ( ColumnOption :: DialectSpecific ( vec ! [
0 commit comments