Skip to content

Commit d1f7ea7

Browse files
committed
add tests for times
1 parent 1bee4c5 commit d1f7ea7

File tree

3 files changed

+106
-18
lines changed

3 files changed

+106
-18
lines changed

src/iceberg/expression/literal.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ Literal Literal::Binary(std::vector<uint8_t> value) {
150150
return {Value{std::move(value)}, binary()};
151151
}
152152

153+
Literal Literal::Fixed(std::vector<uint8_t> value, int32_t length) {
154+
return {Value{std::move(value)}, fixed(length)};
155+
}
156+
153157
Result<Literal> Literal::Deserialize(std::span<const uint8_t> data,
154158
std::shared_ptr<PrimitiveType> type) {
155159
return Conversions::FromBytes(type, data);
@@ -217,6 +221,7 @@ std::partial_ordering Literal::operator<=>(const Literal& other) const {
217221
}
218222

219223
case TypeId::kLong:
224+
case TypeId::kTime:
220225
case TypeId::kTimestamp:
221226
case TypeId::kTimestampTz: {
222227
auto this_val = std::get<int64_t>(value_);
@@ -295,9 +300,17 @@ std::string Literal::ToString() const {
295300
}
296301
return result;
297302
}
303+
case TypeId::kFixed: {
304+
const auto& fixed_data = std::get<std::vector<uint8_t>>(value_);
305+
std::string result;
306+
result.reserve(fixed_data.size() * 2); // 2 chars per byte
307+
for (const auto& byte : fixed_data) {
308+
std::format_to(std::back_inserter(result), "{:02X}", byte);
309+
}
310+
return result;
311+
}
298312
case TypeId::kDecimal:
299313
case TypeId::kUuid:
300-
case TypeId::kFixed:
301314
case TypeId::kDate:
302315
case TypeId::kTime:
303316
case TypeId::kTimestamp:

src/iceberg/expression/literal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class ICEBERG_EXPORT Literal {
7171
static Literal Double(double value);
7272
static Literal String(std::string value);
7373
static Literal Binary(std::vector<uint8_t> value);
74+
static Literal Fixed(std::vector<uint8_t> value, int32_t length);
7475

7576
/// \brief Create a literal representing a null value.
7677
static Literal Null(std::shared_ptr<PrimitiveType> type) {

test/literal_test.cc

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -423,38 +423,112 @@ INSTANTIATE_TEST_SUITE_P(
423423
// Basic types
424424
LiteralRoundTripParam{"BooleanTrue", {1}, Literal::Boolean(true), boolean()},
425425
LiteralRoundTripParam{"BooleanFalse", {0}, Literal::Boolean(false), boolean()},
426+
426427
LiteralRoundTripParam{"Int", {32, 0, 0, 0}, Literal::Int(32), int32()},
428+
LiteralRoundTripParam{
429+
"IntMaxValue", {255, 255, 255, 127}, Literal::Int(2147483647), int32()},
430+
LiteralRoundTripParam{
431+
"IntMinValue", {0, 0, 0, 128}, Literal::Int(-2147483648), int32()},
432+
LiteralRoundTripParam{
433+
"NegativeInt", {224, 255, 255, 255}, Literal::Int(-32), int32()},
434+
427435
LiteralRoundTripParam{
428436
"Long", {32, 0, 0, 0, 0, 0, 0, 0}, Literal::Long(32), int64()},
437+
LiteralRoundTripParam{"LongMaxValue",
438+
{255, 255, 255, 255, 255, 255, 255, 127},
439+
Literal::Long(std::numeric_limits<int64_t>::max()),
440+
int64()},
441+
LiteralRoundTripParam{"LongMinValue",
442+
{0, 0, 0, 0, 0, 0, 0, 128},
443+
Literal::Long(std::numeric_limits<int64_t>::min()),
444+
int64()},
445+
LiteralRoundTripParam{"NegativeLong",
446+
{224, 255, 255, 255, 255, 255, 255, 255},
447+
Literal::Long(-32),
448+
int64()},
449+
429450
LiteralRoundTripParam{"Float", {0, 0, 128, 63}, Literal::Float(1.0f), float32()},
451+
LiteralRoundTripParam{"FloatNegativeInfinity",
452+
{0, 0, 128, 255},
453+
Literal::Float(-std::numeric_limits<float>::infinity()),
454+
float32()},
455+
LiteralRoundTripParam{"FloatMaxValue",
456+
{255, 255, 127, 127},
457+
Literal::Float(std::numeric_limits<float>::max()),
458+
float32()},
459+
LiteralRoundTripParam{"FloatMinValue",
460+
{255, 255, 127, 255},
461+
Literal::Float(std::numeric_limits<float>::lowest()),
462+
float32()},
463+
430464
LiteralRoundTripParam{
431465
"Double", {0, 0, 0, 0, 0, 0, 240, 63}, Literal::Double(1.0), float64()},
466+
LiteralRoundTripParam{"DoubleNegativeInfinity",
467+
{0, 0, 0, 0, 0, 0, 240, 255},
468+
Literal::Double(-std::numeric_limits<double>::infinity()),
469+
float64()},
470+
LiteralRoundTripParam{"DoubleMaxValue",
471+
{255, 255, 255, 255, 255, 255, 239, 127},
472+
Literal::Double(std::numeric_limits<double>::max()),
473+
float64()},
474+
LiteralRoundTripParam{"DoubleMinValue",
475+
{255, 255, 255, 255, 255, 255, 239, 255},
476+
Literal::Double(std::numeric_limits<double>::lowest()),
477+
float64()},
478+
432479
LiteralRoundTripParam{"String",
433480
{105, 99, 101, 98, 101, 114, 103},
434481
Literal::String("iceberg"),
435482
string()},
483+
LiteralRoundTripParam{
484+
"StringLong",
485+
{65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65},
486+
Literal::String("AAAAAAAAAAAAAAAA"),
487+
string()},
488+
436489
LiteralRoundTripParam{"BinaryData",
437490
{0x01, 0x02, 0x03, 0xFF},
438491
Literal::Binary({0x01, 0x02, 0x03, 0xFF}),
439492
binary()},
440-
// Edge cases that fit the round-trip pattern
493+
LiteralRoundTripParam{"BinarySingleByte", {42}, Literal::Binary({42}), binary()},
494+
495+
// Temporal types
496+
LiteralRoundTripParam{"DateEpoch", {0, 0, 0, 0}, Literal::Date(0), date()},
497+
LiteralRoundTripParam{"DateNextDay", {1, 0, 0, 0}, Literal::Date(1), date()},
498+
LiteralRoundTripParam{"DateY2K", {205, 42, 0, 0}, Literal::Date(10957), date()},
441499
LiteralRoundTripParam{
442-
"NegativeInt", {224, 255, 255, 255}, Literal::Int(-32), int32()},
443-
LiteralRoundTripParam{"NegativeLong",
444-
{224, 255, 255, 255, 255, 255, 255, 255},
445-
Literal::Long(-32),
446-
int64()},
447-
// IEEE 754 representation for NaN and Infinity (in little-endian)
448-
LiteralRoundTripParam{"FloatInfinity",
449-
{0, 0, 128, 127},
450-
Literal::Float(std::numeric_limits<float>::infinity()),
451-
float32()},
452-
LiteralRoundTripParam{"FloatNaN",
453-
{0, 0, 192, 127},
454-
Literal::Float(std::numeric_limits<float>::quiet_NaN()),
455-
float32()}
456-
// TODO(Li Feiyang): Add tests for Date, Time, Timestamp, TimestampTz
457-
),
500+
"DateNegative", {255, 255, 255, 255}, Literal::Date(-1), date()},
501+
502+
LiteralRoundTripParam{
503+
"TimeMidnight", {0, 0, 0, 0, 0, 0, 0, 0}, Literal::Time(0), time()},
504+
LiteralRoundTripParam{"TimeNoon",
505+
{128, 9, 230, 124, 10, 0, 0, 0},
506+
Literal::Time(45045123456),
507+
time()},
508+
LiteralRoundTripParam{
509+
"TimeOneSecond", {64, 66, 15, 0, 0, 0, 0, 0}, Literal::Time(1000000), time()},
510+
511+
LiteralRoundTripParam{"TimestampEpoch",
512+
{0, 0, 0, 0, 0, 0, 0, 0},
513+
Literal::Timestamp(0),
514+
timestamp()},
515+
LiteralRoundTripParam{"TimestampOneSecond",
516+
{64, 66, 15, 0, 0, 0, 0, 0},
517+
Literal::Timestamp(1000000),
518+
timestamp()},
519+
LiteralRoundTripParam{"TimestampNoon2024",
520+
{128, 9, 230, 124, 10, 0, 0, 0},
521+
Literal::Timestamp(45045123456),
522+
timestamp()},
523+
524+
LiteralRoundTripParam{"TimestampTzEpoch",
525+
{0, 0, 0, 0, 0, 0, 0, 0},
526+
Literal::TimestampTz(0),
527+
timestamp_tz()},
528+
LiteralRoundTripParam{"TimestampTzOneHour",
529+
{0, 164, 147, 214, 0, 0, 0, 0},
530+
Literal::TimestampTz(3600000000),
531+
timestamp_tz()}),
458532

459533
[](const testing::TestParamInfo<LiteralSerializationParam::ParamType>& info) {
460534
return info.param.test_name;

0 commit comments

Comments
 (0)