@@ -24,12 +24,13 @@ mod redshift;
24
24
mod snowflake;
25
25
mod sqlite;
26
26
27
- use crate :: ast:: { Expr , Statement } ;
28
27
use core:: any:: { Any , TypeId } ;
29
28
use core:: fmt:: Debug ;
30
29
use core:: iter:: Peekable ;
31
30
use core:: str:: Chars ;
32
31
32
+ use log:: debug;
33
+
33
34
pub use self :: ansi:: AnsiDialect ;
34
35
pub use self :: bigquery:: BigQueryDialect ;
35
36
pub use self :: clickhouse:: ClickHouseDialect ;
@@ -43,8 +44,11 @@ pub use self::postgresql::PostgreSqlDialect;
43
44
pub use self :: redshift:: RedshiftSqlDialect ;
44
45
pub use self :: snowflake:: SnowflakeDialect ;
45
46
pub use self :: sqlite:: SQLiteDialect ;
47
+ use crate :: ast:: { Expr , Statement } ;
46
48
pub use crate :: keywords;
49
+ use crate :: keywords:: Keyword ;
47
50
use crate :: parser:: { Parser , ParserError } ;
51
+ use crate :: tokenizer:: Token ;
48
52
49
53
#[ cfg( not( feature = "std" ) ) ]
50
54
use alloc:: boxed:: Box ;
@@ -300,13 +304,172 @@ pub trait Dialect: Debug + Any {
300
304
// return None to fall back to the default behavior
301
305
None
302
306
}
307
+
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.
311
+ ///
312
+ /// Higher number => higher precedence
313
+ fn get_next_precedence_full ( & self , parser : & Parser ) -> Result < u8 , ParserError > {
314
+ if let Some ( precedence) = self . get_next_precedence ( parser) {
315
+ return precedence;
316
+ }
317
+
318
+ let token = parser. peek_token ( ) ;
319
+ debug ! ( "get_next_precedence() {:?}" , token) ;
320
+ match token. token {
321
+ Token :: Word ( w) if w. keyword == Keyword :: OR => Ok ( OR_PREC ) ,
322
+ Token :: Word ( w) if w. keyword == Keyword :: AND => Ok ( AND_PREC ) ,
323
+ Token :: Word ( w) if w. keyword == Keyword :: XOR => Ok ( XOR_PREC ) ,
324
+
325
+ Token :: Word ( w) if w. keyword == Keyword :: AT => {
326
+ match (
327
+ parser. peek_nth_token ( 1 ) . token ,
328
+ parser. peek_nth_token ( 2 ) . token ,
329
+ ) {
330
+ ( Token :: Word ( w) , Token :: Word ( w2) )
331
+ if w. keyword == Keyword :: TIME && w2. keyword == Keyword :: ZONE =>
332
+ {
333
+ Ok ( AT_TZ_PREC )
334
+ }
335
+ _ => Ok ( UNKNOWN_PREC ) ,
336
+ }
337
+ }
338
+
339
+ Token :: Word ( w) if w. keyword == Keyword :: NOT => match parser. peek_nth_token ( 1 ) . token {
340
+ // The precedence of NOT varies depending on keyword that
341
+ // follows it. If it is followed by IN, BETWEEN, or LIKE,
342
+ // it takes on the precedence of those tokens. Otherwise, it
343
+ // is not an infix operator, and therefore has zero
344
+ // precedence.
345
+ Token :: Word ( w) if w. keyword == Keyword :: IN => Ok ( BETWEEN_PREC ) ,
346
+ Token :: Word ( w) if w. keyword == Keyword :: BETWEEN => Ok ( BETWEEN_PREC ) ,
347
+ Token :: Word ( w) if w. keyword == Keyword :: LIKE => Ok ( LIKE_PREC ) ,
348
+ Token :: Word ( w) if w. keyword == Keyword :: ILIKE => Ok ( LIKE_PREC ) ,
349
+ Token :: Word ( w) if w. keyword == Keyword :: RLIKE => Ok ( LIKE_PREC ) ,
350
+ Token :: Word ( w) if w. keyword == Keyword :: REGEXP => Ok ( LIKE_PREC ) ,
351
+ Token :: Word ( w) if w. keyword == Keyword :: SIMILAR => Ok ( LIKE_PREC ) ,
352
+ _ => Ok ( UNKNOWN_PREC ) ,
353
+ } ,
354
+ Token :: Word ( w) if w. keyword == Keyword :: IS => Ok ( IS_PREC ) ,
355
+ Token :: Word ( w) if w. keyword == Keyword :: IN => Ok ( BETWEEN_PREC ) ,
356
+ Token :: Word ( w) if w. keyword == Keyword :: BETWEEN => Ok ( BETWEEN_PREC ) ,
357
+ Token :: Word ( w) if w. keyword == Keyword :: LIKE => Ok ( LIKE_PREC ) ,
358
+ Token :: Word ( w) if w. keyword == Keyword :: ILIKE => Ok ( LIKE_PREC ) ,
359
+ Token :: Word ( w) if w. keyword == Keyword :: RLIKE => Ok ( LIKE_PREC ) ,
360
+ Token :: Word ( w) if w. keyword == Keyword :: REGEXP => Ok ( LIKE_PREC ) ,
361
+ Token :: Word ( w) if w. keyword == Keyword :: SIMILAR => Ok ( LIKE_PREC ) ,
362
+ Token :: Word ( w) if w. keyword == Keyword :: OPERATOR => Ok ( BETWEEN_PREC ) ,
363
+ Token :: Word ( w) if w. keyword == Keyword :: DIV => Ok ( MUL_DIV_MOD_OP_PREC ) ,
364
+ Token :: Eq
365
+ | Token :: Lt
366
+ | Token :: LtEq
367
+ | Token :: Neq
368
+ | Token :: Gt
369
+ | Token :: GtEq
370
+ | Token :: DoubleEq
371
+ | Token :: Tilde
372
+ | Token :: TildeAsterisk
373
+ | Token :: ExclamationMarkTilde
374
+ | Token :: ExclamationMarkTildeAsterisk
375
+ | Token :: DoubleTilde
376
+ | Token :: DoubleTildeAsterisk
377
+ | Token :: ExclamationMarkDoubleTilde
378
+ | Token :: ExclamationMarkDoubleTildeAsterisk
379
+ | Token :: Spaceship => Ok ( EQ_PREC ) ,
380
+ Token :: Pipe => Ok ( PIPE_PREC ) ,
381
+ Token :: Caret | Token :: Sharp | Token :: ShiftRight | Token :: ShiftLeft => Ok ( CARET_PREC ) ,
382
+ Token :: Ampersand => Ok ( AMPERSAND_PREC ) ,
383
+ Token :: Plus | Token :: Minus => Ok ( PLUS_MINUS_PREC ) ,
384
+ Token :: Mul | Token :: Div | Token :: DuckIntDiv | Token :: Mod | Token :: StringConcat => {
385
+ Ok ( MUL_DIV_MOD_OP_PREC )
386
+ }
387
+ Token :: DoubleColon
388
+ | Token :: ExclamationMark
389
+ | Token :: LBracket
390
+ | Token :: Overlap
391
+ | Token :: CaretAt => Ok ( DOUBLE_COLON_PREC ) ,
392
+ // Token::Colon if (self as dyn Dialect).is::<SnowflakeDialect>() => Ok(DOUBLE_COLON_PREC),
393
+ Token :: Arrow
394
+ | Token :: LongArrow
395
+ | Token :: HashArrow
396
+ | Token :: HashLongArrow
397
+ | Token :: AtArrow
398
+ | Token :: ArrowAt
399
+ | Token :: HashMinus
400
+ | Token :: AtQuestion
401
+ | Token :: AtAt
402
+ | Token :: Question
403
+ | Token :: QuestionAnd
404
+ | Token :: QuestionPipe
405
+ | Token :: CustomBinaryOperator ( _) => Ok ( PG_OTHER_PREC ) ,
406
+ _ => Ok ( UNKNOWN_PREC ) ,
407
+ }
408
+ }
409
+
303
410
/// Dialect-specific statement parser override
304
411
fn parse_statement ( & self , _parser : & mut Parser ) -> Option < Result < Statement , ParserError > > {
305
412
// return None to fall back to the default behavior
306
413
None
307
414
}
415
+
416
+ /// The following precedence values are used directly by `Parse` or in dialects,
417
+ /// so have to be made public by the dialect.
418
+ fn prec_double_colon ( & self ) -> u8 {
419
+ DOUBLE_COLON_PREC
420
+ }
421
+
422
+ fn prec_mul_div_mod_op ( & self ) -> u8 {
423
+ MUL_DIV_MOD_OP_PREC
424
+ }
425
+
426
+ fn prec_plus_minus ( & self ) -> u8 {
427
+ PLUS_MINUS_PREC
428
+ }
429
+
430
+ fn prec_between ( & self ) -> u8 {
431
+ BETWEEN_PREC
432
+ }
433
+
434
+ fn prec_like ( & self ) -> u8 {
435
+ LIKE_PREC
436
+ }
437
+
438
+ fn prec_unary_not ( & self ) -> u8 {
439
+ UNARY_NOT_PREC
440
+ }
441
+
442
+ fn prec_unknown ( & self ) -> u8 {
443
+ UNKNOWN_PREC
444
+ }
308
445
}
309
446
447
+ // Define the lexical Precedence of operators.
448
+ //
449
+ // Uses (APPROXIMATELY) <https://www.postgresql.org/docs/7.0/operators.htm#AEN2026> as a reference
450
+ // higher number = higher precedence
451
+ //
452
+ // NOTE: The pg documentation is incomplete, e.g. the AT TIME ZONE operator
453
+ // actually has higher precedence than addition.
454
+ // See <https://postgrespro.com/list/thread-id/2673331>.
455
+ const DOUBLE_COLON_PREC : u8 = 50 ;
456
+ const AT_TZ_PREC : u8 = 41 ;
457
+ const MUL_DIV_MOD_OP_PREC : u8 = 40 ;
458
+ const PLUS_MINUS_PREC : u8 = 30 ;
459
+ const XOR_PREC : u8 = 24 ;
460
+ const AMPERSAND_PREC : u8 = 23 ;
461
+ const CARET_PREC : u8 = 22 ;
462
+ const PIPE_PREC : u8 = 21 ;
463
+ const BETWEEN_PREC : u8 = 20 ;
464
+ const EQ_PREC : u8 = 20 ;
465
+ const LIKE_PREC : u8 = 19 ;
466
+ const IS_PREC : u8 = 17 ;
467
+ const PG_OTHER_PREC : u8 = 16 ;
468
+ const UNARY_NOT_PREC : u8 = 15 ;
469
+ const AND_PREC : u8 = 10 ;
470
+ const OR_PREC : u8 = 5 ;
471
+ const UNKNOWN_PREC : u8 = 0 ;
472
+
310
473
impl dyn Dialect {
311
474
#[ inline]
312
475
pub fn is < T : Dialect > ( & self ) -> bool {
0 commit comments