/src/duckdb/src/storage/statistics/struct_statistics.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "duckdb/storage/statistics/struct_statistics.hpp" |
2 | | |
3 | | #include "duckdb/common/field_writer.hpp" |
4 | | #include "duckdb/common/types/vector.hpp" |
5 | | |
6 | | namespace duckdb { |
7 | | |
8 | 0 | StructStatistics::StructStatistics(LogicalType type_p) : BaseStatistics(move(type_p), StatisticsType::LOCAL_STATS) { |
9 | 0 | D_ASSERT(type.InternalType() == PhysicalType::STRUCT); |
10 | 0 | InitializeBase(); |
11 | |
|
12 | 0 | auto &child_types = StructType::GetChildTypes(type); |
13 | 0 | child_stats.resize(child_types.size()); |
14 | 0 | for (idx_t i = 0; i < child_types.size(); i++) { |
15 | 0 | child_stats[i] = BaseStatistics::CreateEmpty(child_types[i].second, StatisticsType::LOCAL_STATS); |
16 | 0 | } |
17 | 0 | } |
18 | | |
19 | 0 | void StructStatistics::Merge(const BaseStatistics &other_p) { |
20 | 0 | BaseStatistics::Merge(other_p); |
21 | |
|
22 | 0 | auto &other = (const StructStatistics &)other_p; |
23 | 0 | D_ASSERT(other.child_stats.size() == child_stats.size()); |
24 | 0 | for (idx_t i = 0; i < child_stats.size(); i++) { |
25 | 0 | if (child_stats[i] && other.child_stats[i]) { |
26 | 0 | child_stats[i]->Merge(*other.child_stats[i]); |
27 | 0 | } else { |
28 | 0 | child_stats[i].reset(); |
29 | 0 | } |
30 | 0 | } |
31 | 0 | } |
32 | | |
33 | | // LCOV_EXCL_START |
34 | 0 | FilterPropagateResult StructStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) const { |
35 | 0 | throw InternalException("Struct zonemaps are not supported yet"); |
36 | 0 | } |
37 | | // LCOV_EXCL_STOP |
38 | | |
39 | 0 | unique_ptr<BaseStatistics> StructStatistics::Copy() const { |
40 | 0 | auto result = make_unique<StructStatistics>(type); |
41 | 0 | result->CopyBase(*this); |
42 | |
|
43 | 0 | for (idx_t i = 0; i < child_stats.size(); i++) { |
44 | 0 | result->child_stats[i] = child_stats[i] ? child_stats[i]->Copy() : nullptr; |
45 | 0 | } |
46 | 0 | return move(result); |
47 | 0 | } |
48 | | |
49 | 0 | void StructStatistics::Serialize(FieldWriter &writer) const { |
50 | 0 | writer.WriteField<uint32_t>(child_stats.size()); |
51 | 0 | auto &serializer = writer.GetSerializer(); |
52 | 0 | for (idx_t i = 0; i < child_stats.size(); i++) { |
53 | 0 | serializer.Write<bool>(child_stats[i] ? true : false); |
54 | 0 | if (child_stats[i]) { |
55 | 0 | child_stats[i]->Serialize(serializer); |
56 | 0 | } |
57 | 0 | } |
58 | 0 | } |
59 | | |
60 | 0 | unique_ptr<BaseStatistics> StructStatistics::Deserialize(FieldReader &reader, LogicalType type) { |
61 | 0 | D_ASSERT(type.InternalType() == PhysicalType::STRUCT); |
62 | 0 | auto result = make_unique<StructStatistics>(move(type)); |
63 | 0 | auto &child_types = StructType::GetChildTypes(result->type); |
64 | |
|
65 | 0 | auto child_type_count = reader.ReadRequired<uint32_t>(); |
66 | 0 | if (child_types.size() != child_type_count) { |
67 | 0 | throw InternalException("Struct stats deserialization failure: child count does not match type count!"); |
68 | 0 | } |
69 | 0 | auto &source = reader.GetSource(); |
70 | 0 | for (idx_t i = 0; i < child_types.size(); i++) { |
71 | 0 | auto has_child = source.Read<bool>(); |
72 | 0 | if (has_child) { |
73 | 0 | result->child_stats[i] = BaseStatistics::Deserialize(source, child_types[i].second); |
74 | 0 | } else { |
75 | 0 | result->child_stats[i].reset(); |
76 | 0 | } |
77 | 0 | } |
78 | 0 | return move(result); |
79 | 0 | } |
80 | | |
81 | 0 | string StructStatistics::ToString() const { |
82 | 0 | string result; |
83 | 0 | result += " {"; |
84 | 0 | auto &child_types = StructType::GetChildTypes(type); |
85 | 0 | for (idx_t i = 0; i < child_types.size(); i++) { |
86 | 0 | if (i > 0) { |
87 | 0 | result += ", "; |
88 | 0 | } |
89 | 0 | result += child_types[i].first + ": " + (child_stats[i] ? child_stats[i]->ToString() : "No Stats"); |
90 | 0 | } |
91 | 0 | result += "}"; |
92 | 0 | result += BaseStatistics::ToString(); |
93 | 0 | return result; |
94 | 0 | } |
95 | | |
96 | 0 | void StructStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { |
97 | 0 | BaseStatistics::Verify(vector, sel, count); |
98 | |
|
99 | 0 | auto &child_entries = StructVector::GetEntries(vector); |
100 | 0 | for (idx_t i = 0; i < child_entries.size(); i++) { |
101 | 0 | if (child_stats[i]) { |
102 | 0 | child_stats[i]->Verify(*child_entries[i], sel, count); |
103 | 0 | } |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | } // namespace duckdb |