|
24 | 24 | #include <cstdint> |
25 | 25 | #include <string> |
26 | 26 |
|
27 | | -#include "iceberg/exception.h" |
28 | 27 | #include "iceberg/util/checked_cast.h" |
29 | 28 | #include "iceberg/util/conversions.h" |
30 | 29 | #include "iceberg/util/macros.h" |
@@ -339,50 +338,12 @@ std::strong_ordering CompareFloat(T lhs, T rhs) { |
339 | 338 | return lhs_is_negative <=> rhs_is_negative; |
340 | 339 | } |
341 | 340 |
|
342 | | -std::partial_ordering CompareDecimal(Literal const& lhs, Literal const& rhs) { |
343 | | - ICEBERG_DCHECK(std::holds_alternative<Decimal>(lhs.value()), |
344 | | - "LHS of decimal comparison must hold Decimal"); |
345 | | - ICEBERG_DCHECK(std::holds_alternative<Decimal>(rhs.value()), |
346 | | - "RHS of decimal comparison must hold decimal"); |
347 | | - auto lhs_type = internal::checked_pointer_cast<DecimalType>(lhs.type()); |
348 | | - auto rhs_type = internal::checked_pointer_cast<DecimalType>(rhs.type()); |
349 | | - auto lhs_decimal = std::get<Decimal>(lhs.value()); |
350 | | - auto rhs_decimal = std::get<Decimal>(rhs.value()); |
351 | | - if (lhs_type->scale() == rhs_type->scale()) { |
352 | | - return lhs_decimal <=> rhs_decimal; |
353 | | - } else if (lhs_type->scale() > rhs_type->scale()) { |
354 | | - // Rescale to larger scale |
355 | | - auto rhs_res = rhs_decimal.Rescale(rhs_type->scale(), lhs_type->scale()); |
356 | | - if (!rhs_res.has_value()) { |
357 | | - if (rhs_res.error().kind == ErrorKind::kRescaleDataLoss) { |
358 | | - // Rescale would cause data loss, so lhs is definitely less than rhs |
359 | | - return std::partial_ordering::less; |
360 | | - } |
361 | | - // Other errors should return unordered |
362 | | - return std::partial_ordering::unordered; |
363 | | - } |
364 | | - return lhs_decimal <=> rhs_res.value(); |
365 | | - } else { |
366 | | - // Rescale to larger scale |
367 | | - auto lhs_res = lhs_decimal.Rescale(lhs_type->scale(), rhs_type->scale()); |
368 | | - if (!lhs_res.has_value()) { |
369 | | - if (lhs_res.error().kind == ErrorKind::kRescaleDataLoss) { |
370 | | - // Rescale would cause data loss, so lhs is definitely greater than rhs |
371 | | - return std::partial_ordering::greater; |
372 | | - } |
373 | | - // Other errors should return unordered |
374 | | - return std::partial_ordering::unordered; |
375 | | - } |
376 | | - return lhs_res.value() <=> rhs_decimal; |
377 | | - } |
378 | | -} |
379 | | - |
380 | 341 | bool Literal::operator==(const Literal& other) const { return (*this <=> other) == 0; } |
381 | 342 |
|
382 | 343 | // Three-way comparison operator |
383 | 344 | std::partial_ordering Literal::operator<=>(const Literal& other) const { |
384 | 345 | // If types are different, comparison is unordered |
385 | | - if (type_->type_id() != other.type_->type_id()) { |
| 346 | + if (*type_ != *other.type_) { |
386 | 347 | return std::partial_ordering::unordered; |
387 | 348 | } |
388 | 349 |
|
@@ -432,7 +393,12 @@ std::partial_ordering Literal::operator<=>(const Literal& other) const { |
432 | 393 | } |
433 | 394 |
|
434 | 395 | case TypeId::kDecimal: { |
435 | | - return CompareDecimal(*this, other); |
| 396 | + auto& this_val = std::get<::iceberg::Decimal>(value_); |
| 397 | + auto& other_val = std::get<::iceberg::Decimal>(other.value_); |
| 398 | + const auto& this_decimal_type = internal::checked_cast<DecimalType&>(*type_); |
| 399 | + const auto& other_decimal_type = internal::checked_cast<DecimalType&>(*other.type_); |
| 400 | + return ::iceberg::Decimal::Compare(this_val, other_val, this_decimal_type.scale(), |
| 401 | + other_decimal_type.scale()); |
436 | 402 | } |
437 | 403 |
|
438 | 404 | case TypeId::kString: { |
@@ -491,11 +457,10 @@ std::string Literal::ToString() const { |
491 | 457 | return std::to_string(std::get<double>(value_)); |
492 | 458 | } |
493 | 459 | case TypeId::kDecimal: { |
494 | | - auto decimal_type = internal::checked_pointer_cast<DecimalType>(type_); |
495 | | - auto decimal = std::get<::iceberg::Decimal>(value_); |
496 | | - auto result = decimal.ToString(decimal_type->scale()); |
497 | | - ICEBERG_CHECK(result, "Decimal ToString failed"); |
498 | | - return *result; |
| 460 | + const auto& decimal_type = internal::checked_cast<DecimalType&>(*type_); |
| 461 | + const auto& decimal = std::get<::iceberg::Decimal>(value_); |
| 462 | + return decimal.ToString(decimal_type.scale()) |
| 463 | + .value_or("invalid literal of type decimal"); |
499 | 464 | } |
500 | 465 | case TypeId::kString: { |
501 | 466 | return "\"" + std::get<std::string>(value_) + "\""; |
|
0 commit comments