wgtmac commented on code in PR #206:
URL: https://github.com/apache/iceberg-cpp/pull/206#discussion_r2342875443


##########
src/iceberg/expression/literal.cc:
##########
@@ -285,23 +568,29 @@ std::string Literal::ToString() const {
     case TypeId::kString: {
       return std::get<std::string>(value_);
     }
-    case TypeId::kBinary: {
+    case TypeId::kBinary:
+    case TypeId::kFixed: {
       const auto& binary_data = std::get<std::vector<uint8_t>>(value_);
-      std::string result;
-      result.reserve(binary_data.size() * 2);  // 2 chars per byte
+      std::string result = "X'";
+      result.reserve(2 + binary_data.size() * 2 +
+                     1);  // 2 chars per byte and 2 + 1 for prefix and suffix

Review Comment:
   ```suggestion
         result.reserve(/*prefix*/2 + binary_data.size() * 2 + /*suffix*/1);
   ```



##########
src/iceberg/expression/literal.h:
##########
@@ -27,6 +27,8 @@
 
 #include "iceberg/result.h"
 #include "iceberg/type.h"
+#include "iceberg/util/decimal.h"

Review Comment:
   ```suggestion
   ```
   
   We don't need this in this header file.



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);

Review Comment:
   ditto



##########
src/iceberg/expression/literal.h:
##########
@@ -71,6 +74,11 @@ class ICEBERG_EXPORT Literal {
   static Literal Double(double value);
   static Literal String(std::string value);
   static Literal Binary(std::vector<uint8_t> value);
+  static Literal Fixed(std::vector<uint8_t> value);
+
+  /// \brief Factory methods for decimal type
+  static Literal Decimal(const Decimal& value, int32_t precision, int32_t 
scale);
+  static Literal Decimal(int128_t value, int32_t precision, int32_t scale);

Review Comment:
   ```suggestion
     static Literal Decimal(int128_t value, int32_t precision, int32_t scale);
   ```
   
   - Decimal type is also a primitive type so let's put them together without 
blank line.
   - I think `int128_t` is enough and it duplicates with `Decimal`
   
   
   



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));

Review Comment:
   ```suggestion
         int32_t parsed_scale = 0;
         ICEBERG_ASSIGN_OR_RAISE(
             auto parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));

Review Comment:
   ```suggestion
             parsed_val, iceberg::Decimal::FromString(float_str, 
/*precision=*/nullptr, &parsed_scale));
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));

Review Comment:
   ```suggestion
         ICEBERG_ASSIGN_OR_RAISE(auto rescaled_val,
                                 parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
+
+      return Literal::Decimal(rescaled_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
     default:
       return NotSupported("Cast from Float to {} is not supported",
                           target_type->ToString());
   }
 }
 
+Result<Literal> LiteralCaster::CastFromDouble(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  auto double_val = std::get<double>(literal.value_);
+
+  switch (target_type->type_id()) {
+    case TypeId::kFloat: {
+      if (double_val > static_cast<double>(std::numeric_limits<float>::max())) 
{
+        return AboveMaxLiteral(target_type);
+      }
+      if (double_val < 
static_cast<double>(std::numeric_limits<float>::lowest())) {
+        return BelowMinLiteral(target_type);
+      }
+      return Literal::Float(static_cast<float>(double_val));
+    }
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string double_str = std::to_string(double_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(double_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));

Review Comment:
   ```suggestion
         int32_t parsed_scale = 0;
         ICEBERG_ASSIGN_OR_RAISE(
             auto parsed_val, iceberg::Decimal::FromString(double_str, 
/*precision=*/nullptr, &parsed_scale));
         iceberg::Decimal rescaled_val;
         ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
                                 parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -243,19 +445,33 @@ std::partial_ordering Literal::operator<=>(const Literal& 
other) const {
       return this_val <=> other_val;
     }
 
-    case TypeId::kBinary: {
+    case TypeId::kBinary:
+    case TypeId::kFixed: {
       auto& this_val = std::get<std::vector<uint8_t>>(value_);
       auto& other_val = std::get<std::vector<uint8_t>>(other.value_);
       return this_val <=> other_val;
     }
 
+    case TypeId::kDecimal: {
+      auto this_val = std::get<int128_t>(value_);
+      auto other_val = std::get<int128_t>(other.value_);
+      return this_val <=> other_val;
+    }
+
     default:
       // For unsupported types, return unordered
       return std::partial_ordering::unordered;
   }
 }
 
 std::string Literal::ToString() const {
+  auto unsupported_error = [this]() {
+    return std::format("ToString not supported for type: {}", 
type_->ToString());
+  };
+  auto invalid_argument = [this]() {
+    return std::format("Invalid argument for type: {}", type_->ToString());
+  };

Review Comment:
   ```suggestion
     auto invalid_literal = [this]() {
       return std::format("Invalid literal of type: {}", type_->ToString());
     };
   ```
   
   This function will be called in printing an expression so it is better to 
print a consistent short message.



##########
src/iceberg/expression/literal.cc:
##########
@@ -283,28 +499,42 @@ std::string Literal::ToString() const {
       return std::to_string(std::get<double>(value_));
     }
     case TypeId::kString: {
-      return std::get<std::string>(value_);
+      return "\"" + std::get<std::string>(value_) + "\"";
     }
-    case TypeId::kBinary: {
+    case TypeId::kBinary:
+    case TypeId::kFixed: {
       const auto& binary_data = std::get<std::vector<uint8_t>>(value_);
-      std::string result;
-      result.reserve(binary_data.size() * 2);  // 2 chars per byte
+      std::string result = "X'";
+      result.reserve(2 + binary_data.size() * 2 +
+                     1);  // 2 chars per byte and 2 + 1 for prefix and suffix
       for (const auto& byte : binary_data) {
         std::format_to(std::back_inserter(result), "{:02X}", byte);
       }
+      result.push_back('\'');
       return result;
     }
-    case TypeId::kDecimal:
-    case TypeId::kUuid:
-    case TypeId::kFixed:
-    case TypeId::kDate:
     case TypeId::kTime:
     case TypeId::kTimestamp:
     case TypeId::kTimestampTz: {
-      throw IcebergError("Not implemented: ToString for " + type_->ToString());
+      return std::to_string(std::get<int64_t>(value_));
+    }
+    case TypeId::kDate: {
+      return std::to_string(std::get<int32_t>(value_));
+    }
+    case TypeId::kDecimal: {
+      const auto unscaled_value = std::get<int128_t>(value_);
+      auto decimal_type = std::static_pointer_cast<DecimalType>(type_);
+      int32_t scale = decimal_type->scale();
+
+      iceberg::Decimal decimal_val(unscaled_value);
+      Result<std::string> str_res = decimal_val.ToString(scale);
+      if (str_res.has_value()) {
+        return str_res.value();
+      }
+      return invalid_argument();

Review Comment:
   We can use std::expected.value_or to simplify this.



##########
src/iceberg/expression/literal.cc:
##########
@@ -74,6 +101,13 @@ Result<Literal> LiteralCaster::CastFromInt(
       return Literal::Float(static_cast<float>(int_val));
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(int_val));
+    case TypeId::kDate:
+      return Literal::Date(int_val);
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);

Review Comment:
   ```suggestion
         auto decimal_type = 
internal::checked_pointer_cast<DecimalType>(target_type);
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
+
+      return Literal::Decimal(rescaled_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
     default:
       return NotSupported("Cast from Float to {} is not supported",
                           target_type->ToString());
   }
 }
 
+Result<Literal> LiteralCaster::CastFromDouble(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  auto double_val = std::get<double>(literal.value_);
+
+  switch (target_type->type_id()) {
+    case TypeId::kFloat: {
+      if (double_val > static_cast<double>(std::numeric_limits<float>::max())) 
{
+        return AboveMaxLiteral(target_type);
+      }
+      if (double_val < 
static_cast<double>(std::numeric_limits<float>::lowest())) {
+        return BelowMinLiteral(target_type);
+      }
+      return Literal::Float(static_cast<float>(double_val));
+    }
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);

Review Comment:
   ```suggestion
         auto decimal_type = 
internal::checked_pointer_cast<DecimalType>(target_type);
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -100,6 +133,26 @@ Result<Literal> LiteralCaster::CastFromLong(
       return Literal::Float(static_cast<float>(long_val));
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(long_val));
+    case TypeId::kDate: {
+      if (long_val > std::numeric_limits<int32_t>::max()) {
+        return AboveMaxLiteral(target_type);
+      }
+      if (long_val < std::numeric_limits<int32_t>::min()) {
+        return BelowMinLiteral(target_type);
+      }
+      return Literal::Date(static_cast<int32_t>(long_val));
+    }
+    case TypeId::kTime:
+      return Literal::Time(long_val);
+    case TypeId::kTimestamp:
+      return Literal::Timestamp(long_val);
+    case TypeId::kTimestampTz:
+      return Literal::TimestampTz(long_val);
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);

Review Comment:
   ```suggestion
         auto decimal_type = 
internal::checked_pointer_cast<DecimalType>(target_type);
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
+
+      return Literal::Decimal(rescaled_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
     default:
       return NotSupported("Cast from Float to {} is not supported",
                           target_type->ToString());
   }
 }
 
+Result<Literal> LiteralCaster::CastFromDouble(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  auto double_val = std::get<double>(literal.value_);
+
+  switch (target_type->type_id()) {
+    case TypeId::kFloat: {
+      if (double_val > static_cast<double>(std::numeric_limits<float>::max())) 
{
+        return AboveMaxLiteral(target_type);
+      }
+      if (double_val < 
static_cast<double>(std::numeric_limits<float>::lowest())) {
+        return BelowMinLiteral(target_type);
+      }
+      return Literal::Float(static_cast<float>(double_val));
+    }
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string double_str = std::to_string(double_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(double_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
+
+      return Literal::Decimal(rescaled_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
+    default:
+      return NotSupported("Cast from Double to {} is not supported",
+                          target_type->ToString());
+  }
+}
+
+Result<Literal> LiteralCaster::CastFromString(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  const auto& str_val = std::get<std::string>(literal.value_);
+
+  switch (target_type->type_id()) {
+    case TypeId::kDate:
+    case TypeId::kTime:
+    case TypeId::kTimestamp:
+    case TypeId::kTimestampTz:
+    case TypeId::kUuid:
+      return NotImplemented("Cast from String to {} is not implemented yet",
+                            target_type->ToString());
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      iceberg::Decimal dec_val;
+      ICEBERG_ASSIGN_OR_RAISE(dec_val, iceberg::Decimal::FromString(str_val));

Review Comment:
   ```suggestion
         ICEBERG_ASSIGN_OR_RAISE(auto dec_val, 
iceberg::Decimal::FromString(str_val));
   ```



##########
src/iceberg/expression/literal.cc:
##########
@@ -109,17 +162,151 @@ Result<Literal> LiteralCaster::CastFromLong(
 Result<Literal> LiteralCaster::CastFromFloat(
     const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
   auto float_val = std::get<float>(literal.value_);
-  auto target_type_id = target_type->type_id();
 
-  switch (target_type_id) {
+  switch (target_type->type_id()) {
     case TypeId::kDouble:
       return Literal::Double(static_cast<double>(float_val));
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string float_str = std::to_string(float_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(float_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
+
+      return Literal::Decimal(rescaled_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
     default:
       return NotSupported("Cast from Float to {} is not supported",
                           target_type->ToString());
   }
 }
 
+Result<Literal> LiteralCaster::CastFromDouble(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  auto double_val = std::get<double>(literal.value_);
+
+  switch (target_type->type_id()) {
+    case TypeId::kFloat: {
+      if (double_val > static_cast<double>(std::numeric_limits<float>::max())) 
{
+        return AboveMaxLiteral(target_type);
+      }
+      if (double_val < 
static_cast<double>(std::numeric_limits<float>::lowest())) {
+        return BelowMinLiteral(target_type);
+      }
+      return Literal::Float(static_cast<float>(double_val));
+    }
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      std::string double_str = std::to_string(double_val);
+
+      iceberg::Decimal parsed_val;
+      int32_t parsed_scale = 0;
+      ICEBERG_ASSIGN_OR_RAISE(
+          parsed_val, iceberg::Decimal::FromString(double_str, nullptr, 
&parsed_scale));
+      iceberg::Decimal rescaled_val;
+      ICEBERG_ASSIGN_OR_RAISE(rescaled_val,
+                              parsed_val.Rescale(parsed_scale, 
decimal_type->scale()));
+
+      return Literal::Decimal(rescaled_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
+    default:
+      return NotSupported("Cast from Double to {} is not supported",
+                          target_type->ToString());
+  }
+}
+
+Result<Literal> LiteralCaster::CastFromString(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  const auto& str_val = std::get<std::string>(literal.value_);
+
+  switch (target_type->type_id()) {
+    case TypeId::kDate:
+    case TypeId::kTime:
+    case TypeId::kTimestamp:
+    case TypeId::kTimestampTz:
+    case TypeId::kUuid:
+      return NotImplemented("Cast from String to {} is not implemented yet",
+                            target_type->ToString());
+    case TypeId::kDecimal: {
+      auto decimal_type = std::static_pointer_cast<DecimalType>(target_type);
+      iceberg::Decimal dec_val;
+      ICEBERG_ASSIGN_OR_RAISE(dec_val, iceberg::Decimal::FromString(str_val));
+      return Literal::Decimal(dec_val.value(), decimal_type->precision(),
+                              decimal_type->scale());
+    }
+
+    default:
+      return NotSupported("Cast from String to {} is not supported",
+                          target_type->ToString());
+  }
+}
+
+Result<Literal> LiteralCaster::CastFromTimestamp(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  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::kTimestampTz:
+      return Literal::TimestampTz(timestamp_val);
+    default:
+      return NotSupported("Cast from Timestamp to {} is not supported",
+                          target_type->ToString());
+  }
+}
+
+Result<Literal> LiteralCaster::CastFromTimestampTz(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  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::kTimestamp:
+      return Literal::Timestamp(micros);
+    default:
+      return NotSupported("Cast from TimestampTz to {} is not supported",
+                          target_type->ToString());
+  }
+}
+
+Result<Literal> LiteralCaster::CastFromBinary(
+    const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type) 
{
+  auto binary_val = std::get<std::vector<uint8_t>>(literal.value_);
+  switch (target_type->type_id()) {
+    case TypeId::kFixed: {
+      auto target_fixed_type = 
std::static_pointer_cast<FixedType>(target_type);

Review Comment:
   ```suggestion
         auto target_fixed_type = 
internal::checked_pointer_cast<FixedType>(target_type);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org
For additional commands, e-mail: issues-h...@iceberg.apache.org

Reply via email to