diff --git a/proto/expr.proto b/proto/expr.proto index c6d8e2082fa7..e56668c99044 100644 --- a/proto/expr.proto +++ b/proto/expr.proto @@ -325,6 +325,7 @@ message ExprNode { HAS_SCHEMA_PRIVILEGE = 2409; PG_IS_IN_RECOVERY = 2411; RW_RECOVERY_STATUS = 2412; + RW_EPOCH_TO_TS = 2413; // EXTERNAL ICEBERG_TRANSFORM = 2201; diff --git a/src/frontend/src/binder/expr/function/builtin_scalar.rs b/src/frontend/src/binder/expr/function/builtin_scalar.rs index 68b37a3fee4e..66c28b0ba24d 100644 --- a/src/frontend/src/binder/expr/function/builtin_scalar.rs +++ b/src/frontend/src/binder/expr/function/builtin_scalar.rs @@ -661,6 +661,7 @@ impl Binder { ("shobj_description", raw_literal(ExprImpl::literal_varchar("".to_string()))), ("pg_is_in_recovery", raw_call(ExprType::PgIsInRecovery)), ("rw_recovery_status", raw_call(ExprType::RwRecoveryStatus)), + ("rw_epoch_to_ts", raw_call(ExprType::RwEpochToTs)), // internal ("rw_vnode", raw_call(ExprType::VnodeUser)), ("rw_test_paid_tier", raw_call(ExprType::TestPaidTier)), // for testing purposes diff --git a/src/frontend/src/expr/function_impl/mod.rs b/src/frontend/src/expr/function_impl/mod.rs index 4a1e0600dbc0..ed3082df54c4 100644 --- a/src/frontend/src/expr/function_impl/mod.rs +++ b/src/frontend/src/expr/function_impl/mod.rs @@ -22,4 +22,5 @@ mod pg_get_viewdef; mod pg_index_column_has_property; mod pg_indexes_size; mod pg_relation_size; +mod rw_epoch_to_ts; mod rw_recovery_status; diff --git a/src/frontend/src/expr/function_impl/rw_epoch_to_ts.rs b/src/frontend/src/expr/function_impl/rw_epoch_to_ts.rs new file mode 100644 index 000000000000..5522c1acc196 --- /dev/null +++ b/src/frontend/src/expr/function_impl/rw_epoch_to_ts.rs @@ -0,0 +1,22 @@ +// Copyright 2024 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use risingwave_common::types::Timestamptz; +use risingwave_common::util::epoch::Epoch; +use risingwave_expr::{function, Result}; + +#[function("rw_epoch_to_ts(int8) -> timestamptz")] +fn rw_epoch_to_ts(epoch: i64) -> Result { + Ok(Epoch(epoch as u64).as_timestamptz()) +} diff --git a/src/frontend/src/expr/pure.rs b/src/frontend/src/expr/pure.rs index 5e3bd968a46b..83a8cfa537ba 100644 --- a/src/frontend/src/expr/pure.rs +++ b/src/frontend/src/expr/pure.rs @@ -262,7 +262,8 @@ impl ExprVisitor for ImpureAnalyzer { | Type::MapDelete | Type::MapInsert | Type::MapLength - | Type::VnodeUser => + | Type::VnodeUser + |Type::RwEpochToTs => // expression output is deterministic(same result for the same input) { func_call diff --git a/src/frontend/src/optimizer/plan_expr_visitor/strong.rs b/src/frontend/src/optimizer/plan_expr_visitor/strong.rs index 890152f00e33..c53bde642ad3 100644 --- a/src/frontend/src/optimizer/plan_expr_visitor/strong.rs +++ b/src/frontend/src/optimizer/plan_expr_visitor/strong.rs @@ -326,7 +326,8 @@ impl Strong { | ExprType::HasAnyColumnPrivilege | ExprType::HasSchemaPrivilege | ExprType::InetAton - | ExprType::InetNtoa => false, + | ExprType::InetNtoa + | ExprType::RwEpochToTs => false, ExprType::Unspecified => unreachable!(), } }