wgtmac commented on code in PR #206:
URL: https://github.com/apache/iceberg-cpp/pull/206#discussion_r2332866203
##########
src/iceberg/expression/literal.cc:
##########
@@ -120,6 +170,131 @@ Result<Literal> LiteralCaster::CastFromFloat(
}
}
+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));
+ }
+ 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)
{
+ switch (target_type->type_id()) {
+ case TypeId::kDate: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DD" using
std::chrono::parse
+ // once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to Date is not yet
implemented.");
+ }
+
+ case TypeId::kTime: {
+ // TODO(Li Feiyang): Implement parsing for "HH:MM:SS.ffffff" using
+ // std::chrono::parse once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to Time is not yet
implemented.");
+ }
+
+ case TypeId::kTimestamp: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DDTHH:MM:SS.ffffff"
using
+ // std::chrono::parse once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to Timestamp is not yet
implemented.");
+ }
+
+ case TypeId::kTimestampTz: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DDTHH:MM:SS.ffffffZ"
using
+ // std::chrono::parse once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to TimestampTz is not yet
implemented.");
+ }
+
+ 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 Literal::Date(MicrosToDays(timestamp_val));
+ 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 Literal::Date(MicrosToDays(micros));
+ }
+ 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::dynamic_pointer_cast<FixedType>(target_type);
+ if (binary_val.size() == target_fixed_type->length()) {
+ return Literal::Fixed(binary_val);
+ }
+ return NotSupported("Cannot cast Binary with length {} to Fixed({})",
+ binary_val.size(), target_fixed_type->length());
+ }
+ default:
+ return NotSupported("Cast from Binary to {} is not supported",
+ target_type->ToString());
+ }
+}
+
+Result<Literal> LiteralCaster::CastFromFixed(
+ const Literal& literal, const std::shared_ptr<PrimitiveType>& target_type)
{
+ const auto& fixed_val = std::get<std::vector<uint8_t>>(literal.value_);
+
+ switch (target_type->type_id()) {
+ case TypeId::kBinary: {
+ return Literal::Binary(fixed_val);
+ }
+ case TypeId::kFixed: {
+ auto target_fixed_type =
std::dynamic_pointer_cast<FixedType>(target_type);
+ if (fixed_val.size() == target_fixed_type->length()) {
+ return literal;
+ }
+ return NotSupported("Cannot cast Fixed({}) to Fixed({}) due to
mismatched lengths",
+ fixed_val.size(), target_fixed_type->length());
+ }
Review Comment:
```suggestion
```
We don't need this. Identity cast has already been handled in the `CastTo`.
##########
src/iceberg/expression/literal.cc:
##########
@@ -120,6 +170,131 @@ Result<Literal> LiteralCaster::CastFromFloat(
}
}
+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));
+ }
+ 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)
{
+ switch (target_type->type_id()) {
+ case TypeId::kDate: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DD" using
std::chrono::parse
+ // once it becomes available in the target libc++.
Review Comment:
```suggestion
// TODO(Li Feiyang): Implement parsing "YYYY-MM-DD"
```
`libc++` is not a blocker so please remove that explanation. For example you
can leverage https://en.cppreference.com/w/cpp/io/c/fscanf to parse the string.
Same for below.
##########
src/iceberg/expression/literal.cc:
##########
@@ -100,6 +136,21 @@ 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 >
static_cast<int64_t>(std::numeric_limits<int32_t>::max())) {
+ return AboveMaxLiteral(target_type);
+ }
+ if (long_val <
static_cast<int64_t>(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);
Review Comment:
ditto, add TODO for decimal and perhaps TimestampNs / TimestampTzNs
##########
src/iceberg/expression/literal.cc:
##########
@@ -74,6 +109,8 @@ 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);
Review Comment:
```suggestion
return Literal::Date(int_val);
// TODO(foo): support decimal
```
##########
src/iceberg/expression/literal.cc:
##########
@@ -100,6 +136,21 @@ 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 >
static_cast<int64_t>(std::numeric_limits<int32_t>::max())) {
+ return AboveMaxLiteral(target_type);
+ }
+ if (long_val <
static_cast<int64_t>(std::numeric_limits<int32_t>::min())) {
+ return BelowMinLiteral(target_type);
+ }
Review Comment:
```suggestion
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);
}
```
##########
src/iceberg/expression/literal.cc:
##########
@@ -109,9 +160,8 @@ 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()) {
Review Comment:
add TODO for decimal
##########
src/iceberg/expression/literal.cc:
##########
@@ -120,6 +170,131 @@ Result<Literal> LiteralCaster::CastFromFloat(
}
}
+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));
+ }
+ 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)
{
+ switch (target_type->type_id()) {
+ case TypeId::kDate: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DD" using
std::chrono::parse
+ // once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to Date is not yet
implemented.");
+ }
+
+ case TypeId::kTime: {
+ // TODO(Li Feiyang): Implement parsing for "HH:MM:SS.ffffff" using
+ // std::chrono::parse once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to Time is not yet
implemented.");
+ }
+
+ case TypeId::kTimestamp: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DDTHH:MM:SS.ffffff"
using
+ // std::chrono::parse once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to Timestamp is not yet
implemented.");
+ }
+
+ case TypeId::kTimestampTz: {
+ // TODO(Li Feiyang): Implement parsing for "YYYY-MM-DDTHH:MM:SS.ffffffZ"
using
+ // std::chrono::parse once it becomes available in the target libc++.
+ return NotImplemented("Cast from String to TimestampTz is not yet
implemented.");
+ }
+
+ 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 Literal::Date(MicrosToDays(timestamp_val));
+ 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 Literal::Date(MicrosToDays(micros));
+ }
+ case TypeId::kTimestamp: {
+ return Literal::Timestamp(micros);
+ }
Review Comment:
```suggestion
case TypeId::kDate:
return Literal::Date(MicrosToDays(micros));
case TypeId::kTimestamp:
return Literal::Timestamp(micros);
```
For consistency as above.
--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]