@@ -24,12 +24,13 @@ mod redshift;
2424mod snowflake;
2525mod sqlite;
2626
27- use crate :: ast:: { Expr , Statement } ;
2827use core:: any:: { Any , TypeId } ;
2928use core:: fmt:: Debug ;
3029use core:: iter:: Peekable ;
3130use core:: str:: Chars ;
3231
32+ use log:: debug;
33+
3334pub use self :: ansi:: AnsiDialect ;
3435pub use self :: bigquery:: BigQueryDialect ;
3536pub use self :: clickhouse:: ClickHouseDialect ;
@@ -43,8 +44,11 @@ pub use self::postgresql::PostgreSqlDialect;
4344pub use self :: redshift:: RedshiftSqlDialect ;
4445pub use self :: snowflake:: SnowflakeDialect ;
4546pub use self :: sqlite:: SQLiteDialect ;
47+ use crate :: ast:: { Expr , Statement } ;
4648pub use crate :: keywords;
49+ use crate :: keywords:: Keyword ;
4750use crate :: parser:: { Parser , ParserError } ;
51+ use crate :: tokenizer:: Token ;
4852
4953#[ cfg( not( feature = "std" ) ) ]
5054use alloc:: boxed:: Box ;
@@ -300,13 +304,172 @@ pub trait Dialect: Debug + Any {
300304 // return None to fall back to the default behavior
301305 None
302306 }
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+
303410 /// Dialect-specific statement parser override
304411 fn parse_statement ( & self , _parser : & mut Parser ) -> Option < Result < Statement , ParserError > > {
305412 // return None to fall back to the default behavior
306413 None
307414 }
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+ }
308445}
309446
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+
310473impl dyn Dialect {
311474 #[ inline]
312475 pub fn is < T : Dialect > ( & self ) -> bool {
0 commit comments