@@ -115,8 +115,8 @@ pub enum Expr {
115
115
IsNotUnknown ( Box < Expr > ) ,
116
116
/// arithmetic negation of an expression, the operand must be of a signed numeric data type
117
117
Negative ( Box < Expr > ) ,
118
- /// Returns the field of a [`arrow::array::ListArray`] or [`arrow::array::StructArray`] by key
119
- ///
118
+ /// Returns the field of a [`arrow::array::ListArray`] or
119
+ /// [`arrow::array::StructArray`] by index or range
120
120
GetIndexedField ( GetIndexedField ) ,
121
121
/// Whether an expression is between a given range.
122
122
Between ( Between ) ,
@@ -359,19 +359,20 @@ impl ScalarUDF {
359
359
}
360
360
}
361
361
362
+ /// Access a sub field of a nested type, such as `Field` or `List`
362
363
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
363
364
pub enum GetFieldAccess {
364
- /// returns the field `struct[field]`. For example `struct["name"]`
365
+ /// Named field, for example `struct["name"]`
365
366
NamedStructField { name : ScalarValue } ,
366
- /// single list index
367
- // list[i]
367
+ /// Single list index, for example: `list[i]`
368
368
ListIndex { key : Box < Expr > } ,
369
- /// list range `list[i:j]`
369
+ /// List range, for example `list[i:j]`
370
370
ListRange { start : Box < Expr > , stop : Box < Expr > } ,
371
371
}
372
372
373
- /// Returns the field of a [`arrow::array::ListArray`] or [`arrow::array::StructArray`] by `key`.
374
- /// If `extra_key` is not `None`, returns the slice of a [`arrow::array::ListArray`] in the range from `key` to `extra_key`.
373
+ /// Returns the field of a [`arrow::array::ListArray`] or
374
+ /// [`arrow::array::StructArray`] by `key`. See [`GetFieldAccess`] for
375
+ /// details.
375
376
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
376
377
pub struct GetIndexedField {
377
378
/// The expression to take the field from
@@ -925,6 +926,90 @@ impl Expr {
925
926
) )
926
927
}
927
928
929
+ /// Return access to the named field. Example `expr["name"]`
930
+ ///
931
+ /// ## Access field "my_field" from column "c1"
932
+ ///
933
+ /// For example if column "c1" holds documents like this
934
+ ///
935
+ /// ```json
936
+ /// {
937
+ /// "my_field": 123.34,
938
+ /// "other_field": "Boston",
939
+ /// }
940
+ /// ```
941
+ ///
942
+ /// You can access column "my_field" with
943
+ ///
944
+ /// ```
945
+ /// # use datafusion_expr::{col};
946
+ /// let expr = col("c1")
947
+ /// .field("my_field");
948
+ /// assert_eq!(expr.display_name().unwrap(), "c1[my_field]");
949
+ /// ```
950
+ pub fn field ( self , name : impl Into < String > ) -> Self {
951
+ Expr :: GetIndexedField ( GetIndexedField {
952
+ expr : Box :: new ( self ) ,
953
+ field : GetFieldAccess :: NamedStructField {
954
+ name : ScalarValue :: Utf8 ( Some ( name. into ( ) ) ) ,
955
+ } ,
956
+ } )
957
+ }
958
+
959
+ /// Return access to the element field. Example `expr["name"]`
960
+ ///
961
+ /// ## Example Access element 2 from column "c1"
962
+ ///
963
+ /// For example if column "c1" holds documents like this
964
+ ///
965
+ /// ```json
966
+ /// [10, 20, 30, 40]
967
+ /// ```
968
+ ///
969
+ /// You can access the value "30" with
970
+ ///
971
+ /// ```
972
+ /// # use datafusion_expr::{lit, col, Expr};
973
+ /// let expr = col("c1")
974
+ /// .index(lit(3));
975
+ /// assert_eq!(expr.display_name().unwrap(), "c1[Int32(3)]");
976
+ /// ```
977
+ pub fn index ( self , key : Expr ) -> Self {
978
+ Expr :: GetIndexedField ( GetIndexedField {
979
+ expr : Box :: new ( self ) ,
980
+ field : GetFieldAccess :: ListIndex { key : Box :: new ( key) } ,
981
+ } )
982
+ }
983
+
984
+ /// Return elements between `1` based `start` and `stop`, for
985
+ /// example `expr[1:3]`
986
+ ///
987
+ /// ## Example: Access element 2, 3, 4 from column "c1"
988
+ ///
989
+ /// For example if column "c1" holds documents like this
990
+ ///
991
+ /// ```json
992
+ /// [10, 20, 30, 40]
993
+ /// ```
994
+ ///
995
+ /// You can access the value `[20, 30, 40]` with
996
+ ///
997
+ /// ```
998
+ /// # use datafusion_expr::{lit, col};
999
+ /// let expr = col("c1")
1000
+ /// .range(lit(2), lit(4));
1001
+ /// assert_eq!(expr.display_name().unwrap(), "c1[Int32(2):Int32(4)]");
1002
+ /// ```
1003
+ pub fn range ( self , start : Expr , stop : Expr ) -> Self {
1004
+ Expr :: GetIndexedField ( GetIndexedField {
1005
+ expr : Box :: new ( self ) ,
1006
+ field : GetFieldAccess :: ListRange {
1007
+ start : Box :: new ( start) ,
1008
+ stop : Box :: new ( stop) ,
1009
+ } ,
1010
+ } )
1011
+ }
1012
+
928
1013
pub fn try_into_col ( & self ) -> Result < Column > {
929
1014
match self {
930
1015
Expr :: Column ( it) => Ok ( it. clone ( ) ) ,
0 commit comments