1515use ethnum:: i256;
1616use itertools:: Itertools ;
1717use nom:: combinator:: consumed;
18+ use nom:: combinator:: verify;
1819use nom:: error:: context;
1920use nom:: Parser ;
2021use nom_rule:: rule;
@@ -32,6 +33,7 @@ use crate::parser::query::*;
3233use crate :: parser:: token:: * ;
3334use crate :: parser:: Error ;
3435use crate :: parser:: ErrorKind ;
36+ use crate :: span:: merge_span;
3537use crate :: Span ;
3638
3739macro_rules! with_span {
@@ -819,15 +821,42 @@ impl<'a, I: Iterator<Item = WithSpan<'a, ExprElement>>> PrattParser<I> for ExprP
819821 }
820822
821823 fn prefix ( & mut self , elem : WithSpan < ' a , ExprElement > , rhs : Expr ) -> Result < Expr , & ' static str > {
822- let expr = match elem. elem {
823- ExprElement :: UnaryOp { op } => Expr :: UnaryOp {
824- span : transform_span ( elem. span . tokens ) ,
825- op,
826- expr : Box :: new ( rhs) ,
827- } ,
824+ match elem. elem {
825+ ExprElement :: UnaryOp { op } => {
826+ let op_span = transform_span ( elem. span . tokens ) ;
827+ match ( op, rhs) {
828+ (
829+ UnaryOperator :: Minus ,
830+ Expr :: Literal {
831+ span : rhs_span,
832+ value,
833+ } ,
834+ ) => {
835+ if let Some ( value) = try_negate_literal ( & value) {
836+ Ok ( Expr :: Literal {
837+ span : merge_span ( op_span, rhs_span) ,
838+ value,
839+ } )
840+ } else {
841+ Ok ( Expr :: UnaryOp {
842+ span : op_span,
843+ op : UnaryOperator :: Minus ,
844+ expr : Box :: new ( Expr :: Literal {
845+ span : rhs_span,
846+ value,
847+ } ) ,
848+ } )
849+ }
850+ }
851+ ( op, rhs_expr) => Ok ( Expr :: UnaryOp {
852+ span : op_span,
853+ op,
854+ expr : Box :: new ( rhs_expr) ,
855+ } ) ,
856+ }
857+ }
828858 _ => unreachable ! ( ) ,
829- } ;
830- Ok ( expr)
859+ }
831860 }
832861
833862 fn postfix (
@@ -1230,7 +1259,7 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
12301259 rule ! {
12311260 "." ~ #column_id
12321261 } ,
1233- |( _, key ) | ExprElement :: DotAccess { key } ,
1262+ |( _, column ) | ExprElement :: DotAccess { key : column } ,
12341263 ) ;
12351264
12361265 let chain_function_call = check_experimental_chain_function (
@@ -1550,6 +1579,74 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
15501579 let stage_location = map ( rule ! { #at_string } , |location| {
15511580 ExprElement :: StageLocation { location }
15521581 } ) ;
1582+ let string = map ( literal_string, |literal| ExprElement :: Literal {
1583+ value : Literal :: String ( literal) ,
1584+ } ) ;
1585+ let code_string = map ( code_string, |literal| ExprElement :: Literal {
1586+ value : Literal :: String ( literal) ,
1587+ } ) ;
1588+ let boolean = map ( literal_bool, |literal| ExprElement :: Literal {
1589+ value : Literal :: Boolean ( literal) ,
1590+ } ) ;
1591+ let null = value (
1592+ ExprElement :: Literal {
1593+ value : Literal :: Null ,
1594+ } ,
1595+ rule ! { NULL } ,
1596+ ) ;
1597+ let decimal_uint = map_res (
1598+ rule ! {
1599+ LiteralInteger
1600+ } ,
1601+ |token| {
1602+ Ok ( ExprElement :: Literal {
1603+ value : parse_uint ( token. text ( ) , 10 ) . map_err ( nom:: Err :: Failure ) ?,
1604+ } )
1605+ } ,
1606+ ) ;
1607+ let hex_uint = map_res ( literal_hex_str, |str| {
1608+ Ok ( ExprElement :: Literal {
1609+ value : parse_uint ( str, 16 ) . map_err ( nom:: Err :: Failure ) ?,
1610+ } )
1611+ } ) ;
1612+ let decimal_float = map_res (
1613+ verify (
1614+ rule ! {
1615+ LiteralFloat
1616+ } ,
1617+ |token : & Token | !token. text ( ) . starts_with ( '.' ) ,
1618+ ) ,
1619+ |token| {
1620+ Ok ( ExprElement :: Literal {
1621+ value : parse_float ( token. text ( ) ) . map_err ( nom:: Err :: Failure ) ?,
1622+ } )
1623+ } ,
1624+ ) ;
1625+ let column_position = map ( column_position, |column| ExprElement :: ColumnRef {
1626+ column : ColumnRef {
1627+ database : None ,
1628+ table : None ,
1629+ column,
1630+ } ,
1631+ } ) ;
1632+ let column_row = map ( column_row, |column| ExprElement :: ColumnRef {
1633+ column : ColumnRef {
1634+ database : None ,
1635+ table : None ,
1636+ column,
1637+ } ,
1638+ } ) ;
1639+ let column_ident = map ( column_ident, |column| ExprElement :: ColumnRef {
1640+ column : ColumnRef {
1641+ database : None ,
1642+ table : None ,
1643+ column,
1644+ } ,
1645+ } ) ;
1646+
1647+ if i. tokens . first ( ) . map ( |token| token. kind ) == Some ( ColumnPosition ) {
1648+ return with_span ! ( column_position) . parse ( i) ;
1649+ }
15531650
15541651 try_dispatch ! ( i, true ,
15551652 IS => with_span!( rule!( #is_null | #is_distinct_from) ) . parse( i) ,
@@ -1656,6 +1753,14 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
16561753 | AtAt
16571754 | HashMinus => with_span!( json_op) . parse( i) ,
16581755 Factorial | SquareRoot | BitWiseNot | CubeRoot | Abs => with_span!( unary_op) . parse( i) ,
1756+ LiteralString => with_span!( string) . parse( i) ,
1757+ LiteralCodeString => with_span!( code_string) . parse( i) ,
1758+ LiteralInteger => with_span!( decimal_uint) . parse( i) ,
1759+ LiteralFloat => with_span!( decimal_float) . parse( i) ,
1760+ MySQLLiteralHex | PGLiteralHex => with_span!( hex_uint) . parse( i) ,
1761+ TRUE | FALSE => with_span!( boolean) . parse( i) ,
1762+ NULL => with_span!( null) . parse( i) ,
1763+ ROW => with_span!( column_row) . parse( i) ,
16591764 ) ;
16601765
16611766 // The try-parse operation in the function call is very expensive, easy to stack overflow
@@ -1669,7 +1774,7 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
16691774 }
16701775
16711776 with_span ! ( alt( ( rule!(
1672- #column_ref : "<column>"
1777+ #column_ident : "<column>"
16731778 | #dot_number_map_access : ".<key>"
16741779 | #literal : "<literal>"
16751780 ) , ) ) )
@@ -2722,6 +2827,27 @@ pub fn parse_uint(text: &str, radix: u32) -> Result<Literal, ErrorKind> {
27222827 }
27232828}
27242829
2830+ fn try_negate_literal ( literal : & Literal ) -> Option < Literal > {
2831+ match literal {
2832+ Literal :: UInt64 ( value) => Some ( Literal :: Decimal256 {
2833+ value : -i256:: from ( * value) ,
2834+ precision : 76 ,
2835+ scale : 0 ,
2836+ } ) ,
2837+ Literal :: Decimal256 {
2838+ value,
2839+ precision,
2840+ scale,
2841+ } => Some ( Literal :: Decimal256 {
2842+ value : -* value,
2843+ precision : * precision,
2844+ scale : * scale,
2845+ } ) ,
2846+ Literal :: Float64 ( value) => Some ( Literal :: Float64 ( -value) ) ,
2847+ _ => None ,
2848+ }
2849+ }
2850+
27252851pub ( crate ) fn make_func_get_variable ( span : Span , name : String ) -> Expr {
27262852 Expr :: FunctionCall {
27272853 span,
0 commit comments