33
44use vortex_array:: ArrayView ;
55use vortex_array:: ExecutionCtx ;
6+ use vortex_array:: ProbeState ;
67use vortex_array:: dtype:: DType ;
78use vortex_array:: extension:: datetime:: Timestamp ;
89use vortex_array:: scalar:: Scalar ;
910use vortex_array:: vtable:: OperationsVTable ;
1011use vortex_error:: VortexExpect ;
1112use vortex_error:: VortexResult ;
13+ use vortex_error:: vortex_err;
1214use vortex_error:: vortex_panic;
1315
1416use crate :: DateTimeParts ;
15- use crate :: array :: DateTimePartsArraySlotsExt ;
17+ use crate :: DateTimePartsSlots ;
1618use crate :: timestamp;
1719use crate :: timestamp:: TimestampParts ;
1820
1921impl OperationsVTable < DateTimeParts > for DateTimeParts {
2022 type ProbeState = ( ) ;
2123
22- fn scalar_at (
23- array : ArrayView < ' _ , DateTimeParts > ,
24+ fn probe_scalar (
25+ state : & mut ProbeState < ' _ , DateTimeParts > ,
2426 index : usize ,
2527 ctx : & mut ExecutionCtx ,
2628 ) -> VortexResult < Scalar > {
29+ let array = state. array ( ) ;
2730 let DType :: Extension ( ext) = array. dtype ( ) . clone ( ) else {
2831 vortex_panic ! (
2932 "DateTimePartsArray must have extension dtype, found {}" ,
@@ -35,28 +38,19 @@ impl OperationsVTable<DateTimeParts> for DateTimeParts {
3538 vortex_panic ! ( Compute : "must decode TemporalMetadata from extension metadata" ) ;
3639 } ;
3740
38- if !array . as_ref ( ) . is_valid ( index, ctx) ? {
41+ if !state . is_valid ( index, ctx) ? {
3942 return Ok ( Scalar :: null ( DType :: Extension ( ext) ) ) ;
4043 }
4144
42- let days: i32 = array
43- . days ( )
44- . execute_scalar ( index, ctx) ?
45- . as_primitive ( )
46- . as_ :: < i32 > ( )
47- . vortex_expect ( "days fits in i32" ) ;
48- let seconds: i32 = array
49- . seconds ( )
50- . execute_scalar ( index, ctx) ?
51- . as_primitive ( )
52- . as_ :: < i32 > ( )
53- . vortex_expect ( "seconds fits in i32" ) ;
54- let subseconds: i32 = array
55- . subseconds ( )
56- . execute_scalar ( index, ctx) ?
57- . as_primitive ( )
58- . as_ :: < i32 > ( )
59- . vortex_expect ( "subseconds fits in i32" ) ;
45+ let days = part_at ( state, DateTimePartsSlots :: DAYS , "days" , index, ctx) ?;
46+ let seconds = part_at ( state, DateTimePartsSlots :: SECONDS , "seconds" , index, ctx) ?;
47+ let subseconds = part_at (
48+ state,
49+ DateTimePartsSlots :: SUBSECONDS ,
50+ "subseconds" ,
51+ index,
52+ ctx,
53+ ) ?;
6054
6155 let ts = timestamp:: combine (
6256 TimestampParts {
@@ -72,4 +66,30 @@ impl OperationsVTable<DateTimeParts> for DateTimeParts {
7266 Scalar :: primitive ( ts, ext. storage_dtype ( ) . nullability ( ) ) ,
7367 ) )
7468 }
69+
70+ fn scalar_at (
71+ array : ArrayView < ' _ , DateTimeParts > ,
72+ index : usize ,
73+ ctx : & mut ExecutionCtx ,
74+ ) -> VortexResult < Scalar > {
75+ Self :: probe_scalar ( & mut ProbeState :: once ( array) , index, ctx)
76+ }
77+ }
78+
79+ /// Reads one timestamp part out of `slot`, through the probe so a repeated read keeps the
80+ /// child's preparation.
81+ fn part_at (
82+ state : & mut ProbeState < ' _ , DateTimeParts > ,
83+ slot : usize ,
84+ name : & ' static str ,
85+ index : usize ,
86+ ctx : & mut ExecutionCtx ,
87+ ) -> VortexResult < i32 > {
88+ Ok ( state
89+ . slot ( slot) ?
90+ . ok_or_else ( || vortex_err ! ( "DateTimeParts {name} slot is missing" ) ) ?
91+ . execute_scalar ( index, ctx) ?
92+ . as_primitive ( )
93+ . as_ :: < i32 > ( )
94+ . vortex_expect ( "timestamp part fits in i32" ) )
7595}
0 commit comments