Changed-lines coverage: PR changed C/C++ lines covered by tests: 91.12% (626/687) Uncovered changed code (with context): ================================================================================ src/Common/DateLUTImpl.cpp ================================================================================ --- uncovered block 222-222 --- 220 | } 221 | >> 222 | DateLUTImpl::~DateLUTImpl() = default; 223 | 224 | namespace --- uncovered block 305-311 --- 303 | /// exactly as the in-range toTime does (which returns the time of day starting at 1970-01-01 00:00:00 local time). 304 | /// Bound only enough to avoid chrono overflow, so local boundary values keep their correct time of day. >> 305 | t = std::clamp(t, min_chrono_safe_time, max_chrono_safe_time); >> 306 | const cctz::time_zone & tz = *cctz_time_zone; >> 307 | const auto tp = std::chrono::system_clock::from_time_t(t); >> 308 | const cctz::civil_second cs = cctz::convert(tp, tz); >> 309 | const cctz::civil_day cd{cs}; >> 310 | const Time start_of_day = std::chrono::system_clock::to_time_t(lookupTz(tz, cd)); >> 311 | return (t - start_of_day) - offset_at_start_of_epoch; 312 | } 313 | --- uncovered block 376-376 --- 374 | /// Saturation to 28 Feb can happen for 29 Feb of a leap year mapped onto a non-leap year. 375 | if (cs.month() == 2 && day_of_month == 29) >> 376 | day_of_month = std::min(day_of_month, daysInCivilMonth(year, 2)); 377 | 378 | const cctz::civil_second target{static_cast(year), cs.month(), day_of_month, cs.hour(), cs.minute(), cs.second()}; --- uncovered block 394-396 --- 392 | /// Saturate the whole date to the boundary rather than clamping only the year (which would keep a wrapped month). 393 | if (unclamped_year > DATE_LUT_MAX_REPRESENTABLE_YEAR) >> 394 | return dayNumOfDayIndex(dayIndexOfCivilDay(cctz::civil_day{DATE_LUT_MAX_REPRESENTABLE_YEAR, 12, 31})); 395 | if (unclamped_year < DATE_LUT_MIN_REPRESENTABLE_YEAR) >> 396 | return dayNumOfDayIndex(dayIndexOfCivilDay(cctz::civil_day{DATE_LUT_MIN_REPRESENTABLE_YEAR, 1, 1})); 397 | 398 | const int month = static_cast(month_index - unclamped_year * 12) + 1; --- uncovered block 413-413 --- 411 | int day_of_month = cd.day(); 412 | if (cd.month() == 2 && day_of_month == 29) >> 413 | day_of_month = std::min(day_of_month, daysInCivilMonth(year, 2)); 414 | 415 | return dayNumOfDayIndex(dayIndexOfCivilDay(cctz::civil_day{static_cast(year), cd.month(), day_of_month})); ================================================================================ src/Common/DateLUTImpl.h ================================================================================ --- uncovered block 327-328 --- 325 | if (index < 0) 326 | k = (days_in_400_years - 1 - index) / days_in_400_years; >> 327 | else if (index >= days_in_400_years) >> 328 | k = -(index / days_in_400_years); 329 | index += k * days_in_400_years; 330 | cycles = static_cast(k); --- uncovered block 532-532 --- 530 | if constexpr (may_be_out_of_lut_range) 531 | if (unlikely(isOutOfLUTRange(v))) >> 532 | return dateOfDayIndex(outOfRangeDayIndex(v) - (outOfRangeValues(v).day_of_week - 1)); 533 | 534 | const LUTIndex i = toLUTIndex(v); --- uncovered block 561-561 --- 559 | if constexpr (may_be_out_of_lut_range) 560 | if (unlikely(isOutOfLUTRange(v))) >> 561 | return dateOfDayIndex(outOfRangeDayIndex(v) + (7 - outOfRangeValues(v).day_of_week)); 562 | 563 | const LUTIndex i = toLUTIndex(v); --- uncovered block 575-575 --- 573 | if constexpr (may_be_out_of_lut_range) 574 | if (unlikely(isOutOfLUTRange(v))) >> 575 | return dayNumOfDayIndex(outOfRangeDayIndex(v) + (7 - outOfRangeValues(v).day_of_week)); 576 | 577 | const LUTIndex i = toLUTIndex(v); --- uncovered block 620-621 --- 618 | if (unlikely(isOutOfLUTRange(v))) 619 | { >> 620 | const Values values = outOfRangeValues(v); >> 621 | return dateOfDayIndex(outOfRangeDayIndex(v) + (values.days_in_month - values.day_of_month)); 622 | } 623 | --- uncovered block 637-638 --- 635 | if (unlikely(isOutOfLUTRange(v))) 636 | { >> 637 | const Values values = outOfRangeValues(v); >> 638 | return dayNumOfDayIndex(outOfRangeDayIndex(v) + (values.days_in_month - values.day_of_month)); 639 | } 640 | --- uncovered block 655-656 --- 653 | if (unlikely(isOutOfLUTRange(v))) 654 | { >> 655 | const Values values = outOfRangeValues(v); >> 656 | return makeDayNumOutOfRange(values.year, (values.month - 1) / 3 * 3 + 1, 1); 657 | } 658 | --- uncovered block 687-688 --- 685 | if (unlikely(isOutOfLUTRange(v))) 686 | { >> 687 | const Values values = outOfRangeValues(v); >> 688 | return makeDateOutOfRange(values.year, (values.month - 1) / 3 * 3 + 1, 1); 689 | } 690 | --- uncovered block 726-727 --- 724 | if (unlikely(isOutOfLUTRange(t))) 725 | { >> 726 | const Values values = outOfRangeValues(t); >> 727 | return makeDateOutOfRange(values.year, values.month + 1, 1); 728 | } 729 | --- uncovered block 739-740 --- 737 | if (unlikely(isOutOfLUTRange(t))) 738 | { >> 739 | const Values values = outOfRangeValues(t); >> 740 | return makeDateOutOfRange(values.year, values.month - 1, 1); 741 | } 742 | --- uncovered block 774-779 --- 772 | { 773 | if (unlikely(isOutOfLUTRange(t))) >> 774 | return dateOfDayIndex(findDayIndexOutOfRange(t) + days); 775 | 776 | const LUTIndex index = findIndexInRange(t); 777 | const Int64 shifted = static_cast(index.toUnderType()) + days; 778 | if (unlikely(shifted < 0 || shifted >= DATE_LUT_SIZE)) >> 779 | return dateOfDayIndex(shifted); 780 | 781 | return lut[index + days].date; --- uncovered block 787-787 --- 785 | { 786 | if (unlikely(isOutOfLUTRange(t))) >> 787 | return toTimeOutOfRange(t); 788 | 789 | const LUTIndex index = findIndexInRange(t); --- uncovered block 922-922 --- 920 | { 921 | if (unlikely(isOutOfLUTRange(d))) >> 922 | return outOfRangeValues(d).date; 923 | return lut[toLUTIndex(d)].date; 924 | } --- uncovered block 1028-1030 --- 1026 | Int32 iso_year = toISOYear(shifted) - cycles * 400; 1027 | if (iso_year < DATE_LUT_MIN_REPRESENTABLE_YEAR) >> 1028 | iso_year = DATE_LUT_MIN_REPRESENTABLE_YEAR; 1029 | else if (iso_year > DATE_LUT_MAX_REPRESENTABLE_YEAR) >> 1030 | iso_year = DATE_LUT_MAX_REPRESENTABLE_YEAR; 1031 | return static_cast(iso_year); 1032 | } --- uncovered block 1062-1066 --- 1060 | if (unlikely(isOutOfLUTRange(v))) 1061 | { >> 1062 | Int32 cycles = 0; >> 1063 | const ExtendedDayNum shifted = shiftIntoLUTRange(toDayNum(v), cycles); 1064 | /// Not recursing into toFirstDayNumOfISOYear (it has a deduced return type); use the index helper directly. >> 1065 | const ExtendedDayNum first = toDayNum(toFirstDayNumOfISOYearIndex(shifted)); >> 1066 | return ExtendedDayNum{static_cast(first.toUnderType() - cycles * days_in_400_years)}; 1067 | } 1068 | --- uncovered block 1079-1080 --- 1077 | if (unlikely(isOutOfLUTRange(t))) 1078 | { >> 1079 | const ExtendedDayNum first = toFirstDayNumOfISOYear(t); >> 1080 | return dateOfDayIndex(static_cast(first.toUnderType()) + daynum_offset_epoch); 1081 | } 1082 | --- uncovered block 1150-1152 --- 1148 | Int32 adjusted_year = static_cast(yw.first) - cycles * 400; 1149 | if (adjusted_year < DATE_LUT_MIN_REPRESENTABLE_YEAR) >> 1150 | adjusted_year = DATE_LUT_MIN_REPRESENTABLE_YEAR; 1151 | else if (adjusted_year > DATE_LUT_MAX_REPRESENTABLE_YEAR) >> 1152 | adjusted_year = DATE_LUT_MAX_REPRESENTABLE_YEAR; 1153 | yw.first = static_cast(adjusted_year); 1154 | return yw; --- uncovered block 1392-1393 --- 1390 | if (unlikely(isOutOfLUTRange(v))) 1391 | { >> 1392 | const Int64 rounded_year = static_cast(outOfRangeValues(v).year) / static_cast(years) * static_cast(years); >> 1393 | return makeDayNumOutOfRange(rounded_year, 1, 1); 1394 | } 1395 | --- uncovered block 1459-1459 --- 1457 | // January 1st 1970 was Thursday so we need this 4-days offset to make weeks start on Monday. 1458 | if constexpr (std::is_same_v) >> 1459 | return DayNum(static_cast(4 + (d - 4) / days * days)); 1460 | else 1461 | { --- uncovered block 1482-1489 --- 1480 | /// Floor division towards -inf: truncating division would round a pre-epoch day number 1481 | /// towards zero, i.e. forward in time, past the start of the interval. >> 1482 | const Int64 day_num = static_cast(d.toUnderType()); >> 1483 | const Int64 idays = static_cast(days); >> 1484 | const Int64 rounded_day_num = day_num >= 0 ? day_num / idays * idays : (day_num + 1 - idays) / idays * idays; >> 1485 | return dateOfDayIndex(rounded_day_num + daynum_offset_epoch); 1486 | } 1487 | 1488 | if constexpr (std::is_same_v) >> 1489 | return lut_saturated[toLUTIndex(ExtendedDayNum(static_cast(d / days * days)))].date; 1490 | else 1491 | return lut[toLUTIndex(ExtendedDayNum(static_cast(d / days * days)))].date; --- uncovered block 1525-1525 --- 1523 | } 1524 | >> 1525 | const LUTIndex index = findIndexInRange(t); 1526 | const Values & values = lut[index]; 1527 | --- uncovered block 1693-1693 --- 1691 | auto index = tryToMakeLUTIndex(year, month, day_of_month); 1692 | if (!index) >> 1693 | return std::nullopt; 1694 | 1695 | Time time_offset = hour * 3600 + minute * 60 + second; --- uncovered block 1795-1795 --- 1793 | DateComponents toDateComponents(Time t) const 1794 | { >> 1795 | const Values & values = getValues(t); 1796 | return { .year = values.year, .month = values.month, .day = values.day_of_month }; 1797 | } --- uncovered block 2012-2012 --- 2010 | { 2011 | if (unlikely(isOutOfLUTRange(d))) >> 2012 | return addMonthsOutOfRange(d, delta); 2013 | 2014 | const Values & values = lut[toLUTIndex(d)]; --- uncovered block 2096-2096 --- 2094 | { 2095 | if (unlikely(isOutOfLUTRange(d))) >> 2096 | return addYearsOutOfRange(d, delta); 2097 | 2098 | const Values & values = lut[toLUTIndex(d)]; ================================================================================ src/Common/tests/gtest_DateLUTImpl.cpp ================================================================================ --- uncovered block 125-125 --- 123 | case cctz::weekday::sunday: return 7; 124 | } >> 125 | return 0; 126 | } 127 | ================================================================================ src/Functions/FunctionsConversion.h ================================================================================ --- uncovered block 368-368 --- 366 | if constexpr (is_floating_point) 367 | return time_zone.toDayNum(static_cast(std::min(static_cast(from), static_cast(MAX_DATE32_TIMESTAMP)))); >> 368 | return time_zone.toDayNum(std::min(time_t(Int64(from)), time_t(MAX_DATE32_TIMESTAMP))); 369 | } 370 | ================================================================================ src/Functions/parseDateTime.cpp ================================================================================ --- uncovered block 244-246 --- 242 | { 243 | if (century < 0 || century > 99) >> 244 | RETURN_ERROR(ErrorCodes::CANNOT_PARSE_DATETIME, "Value {} for century must be in the range [0, 99]", century) 245 | >> 246 | year = 100 * century; 247 | has_year = true; 248 | return {}; --- uncovered block 553-553 --- 551 | /// calendar (Howard Hinnant's days_from_civil specialised to January 1). Computed rather than 552 | /// looked up in a table so the whole supported [0000, 9999] range works, not just years near the epoch. >> 553 | const Int32 y = year_ - 1; 554 | const Int32 era = (y >= 0 ? y : y - 399) / 400; 555 | const Int32 year_of_era = y - era * 400; WARNING: Failed to get start time for [Print Uncovered Code] - start time and duration won't be set --- Coverage counts --- Lines : baseline 882,870/1,028,499 -> current 883,191/1,029,066 (delta +321 / +567) Functions : baseline 947,414/1,022,292 -> current 947,496/1,022,331 (delta +82 / +39) Branches : baseline 285,047/365,426 -> current 285,219/365,734 (delta +172 / +308)