Skip to content

Commit 664c4b0

Browse files
committed
[task #5568] add_to_unixtime_function
Signed-off-by: tangruilin <[email protected]>
1 parent 10d5f2d commit 664c4b0

File tree

9 files changed

+81
-0
lines changed

9 files changed

+81
-0
lines changed

datafusion/expr/src/built_in_function.rs

+8
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ pub enum BuiltinScalarFunction {
277277
FromUnixtime,
278278
/// to_date
279279
ToDate,
280+
/// to_unixtime
281+
ToUnixtime,
280282
///now
281283
Now,
282284
///current_date
@@ -475,6 +477,7 @@ impl BuiltinScalarFunction {
475477
BuiltinScalarFunction::Struct => Volatility::Immutable,
476478
BuiltinScalarFunction::FromUnixtime => Volatility::Immutable,
477479
BuiltinScalarFunction::ToDate => Volatility::Immutable,
480+
BuiltinScalarFunction::ToUnixtime => Volatility::Immutable,
478481
BuiltinScalarFunction::ArrowTypeof => Volatility::Immutable,
479482
BuiltinScalarFunction::OverLay => Volatility::Immutable,
480483
BuiltinScalarFunction::Levenshtein => Volatility::Immutable,
@@ -785,6 +788,7 @@ impl BuiltinScalarFunction {
785788
BuiltinScalarFunction::ToTimestampSeconds => Ok(Timestamp(Second, None)),
786789
BuiltinScalarFunction::FromUnixtime => Ok(Timestamp(Second, None)),
787790
BuiltinScalarFunction::ToDate => Ok(Date32),
791+
BuiltinScalarFunction::ToUnixtime => Ok(Int64),
788792
BuiltinScalarFunction::Now => {
789793
Ok(Timestamp(Nanosecond, Some("+00:00".into())))
790794
}
@@ -1063,6 +1067,9 @@ impl BuiltinScalarFunction {
10631067
Signature::uniform(1, vec![Int64], self.volatility())
10641068
}
10651069
BuiltinScalarFunction::ToDate => Signature::variadic_any(self.volatility()),
1070+
BuiltinScalarFunction::ToUnixtime => {
1071+
Signature::variadic_any(self.volatility())
1072+
}
10661073
BuiltinScalarFunction::Digest => Signature::one_of(
10671074
vec![
10681075
Exact(vec![Utf8, Utf8]),
@@ -1496,6 +1503,7 @@ impl BuiltinScalarFunction {
14961503
BuiltinScalarFunction::ToTimestampNanos => &["to_timestamp_nanos"],
14971504
BuiltinScalarFunction::FromUnixtime => &["from_unixtime"],
14981505
BuiltinScalarFunction::ToDate => &["to_date"],
1506+
BuiltinScalarFunction::ToUnixtime => &["to_unixtime"],
14991507

15001508
// hashing functions
15011509
BuiltinScalarFunction::Digest => &["digest"],

datafusion/physical-expr/src/datetime_expressions.rs

+31
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,37 @@ pub fn from_unixtime_invoke(args: &[ColumnarValue]) -> Result<ColumnarValue> {
18781878
}
18791879
}
18801880

1881+
/// to_unixtime() SQL function implementation
1882+
pub fn to_unixtime_invoke(args: &[ColumnarValue]) -> Result<ColumnarValue> {
1883+
if args.is_empty() {
1884+
return exec_err!(
1885+
"to_unixtime function requires 1 or more arguments, got {}",
1886+
args.len()
1887+
);
1888+
}
1889+
1890+
// validate that any args after the first one are Utf8
1891+
if args.len() > 1 {
1892+
if let Some(value) = validate_to_timestamp_data_types(args, "to_unixtime") {
1893+
return value;
1894+
}
1895+
}
1896+
1897+
match args[0].data_type() {
1898+
DataType::Null | DataType::Int32 | DataType::Int64 => Ok(args[0].clone()),
1899+
DataType::Timestamp(_, None) => cast_column(&args[0], &DataType::Int64, None),
1900+
DataType::Utf8 => {
1901+
cast_column(&to_timestamp_seconds(args)?, &DataType::Int64, None)
1902+
}
1903+
other => {
1904+
exec_err!(
1905+
"Unsupported data type {:?} for function to_unixtime function",
1906+
other
1907+
)
1908+
}
1909+
}
1910+
}
1911+
18811912
#[cfg(test)]
18821913
mod tests {
18831914
use std::sync::Arc;

datafusion/physical-expr/src/functions.rs

+3
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,9 @@ pub fn create_physical_fun(
523523
BuiltinScalarFunction::FromUnixtime => {
524524
Arc::new(datetime_expressions::from_unixtime_invoke)
525525
}
526+
BuiltinScalarFunction::ToUnixtime => {
527+
Arc::new(datetime_expressions::to_unixtime_invoke)
528+
}
526529
BuiltinScalarFunction::ToDate => Arc::new(datetime_expressions::to_date_invoke),
527530
BuiltinScalarFunction::InitCap => Arc::new(|args| match args[0].data_type() {
528531
DataType::Utf8 => {

datafusion/proto/proto/datafusion.proto

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
3+
34
* Licensed to the Apache Software Foundation (ASF) under one
45
* or more contributor license agreements. See the NOTICE file
56
* distributed with this work for additional information
@@ -684,6 +685,7 @@ enum ScalarFunction {
684685
RegexpLike = 135;
685686
ToChar = 136;
686687
ToDate = 137;
688+
ToUnixtime = 138;
687689
}
688690

689691
message ScalarFunctionNode {

datafusion/proto/src/generated/pbjson.rs

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/proto/src/generated/prost.rs

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/proto/src/logical_plan/from_proto.rs

+11
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ impl From<&protobuf::ScalarFunction> for BuiltinScalarFunction {
571571
ScalarFunction::SubstrIndex => Self::SubstrIndex,
572572
ScalarFunction::FindInSet => Self::FindInSet,
573573
ScalarFunction::ToDate => Self::ToDate,
574+
ScalarFunction::ToUnixtime => Self::ToUnixtime,
574575
}
575576
}
576577
}
@@ -1821,6 +1822,16 @@ pub fn parse_expr(
18211822
args,
18221823
)))
18231824
}
1825+
ScalarFunction::ToUnixtime => {
1826+
let args: Vec<_> = args
1827+
.iter()
1828+
.map(|expr| parse_expr(expr, registry))
1829+
.collect::<std::result::Result<_, _>>()?;
1830+
Ok(Expr::ScalarFunction(expr::ScalarFunction::new(
1831+
BuiltinScalarFunction::ToUnixtime,
1832+
args,
1833+
)))
1834+
}
18241835
}
18251836
}
18261837
ExprType::ScalarUdfExpr(protobuf::ScalarUdfExprNode { fun_name, args }) => {

datafusion/proto/src/logical_plan/to_proto.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,7 @@ impl TryFrom<&BuiltinScalarFunction> for protobuf::ScalarFunction {
15501550
BuiltinScalarFunction::SubstrIndex => Self::SubstrIndex,
15511551
BuiltinScalarFunction::FindInSet => Self::FindInSet,
15521552
BuiltinScalarFunction::ToDate => Self::ToDate,
1553+
BuiltinScalarFunction::ToUnixtime => Self::ToUnixtime,
15531554
};
15541555

15551556
Ok(scalar_function)

datafusion/sqllogictest/test_files/timestamps.slt

+19
Original file line numberDiff line numberDiff line change
@@ -2678,3 +2678,22 @@ SELECT to_char(null, '%d-%m-%Y');
26782678

26792679
statement ok
26802680
drop table formats;
2681+
2682+
##########
2683+
## to_unixtime tests
2684+
##########
2685+
2686+
query I
2687+
select to_unixtime('2020-09-08T12:00:00+00:00');
2688+
----
2689+
1599566400
2690+
2691+
query I
2692+
select to_unixtime('01-14-2023 01:01:30+05:30', '%q', '%d-%m-%Y %H/%M/%S', '%+', '%m-%d-%Y %H:%M:%S%#z');
2693+
----
2694+
1673638290
2695+
2696+
query I
2697+
select to_unixtime('03:59:00.123456789 05-17-2023', '%c', '%+', '%H:%M:%S%.f %m-%d-%Y');
2698+
----
2699+
1684295940

0 commit comments

Comments
 (0)