@@ -66,7 +66,8 @@ macro_rules! dialect_of {
66
66
/// Encapsulates the differences between SQL implementations.
67
67
///
68
68
/// # SQL Dialects
69
- /// SQL implementations deviatiate from one another, either due to
69
+ ///
70
+ /// SQL implementations deviate from one another, either due to
70
71
/// custom extensions or various historical reasons. This trait
71
72
/// encapsulates the parsing differences between dialects.
72
73
///
@@ -114,16 +115,20 @@ pub trait Dialect: Debug + Any {
114
115
fn is_delimited_identifier_start ( & self , ch : char ) -> bool {
115
116
ch == '"' || ch == '`'
116
117
}
118
+
117
119
/// Return the character used to quote identifiers.
118
120
fn identifier_quote_style ( & self , _identifier : & str ) -> Option < char > {
119
121
None
120
122
}
123
+
121
124
/// Determine if quoted characters are proper for identifier
122
125
fn is_proper_identifier_inside_quotes ( & self , mut _chars : Peekable < Chars < ' _ > > ) -> bool {
123
126
true
124
127
}
128
+
125
129
/// Determine if a character is a valid start character for an unquoted identifier
126
130
fn is_identifier_start ( & self , ch : char ) -> bool ;
131
+
127
132
/// Determine if a character is a valid unquoted identifier character
128
133
fn is_identifier_part ( & self , ch : char ) -> bool ;
129
134
@@ -168,6 +173,7 @@ pub trait Dialect: Debug + Any {
168
173
fn supports_filter_during_aggregation ( & self ) -> bool {
169
174
false
170
175
}
176
+
171
177
/// Returns true if the dialect supports referencing another named window
172
178
/// within a window clause declaration.
173
179
///
@@ -179,45 +185,55 @@ pub trait Dialect: Debug + Any {
179
185
fn supports_window_clause_named_window_reference ( & self ) -> bool {
180
186
false
181
187
}
188
+
182
189
/// Returns true if the dialect supports `ARRAY_AGG() [WITHIN GROUP (ORDER BY)]` expressions.
183
190
/// Otherwise, the dialect should expect an `ORDER BY` without the `WITHIN GROUP` clause, e.g. [`ANSI`]
184
191
///
185
192
/// [`ANSI`]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#array-aggregate-function
186
193
fn supports_within_after_array_aggregation ( & self ) -> bool {
187
194
false
188
195
}
196
+
189
197
/// Returns true if the dialects supports `group sets, roll up, or cube` expressions.
190
198
fn supports_group_by_expr ( & self ) -> bool {
191
199
false
192
200
}
201
+
193
202
/// Returns true if the dialect supports CONNECT BY.
194
203
fn supports_connect_by ( & self ) -> bool {
195
204
false
196
205
}
206
+
197
207
/// Returns true if the dialect supports the MATCH_RECOGNIZE operation.
198
208
fn supports_match_recognize ( & self ) -> bool {
199
209
false
200
210
}
211
+
201
212
/// Returns true if the dialect supports `(NOT) IN ()` expressions
202
213
fn supports_in_empty_list ( & self ) -> bool {
203
214
false
204
215
}
216
+
205
217
/// Returns true if the dialect supports `BEGIN {DEFERRED | IMMEDIATE | EXCLUSIVE} [TRANSACTION]` statements
206
218
fn supports_start_transaction_modifier ( & self ) -> bool {
207
219
false
208
220
}
221
+
209
222
/// Returns true if the dialect supports named arguments of the form FUN(a = '1', b = '2').
210
223
fn supports_named_fn_args_with_eq_operator ( & self ) -> bool {
211
224
false
212
225
}
226
+
213
227
/// Returns true if the dialect supports identifiers starting with a numeric
214
- /// prefix such as tables named: `59901_user_login`
228
+ /// prefix such as tables named `59901_user_login`
215
229
fn supports_numeric_prefix ( & self ) -> bool {
216
230
false
217
231
}
232
+
218
233
/// Returns true if the dialects supports specifying null treatment
219
- /// as part of a window function's parameter list. As opposed
234
+ /// as part of a window function's parameter list as opposed
220
235
/// to after the parameter list.
236
+ ///
221
237
/// i.e The following syntax returns true
222
238
/// ```sql
223
239
/// FIRST_VALUE(a IGNORE NULLS) OVER ()
@@ -229,16 +245,19 @@ pub trait Dialect: Debug + Any {
229
245
fn supports_window_function_null_treatment_arg ( & self ) -> bool {
230
246
false
231
247
}
248
+
232
249
/// Returns true if the dialect supports defining structs or objects using a
233
250
/// syntax like `{'x': 1, 'y': 2, 'z': 3}`.
234
251
fn supports_dictionary_syntax ( & self ) -> bool {
235
252
false
236
253
}
254
+
237
255
/// Returns true if the dialect supports defining object using the
238
256
/// syntax like `Map {1: 10, 2: 20}`.
239
257
fn support_map_literal_syntax ( & self ) -> bool {
240
258
false
241
259
}
260
+
242
261
/// Returns true if the dialect supports lambda functions, for example:
243
262
///
244
263
/// ```sql
@@ -247,6 +266,7 @@ pub trait Dialect: Debug + Any {
247
266
fn supports_lambda_functions ( & self ) -> bool {
248
267
false
249
268
}
269
+
250
270
/// Returns true if the dialect supports multiple variable assignment
251
271
/// using parentheses in a `SET` variable declaration.
252
272
///
@@ -256,6 +276,7 @@ pub trait Dialect: Debug + Any {
256
276
fn supports_parenthesized_set_variables ( & self ) -> bool {
257
277
false
258
278
}
279
+
259
280
/// Returns true if the dialect supports an `EXCEPT` clause following a
260
281
/// wildcard in a select list.
261
282
///
@@ -266,30 +287,40 @@ pub trait Dialect: Debug + Any {
266
287
fn supports_select_wildcard_except ( & self ) -> bool {
267
288
false
268
289
}
290
+
269
291
/// Returns true if the dialect has a CONVERT function which accepts a type first
270
292
/// and an expression second, e.g. `CONVERT(varchar, 1)`
271
293
fn convert_type_before_value ( & self ) -> bool {
272
294
false
273
295
}
296
+
274
297
/// Returns true if the dialect supports triple quoted string
275
298
/// e.g. `"""abc"""`
276
299
fn supports_triple_quoted_string ( & self ) -> bool {
277
300
false
278
301
}
302
+
279
303
/// Dialect-specific prefix parser override
280
304
fn parse_prefix ( & self , _parser : & mut Parser ) -> Option < Result < Expr , ParserError > > {
281
305
// return None to fall back to the default behavior
282
306
None
283
307
}
308
+
284
309
/// Does the dialect support trailing commas around the query?
285
310
fn supports_trailing_commas ( & self ) -> bool {
286
311
false
287
312
}
313
+
288
314
/// Does the dialect support trailing commas in the projection list?
289
315
fn supports_projection_trailing_commas ( & self ) -> bool {
290
316
self . supports_trailing_commas ( )
291
317
}
318
+
292
319
/// Dialect-specific infix parser override
320
+ ///
321
+ /// This method is called to parse the next infix expression.
322
+ ///
323
+ /// If `None` is returned, falls back to the default behavior.
293
324
fn parse_infix (
294
325
& self ,
295
326
_parser : & mut Parser ,
@@ -299,24 +330,33 @@ pub trait Dialect: Debug + Any {
299
330
// return None to fall back to the default behavior
300
331
None
301
332
}
333
+
302
334
/// Dialect-specific precedence override
335
+ ///
336
+ /// This method is called to get the precedence of the next token.
337
+ ///
338
+ /// If `None` is returned, falls back to the default behavior.
303
339
fn get_next_precedence ( & self , _parser : & Parser ) -> Option < Result < u8 , ParserError > > {
304
340
// return None to fall back to the default behavior
305
341
None
306
342
}
307
343
308
- /// Get the precedence of the next token. This "full" method means all precedence logic and remain
309
- /// in the dialect. while still allowing overriding the `get_next_precedence` method with the option to
310
- /// fallback to the default behavior.
344
+ /// Get the precedence of the next token, looking at the full token stream.
311
345
///
312
- /// Higher number => higher precedence
346
+ /// A higher number => higher precedence
347
+ ///
348
+ /// See [`Self::get_next_precedence`] to override the behavior for just the
349
+ /// next token.
350
+ ///
351
+ /// The default implementation is used for many dialects, but can be
352
+ /// overridden to provide dialect-specific behavior.
313
353
fn get_next_precedence_full ( & self , parser : & Parser ) -> Result < u8 , ParserError > {
314
354
if let Some ( precedence) = self . get_next_precedence ( parser) {
315
355
return precedence;
316
356
}
317
357
318
358
let token = parser. peek_token ( ) ;
319
- debug ! ( "get_next_precedence () {:?}" , token) ;
359
+ debug ! ( "get_next_precedence_full () {:?}" , token) ;
320
360
match token. token {
321
361
Token :: Word ( w) if w. keyword == Keyword :: OR => Ok ( OR_PREC ) ,
322
362
Token :: Word ( w) if w. keyword == Keyword :: AND => Ok ( AND_PREC ) ,
@@ -408,37 +448,67 @@ pub trait Dialect: Debug + Any {
408
448
}
409
449
410
450
/// Dialect-specific statement parser override
451
+ ///
452
+ /// This method is called to parse the next statement.
453
+ ///
454
+ /// If `None` is returned, falls back to the default behavior.
411
455
fn parse_statement ( & self , _parser : & mut Parser ) -> Option < Result < Statement , ParserError > > {
412
456
// return None to fall back to the default behavior
413
457
None
414
458
}
415
459
416
- /// The following precedence values are used directly by `Parse` or in dialects,
417
- /// so have to be made public by the dialect.
460
+ // The following precedence values are used directly by `Parse` or in dialects,
461
+ // so have to be made public by the dialect.
462
+
463
+ /// Return the precedence of the `::` operator.
464
+ ///
465
+ /// Default is 50.
418
466
fn prec_double_colon ( & self ) -> u8 {
419
467
DOUBLE_COLON_PREC
420
468
}
421
469
470
+ /// Return the precedence of `*`, `/`, and `%` operators.
471
+ ///
472
+ /// Default is 40.
422
473
fn prec_mul_div_mod_op ( & self ) -> u8 {
423
474
MUL_DIV_MOD_OP_PREC
424
475
}
425
476
477
+ /// Return the precedence of the `+` and `-` operators.
478
+ ///
479
+ /// Default is 30.
426
480
fn prec_plus_minus ( & self ) -> u8 {
427
481
PLUS_MINUS_PREC
428
482
}
429
483
484
+ /// Return the precedence of the `BETWEEN` operator.
485
+ ///
486
+ /// For example `BETWEEN <low> AND <high>`
487
+ ///
488
+ /// Default is 22.
430
489
fn prec_between ( & self ) -> u8 {
431
490
BETWEEN_PREC
432
491
}
433
492
493
+ /// Return the precedence of the `LIKE` operator.
494
+ ///
495
+ /// Default is 19.
434
496
fn prec_like ( & self ) -> u8 {
435
497
LIKE_PREC
436
498
}
437
499
500
+ /// Return the precedence of the unary `NOT` operator.
501
+ ///
502
+ /// For example `NOT (a OR b)`
503
+ ///
504
+ /// Default is 15.
438
505
fn prec_unary_not ( & self ) -> u8 {
439
506
UNARY_NOT_PREC
440
507
}
441
508
509
+ /// Return the default (unknown) precedence.
510
+ ///
511
+ /// Default is 0.
442
512
fn prec_unknown ( & self ) -> u8 {
443
513
UNKNOWN_PREC
444
514
}
0 commit comments