@@ -344,6 +344,42 @@ std::strong_ordering CompareFloat(T lhs, T rhs) {
344344 return lhs_is_negative <=> rhs_is_negative;
345345}
346346
347+ std::strong_ordering CompareDecimal (Literal const & lhs, Literal const & rhs) {
348+ ICEBERG_DCHECK (std::holds_alternative<int128_t >(lhs.value ()),
349+ " LHS of decimal comparison must hold int128_t" );
350+ ICEBERG_DCHECK (std::holds_alternative<int128_t >(rhs.value ()),
351+ " RHS of decimal comparison must hold int128_t" );
352+ const auto & lhs_type = std::dynamic_pointer_cast<DecimalType>(lhs.type ());
353+ const auto & rhs_type = std::dynamic_pointer_cast<DecimalType>(rhs.type ());
354+ ICEBERG_DCHECK (lhs_type != nullptr , " LHS type must be DecimalType" );
355+ ICEBERG_DCHECK (rhs_type != nullptr , " RHS type must be DecimalType" );
356+ auto lhs_val = std::get<int128_t >(lhs.value ());
357+ auto rhs_val = std::get<int128_t >(rhs.value ());
358+ if (lhs_type->scale () == rhs_type->scale ()) {
359+ return lhs_val <=> rhs_val;
360+ } else if (lhs_type->scale () > rhs_type->scale ()) {
361+ auto lhs_decimal = Decimal (lhs_val);
362+ // Rescale to larger scale
363+ auto rhs_decimal = Decimal (rhs_val).Rescale (rhs_type->scale (), lhs_type->scale ());
364+ if (!rhs_decimal) {
365+ // Rescale would cause data loss, so lhs is definitely less than rhs
366+ return std::strong_ordering::less;
367+ }
368+ return lhs_decimal <=> rhs_decimal.value ();
369+ } else {
370+ auto rhs_decimal = Decimal (rhs_val);
371+ // Rescale to larger scale
372+ auto lhs_decimal = Decimal (lhs_val).Rescale (lhs_type->scale (), rhs_type->scale ());
373+ if (!lhs_decimal) {
374+ // Rescale would cause data loss, so lhs is definitely greater than rhs
375+ return std::strong_ordering::greater;
376+ }
377+ return lhs_decimal.value () <=> rhs_decimal;
378+ }
379+
380+ return lhs_val <=> rhs_val;
381+ }
382+
347383bool Literal::operator ==(const Literal& other) const { return (*this <=> other) == 0 ; }
348384
349385// Three-way comparison operator
@@ -410,10 +446,7 @@ std::partial_ordering Literal::operator<=>(const Literal& other) const {
410446 }
411447
412448 case TypeId::kDecimal : {
413- // TODO(zhjwpku): Handle precision/scale differences
414- auto this_val = std::get<int128_t >(value_);
415- auto other_val = std::get<int128_t >(other.value_ );
416- return this_val <=> other_val;
449+ return CompareDecimal (*this , other);
417450 }
418451
419452 default :
0 commit comments