1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/storage/statistics/numeric_stats.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/storage/statistics/numeric_stats_union.hpp"
12#include "duckdb/common/enums/filter_propagate_result.hpp"
13#include "duckdb/common/enums/expression_type.hpp"
14#include "duckdb/common/operator/comparison_operators.hpp"
15#include "duckdb/common/types/value.hpp"
16
17namespace duckdb {
18class BaseStatistics;
19class FieldWriter;
20class FieldReader;
21struct SelectionVector;
22class Vector;
23
24struct NumericStatsData {
25 //! Whether or not the value has a max value
26 bool has_min;
27 //! Whether or not the segment has a min value
28 bool has_max;
29 //! The minimum value of the segment
30 NumericValueUnion min;
31 //! The maximum value of the segment
32 NumericValueUnion max;
33};
34
35struct NumericStats {
36 //! Unknown statistics - i.e. "has_min" is false, "has_max" is false
37 DUCKDB_API static BaseStatistics CreateUnknown(LogicalType type);
38 //! Empty statistics - i.e. "min = MaxValue<type>, max = MinValue<type>"
39 DUCKDB_API static BaseStatistics CreateEmpty(LogicalType type);
40
41 //! Returns true if the stats has a constant value
42 DUCKDB_API static bool IsConstant(const BaseStatistics &stats);
43 //! Returns true if the stats has both a min and max value defined
44 DUCKDB_API static bool HasMinMax(const BaseStatistics &stats);
45 //! Returns true if the stats has a min value defined
46 DUCKDB_API static bool HasMin(const BaseStatistics &stats);
47 //! Returns true if the stats has a max value defined
48 DUCKDB_API static bool HasMax(const BaseStatistics &stats);
49 //! Returns the min value - throws an exception if there is no min value
50 DUCKDB_API static Value Min(const BaseStatistics &stats);
51 //! Returns the max value - throws an exception if there is no max value
52 DUCKDB_API static Value Max(const BaseStatistics &stats);
53 //! Sets the min value of the statistics
54 DUCKDB_API static void SetMin(BaseStatistics &stats, const Value &val);
55 //! Sets the max value of the statistics
56 DUCKDB_API static void SetMax(BaseStatistics &stats, const Value &val);
57
58 //! Check whether or not a given comparison with a constant could possibly be satisfied by rows given the statistics
59 DUCKDB_API static FilterPropagateResult CheckZonemap(const BaseStatistics &stats, ExpressionType comparison_type,
60 const Value &constant);
61
62 DUCKDB_API static void Merge(BaseStatistics &stats, const BaseStatistics &other_p);
63
64 DUCKDB_API static void Serialize(const BaseStatistics &stats, FieldWriter &writer);
65 DUCKDB_API static BaseStatistics Deserialize(FieldReader &reader, LogicalType type);
66
67 DUCKDB_API static string ToString(const BaseStatistics &stats);
68
69 template <class T>
70 static inline void UpdateValue(T new_value, T &min, T &max) {
71 if (LessThan::Operation(new_value, min)) {
72 min = new_value;
73 }
74 if (GreaterThan::Operation(new_value, max)) {
75 max = new_value;
76 }
77 }
78
79 template <class T>
80 static inline void Update(BaseStatistics &stats, T new_value) {
81 auto &nstats = NumericStats::GetDataUnsafe(stats);
82 UpdateValue<T>(new_value, nstats.min.GetReferenceUnsafe<T>(), nstats.max.GetReferenceUnsafe<T>());
83 }
84
85 static void Verify(const BaseStatistics &stats, Vector &vector, const SelectionVector &sel, idx_t count);
86
87 template <class T>
88 static T GetMin(const BaseStatistics &stats) {
89 return NumericStats::Min(stats).GetValueUnsafe<T>();
90 }
91 template <class T>
92 static T GetMax(const BaseStatistics &stats) {
93 return NumericStats::Max(stats).GetValueUnsafe<T>();
94 }
95 template <class T>
96 static T GetMinUnsafe(const BaseStatistics &stats);
97 template <class T>
98 static T GetMaxUnsafe(const BaseStatistics &stats);
99
100private:
101 static NumericStatsData &GetDataUnsafe(BaseStatistics &stats);
102 static const NumericStatsData &GetDataUnsafe(const BaseStatistics &stats);
103 static Value MinOrNull(const BaseStatistics &stats);
104 static Value MaxOrNull(const BaseStatistics &stats);
105 template <class T>
106 static void TemplatedVerify(const BaseStatistics &stats, Vector &vector, const SelectionVector &sel, idx_t count);
107};
108
109template <>
110void NumericStats::Update<interval_t>(BaseStatistics &stats, interval_t new_value);
111template <>
112void NumericStats::Update<list_entry_t>(BaseStatistics &stats, list_entry_t new_value);
113
114} // namespace duckdb
115