@@ -679,7 +679,7 @@ pub enum Expr {
679679 } ,
680680 /// Access a map-like object by field (e.g. `column['field']` or `column[4]`
681681 /// Note that depending on the dialect, struct like accesses may be
682- /// parsed as [`ArrayIndex `](Self::ArrayIndex ) or [`MapAccess`](Self::MapAccess)
682+ /// parsed as [`Subscript `](Self::Subscript ) or [`MapAccess`](Self::MapAccess)
683683 /// <https://clickhouse.com/docs/en/sql-reference/data-types/map/>
684684 MapAccess {
685685 column : Box < Expr > ,
@@ -746,10 +746,10 @@ pub enum Expr {
746746 /// ```
747747 /// [1]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
748748 Dictionary ( Vec < DictionaryField > ) ,
749- /// An array index expression e.g. `(ARRAY[1, 2])[1]` or `(current_schemas(FALSE))[1]`
750- ArrayIndex {
751- obj : Box < Expr > ,
752- indexes : Vec < Expr > ,
749+ /// An access of nested data using subscript syntax, for example `array[2]`.
750+ Subscript {
751+ expr : Box < Expr > ,
752+ subscript : Box < Subscript > ,
753753 } ,
754754 /// An array expression e.g. `ARRAY[1, 2]`
755755 Array ( Array ) ,
@@ -805,6 +805,68 @@ pub enum Expr {
805805 Lambda ( LambdaFunction ) ,
806806}
807807
808+ /// The contents inside the `[` and `]` in a subscript expression.
809+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
810+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
811+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
812+ pub enum Subscript {
813+ /// Accesses the element of the array at the given index.
814+ Index { index : Expr } ,
815+
816+ /// Accesses a slice of an array on PostgreSQL, e.g.
817+ ///
818+ /// ```plaintext
819+ /// => select (array[1,2,3,4,5,6])[2:5];
820+ /// -----------
821+ /// {2,3,4,5}
822+ /// ```
823+ ///
824+ /// The lower and/or upper bound can be omitted to slice from the start or
825+ /// end of the array respectively.
826+ ///
827+ /// See <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING>.
828+ ///
829+ /// Also supports an optional "stride" as the last element (this is not
830+ /// supported by postgres), e.g.
831+ ///
832+ /// ```plaintext
833+ /// => select (array[1,2,3,4,5,6])[1:6:2];
834+ /// -----------
835+ /// {1,3,5}
836+ /// ```
837+ Slice {
838+ lower_bound : Option < Expr > ,
839+ upper_bound : Option < Expr > ,
840+ stride : Option < Expr > ,
841+ } ,
842+ }
843+
844+ impl fmt:: Display for Subscript {
845+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
846+ match self {
847+ Subscript :: Index { index } => write ! ( f, "{index}" ) ,
848+ Subscript :: Slice {
849+ lower_bound,
850+ upper_bound,
851+ stride,
852+ } => {
853+ if let Some ( lower) = lower_bound {
854+ write ! ( f, "{lower}" ) ?;
855+ }
856+ write ! ( f, ":" ) ?;
857+ if let Some ( upper) = upper_bound {
858+ write ! ( f, "{upper}" ) ?;
859+ }
860+ if let Some ( stride) = stride {
861+ write ! ( f, ":" ) ?;
862+ write ! ( f, "{stride}" ) ?;
863+ }
864+ Ok ( ( ) )
865+ }
866+ }
867+ }
868+ }
869+
808870/// A lambda function.
809871#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
810872#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -1251,12 +1313,11 @@ impl fmt::Display for Expr {
12511313 Expr :: Dictionary ( fields) => {
12521314 write ! ( f, "{{{}}}" , display_comma_separated( fields) )
12531315 }
1254- Expr :: ArrayIndex { obj, indexes } => {
1255- write ! ( f, "{obj}" ) ?;
1256- for i in indexes {
1257- write ! ( f, "[{i}]" ) ?;
1258- }
1259- Ok ( ( ) )
1316+ Expr :: Subscript {
1317+ expr,
1318+ subscript : key,
1319+ } => {
1320+ write ! ( f, "{expr}[{key}]" )
12601321 }
12611322 Expr :: Array ( set) => {
12621323 write ! ( f, "{set}" )
0 commit comments