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),

Reply via email to