Skip to content

Commit 1488e10

Browse files
feat(substrait): add time literal support (#17655)
Adds support for `ScalarValue::Time64Microsecond` and `ScalarValue::Time64Nanosecond` to be converted to and from Substrait literals. This includes the `PrecisionTime` literal type and specific `TIME_64_TYPE_VARIATION_REF` for 6-digit (microseconds) and 9-digit (nanoseconds) precision. Co-authored-by: Bruno Volpato <[email protected]>
1 parent 03b6789 commit 1488e10

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

datafusion/substrait/src/logical_plan/consumer/expr/literal.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use crate::variation_const::{
2525
INTERVAL_MONTH_DAY_NANO_TYPE_REF, INTERVAL_YEAR_MONTH_TYPE_REF,
2626
LARGE_CONTAINER_TYPE_VARIATION_REF, TIMESTAMP_MICRO_TYPE_VARIATION_REF,
2727
TIMESTAMP_MILLI_TYPE_VARIATION_REF, TIMESTAMP_NANO_TYPE_VARIATION_REF,
28-
TIMESTAMP_SECOND_TYPE_VARIATION_REF, UNSIGNED_INTEGER_TYPE_VARIATION_REF,
29-
VIEW_CONTAINER_TYPE_VARIATION_REF,
28+
TIMESTAMP_SECOND_TYPE_VARIATION_REF, TIME_64_TYPE_VARIATION_REF,
29+
UNSIGNED_INTEGER_TYPE_VARIATION_REF, VIEW_CONTAINER_TYPE_VARIATION_REF,
3030
};
3131
use datafusion::arrow::array::{new_empty_array, AsArray, MapArray};
3232
use datafusion::arrow::buffer::OffsetBuffer;
@@ -155,6 +155,29 @@ pub(crate) fn from_substrait_literal(
155155
}
156156
},
157157
Some(LiteralType::Date(d)) => ScalarValue::Date32(Some(*d)),
158+
Some(LiteralType::PrecisionTime(pt)) => match pt.precision {
159+
6 => match lit.type_variation_reference {
160+
TIME_64_TYPE_VARIATION_REF => {
161+
ScalarValue::Time64Microsecond(Some(pt.value))
162+
}
163+
others => {
164+
return substrait_err!("Unknown type variation reference {others}");
165+
}
166+
},
167+
9 => match lit.type_variation_reference {
168+
TIME_64_TYPE_VARIATION_REF => {
169+
ScalarValue::Time64Nanosecond(Some(pt.value))
170+
}
171+
others => {
172+
return substrait_err!("Unknown type variation reference {others}");
173+
}
174+
},
175+
p => {
176+
return not_impl_err!(
177+
"Unsupported Substrait precision {p} for PrecisionTime"
178+
);
179+
}
180+
},
158181
Some(LiteralType::String(s)) => match lit.type_variation_reference {
159182
DEFAULT_CONTAINER_TYPE_VARIATION_REF => ScalarValue::Utf8(Some(s.clone())),
160183
LARGE_CONTAINER_TYPE_VARIATION_REF => ScalarValue::LargeUtf8(Some(s.clone())),

datafusion/substrait/src/logical_plan/producer/expr/literal.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use crate::logical_plan::producer::{to_substrait_type, SubstraitProducer};
1919
use crate::variation_const::{
2020
DATE_32_TYPE_VARIATION_REF, DECIMAL_128_TYPE_VARIATION_REF,
2121
DEFAULT_CONTAINER_TYPE_VARIATION_REF, DEFAULT_TYPE_VARIATION_REF,
22-
LARGE_CONTAINER_TYPE_VARIATION_REF, UNSIGNED_INTEGER_TYPE_VARIATION_REF,
23-
VIEW_CONTAINER_TYPE_VARIATION_REF,
22+
LARGE_CONTAINER_TYPE_VARIATION_REF, TIME_64_TYPE_VARIATION_REF,
23+
UNSIGNED_INTEGER_TYPE_VARIATION_REF, VIEW_CONTAINER_TYPE_VARIATION_REF,
2424
};
2525
use datafusion::arrow::array::{Array, GenericListArray, OffsetSizeTrait};
2626
use datafusion::arrow::temporal_conversions::NANOSECONDS;
@@ -29,7 +29,7 @@ use substrait::proto::expression::literal::interval_day_to_second::PrecisionMode
2929
use substrait::proto::expression::literal::map::KeyValue;
3030
use substrait::proto::expression::literal::{
3131
Decimal, IntervalCompound, IntervalDayToSecond, IntervalYearToMonth, List,
32-
LiteralType, Map, PrecisionTimestamp, Struct,
32+
LiteralType, Map, PrecisionTime, PrecisionTimestamp, Struct,
3333
};
3434
use substrait::proto::expression::{Literal, RexType};
3535
use substrait::proto::{r#type, Expression};
@@ -280,6 +280,20 @@ pub(crate) fn to_substrait_literal(
280280
};
281281
(map, DEFAULT_CONTAINER_TYPE_VARIATION_REF)
282282
}
283+
ScalarValue::Time64Microsecond(Some(t)) => (
284+
LiteralType::PrecisionTime(PrecisionTime {
285+
precision: 6,
286+
value: *t,
287+
}),
288+
TIME_64_TYPE_VARIATION_REF,
289+
),
290+
ScalarValue::Time64Nanosecond(Some(t)) => (
291+
LiteralType::PrecisionTime(PrecisionTime {
292+
precision: 9,
293+
value: *t,
294+
}),
295+
TIME_64_TYPE_VARIATION_REF,
296+
),
283297
ScalarValue::Struct(s) => (
284298
LiteralType::Struct(Struct {
285299
fields: s
@@ -398,6 +412,12 @@ mod tests {
398412
round_trip_literal(ScalarValue::TimestampNanosecond(ts, tz))?;
399413
}
400414

415+
// Test Time64 literals
416+
round_trip_literal(ScalarValue::Time64Microsecond(Some(45296789123)))?;
417+
round_trip_literal(ScalarValue::Time64Microsecond(None))?;
418+
round_trip_literal(ScalarValue::Time64Nanosecond(Some(45296789123000)))?;
419+
round_trip_literal(ScalarValue::Time64Nanosecond(None))?;
420+
401421
round_trip_literal(ScalarValue::List(ScalarValue::new_list_nullable(
402422
&[ScalarValue::Float32(Some(1.0))],
403423
&DataType::Float32,

0 commit comments

Comments
 (0)