This is an automated email from the ASF dual-hosted git repository.
gangwu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-cpp.git
The following commit(s) were added to refs/heads/main by this push:
new 282b582 feat: add literal cast to date (#270)
282b582 is described below
commit 282b582082e2d549c15abb6f11ea313b1029fb4a
Author: Junwang Zhao <[email protected]>
AuthorDate: Thu Oct 23 09:41:12 2025 +0800
feat: add literal cast to date (#270)
---
src/iceberg/expression/literal.cc | 13 +++++++----
src/iceberg/test/literal_test.cc | 46 +++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/src/iceberg/expression/literal.cc
b/src/iceberg/expression/literal.cc
index aea719c..a1222ff 100644
--- a/src/iceberg/expression/literal.cc
+++ b/src/iceberg/expression/literal.cc
@@ -27,6 +27,7 @@
#include "iceberg/util/checked_cast.h"
#include "iceberg/util/conversions.h"
#include "iceberg/util/macros.h"
+#include "iceberg/util/temporal_util.h"
namespace iceberg {
@@ -209,8 +210,10 @@ Result<Literal> LiteralCaster::CastFromTimestamp(
auto timestamp_val = std::get<int64_t>(literal.value_);
switch (target_type->type_id()) {
- case TypeId::kDate:
- return NotImplemented("Cast from Timestamp to Date is not implemented
yet");
+ case TypeId::kDate: {
+ ICEBERG_ASSIGN_OR_RAISE(auto days, TemporalUtils::ExtractDay(literal));
+ return Literal::Date(std::get<int32_t>(days.value()));
+ }
case TypeId::kTimestampTz:
return Literal::TimestampTz(timestamp_val);
default:
@@ -224,8 +227,10 @@ Result<Literal> LiteralCaster::CastFromTimestampTz(
auto micros = std::get<int64_t>(literal.value_);
switch (target_type->type_id()) {
- case TypeId::kDate:
- return NotImplemented("Cast from TimestampTz to Date is not implemented
yet");
+ case TypeId::kDate: {
+ ICEBERG_ASSIGN_OR_RAISE(auto days, TemporalUtils::ExtractDay(literal));
+ return Literal::Date(std::get<int32_t>(days.value()));
+ }
case TypeId::kTimestamp:
return Literal::Timestamp(micros);
default:
diff --git a/src/iceberg/test/literal_test.cc b/src/iceberg/test/literal_test.cc
index 0dd291d..ca2a406 100644
--- a/src/iceberg/test/literal_test.cc
+++ b/src/iceberg/test/literal_test.cc
@@ -27,6 +27,7 @@
#include "iceberg/type.h"
#include "matchers.h"
+#include "temporal_test_helper.h"
namespace iceberg {
@@ -689,6 +690,51 @@ INSTANTIATE_TEST_SUITE_P(
.source_literal = Literal::Long(42L),
.target_type = timestamp_tz(),
.expected_literal = Literal::TimestampTz(42L)},
+ CastLiteralTestParam{
+ .test_name = "TimestampToDate",
+ .source_literal =
+ Literal::Timestamp(TemporalTestHelper::CreateTimestamp({.year
= 2021,
+ .month
= 6,
+ .day =
1,
+ .hour
= 11,
+
.minute = 43,
+
.second = 20})),
+ .target_type = date(),
+ .expected_literal = Literal::Date(
+ TemporalTestHelper::CreateDate({.year = 2021, .month = 6, .day
= 1}))},
+ CastLiteralTestParam{
+ .test_name = "TimestampTzToDate",
+ .source_literal = Literal::TimestampTz(
+ TemporalTestHelper::CreateTimestampTz({.year = 2021,
+ .month = 1,
+ .day = 1,
+ .hour = 7,
+ .minute = 43,
+ .second = 20,
+ .tz_offset_minutes =
480})),
+ .target_type = date(),
+ .expected_literal = Literal::Date(
+ TemporalTestHelper::CreateDate({.year = 2020, .month = 12,
.day = 31}))},
+ CastLiteralTestParam{.test_name = "EpochToDate",
+ .source_literal = Literal::Timestamp(
+ TemporalTestHelper::CreateTimestamp({.year =
1970,
+ .month =
1,
+ .day = 1,
+ .hour =
0,
+ .minute
= 0,
+ .second
= 0})),
+ .target_type = date(),
+ .expected_literal = Literal::Date(0)},
+ CastLiteralTestParam{.test_name = "TimestampBeforeEpochToDate",
+ .source_literal = Literal::Timestamp(
+ TemporalTestHelper::CreateTimestamp({.year =
1969,
+ .month =
12,
+ .day =
31,
+ .hour =
23,
+ .minute
= 59,
+ .second
= 59})),
+ .target_type = date(),
+ .expected_literal = Literal::Date(-1)},
// Float cast tests
CastLiteralTestParam{.test_name = "FloatToDouble",
.source_literal = Literal::Float(2.0f),