28
netdata_mutex_destroy(&db_mutex);
29
}
30
31
+namespace {
32
+
33
+template <bool NeedLowerBound, bool NeedUpperBound>
34
+inline bool ml_sqlite_int64_fits_time_t(sqlite3_int64 value)
35
+{
36
+ (void)value;
37
+ return true;
38
+}
39
+
40
+template <>
41
+inline bool ml_sqlite_int64_fits_time_t<true, false>(sqlite3_int64 value)
42
+{
43
+ const sqlite3_int64 kTimeMin = (sqlite3_int64) std::numeric_limits<time_t>::min();
44
+ return value >= kTimeMin;
45
+}
46
+
47
+template <>
48
+inline bool ml_sqlite_int64_fits_time_t<false, true>(sqlite3_int64 value)
49
+{
50
+ const sqlite3_int64 kTimeMax = (sqlite3_int64) std::numeric_limits<time_t>::max();
51
+ return value <= kTimeMax;
52
+}
53
+
54
+template <>
55
+inline bool ml_sqlite_int64_fits_time_t<true, true>(sqlite3_int64 value)
56
+{
57
+ const sqlite3_int64 kTimeMin = (sqlite3_int64) std::numeric_limits<time_t>::min();
58
+ const sqlite3_int64 kTimeMax = (sqlite3_int64) std::numeric_limits<time_t>::max();
59
+ return value >= kTimeMin && value <= kTimeMax;
60
+}
61
+
62
+}
63
+
64
static inline size_t ml_dimension_smoothing_window(const ml_dimension_t *dim)
65
{
66
unsigned chart_update_every = dim->rd->rrdset->update_every;
464
465
sqlite3_int64 raw_after = sqlite3_column_int64(res, 0);
466
sqlite3_int64 raw_before = sqlite3_column_int64(res, 1);
467
+ constexpr bool kNeedLowerBound =
468
+ !std::numeric_limits<time_t>::is_signed ||
469
+ std::numeric_limits<time_t>::digits < std::numeric_limits<sqlite3_int64>::digits;
470
+ constexpr bool kNeedUpperBound =
471
+ std::numeric_limits<time_t>::digits < std::numeric_limits<sqlite3_int64>::digits;
472
473
// Protect against silent truncation when time_t is narrower than int64_t
474
// (e.g. 32-bit builds, corrupted DB, or far-future timestamps).
437
- static constexpr sqlite3_int64 kTimeMin = std::numeric_limits<time_t>::min();
438
- static constexpr sqlite3_int64 kTimeMax = std::numeric_limits<time_t>::max();
439
- if (raw_after < kTimeMin || raw_after > kTimeMax ||
440
- raw_before < kTimeMin || raw_before > kTimeMax) {
475
+ if (!ml_sqlite_int64_fits_time_t<kNeedLowerBound, kNeedUpperBound>(raw_after) ||
476
+ !ml_sqlite_int64_fits_time_t<kNeedLowerBound, kNeedUpperBound>(raw_before)) {
477
error_report("Skipping ML model row with out-of-range timestamps: after=%" PRId64 " before=%" PRId64,
478
(int64_t) raw_after, (int64_t) raw_before);
479
continue;