1#include "duckdb/function/compression/compression.hpp"
2#include "duckdb/common/types/vector.hpp"
3
4#include "duckdb/storage/table/column_segment.hpp"
5#include "duckdb/function/compression_function.hpp"
6#include "duckdb/storage/segment/uncompressed.hpp"
7#include "duckdb/storage/table/scan_state.hpp"
8
9namespace duckdb {
10
11//===--------------------------------------------------------------------===//
12// Scan
13//===--------------------------------------------------------------------===//
14unique_ptr<SegmentScanState> ConstantInitScan(ColumnSegment &segment) {
15 return nullptr;
16}
17
18//===--------------------------------------------------------------------===//
19// Scan Partial
20//===--------------------------------------------------------------------===//
21void ConstantFillFunctionValidity(ColumnSegment &segment, Vector &result, idx_t start_idx, idx_t count) {
22 auto &stats = segment.stats.statistics;
23 if (stats.CanHaveNull()) {
24 auto &mask = FlatVector::Validity(vector&: result);
25 for (idx_t i = 0; i < count; i++) {
26 mask.SetInvalid(start_idx + i);
27 }
28 }
29}
30
31template <class T>
32void ConstantFillFunction(ColumnSegment &segment, Vector &result, idx_t start_idx, idx_t count) {
33 auto &nstats = segment.stats.statistics;
34
35 auto data = FlatVector::GetData<T>(result);
36 auto constant_value = NumericStats::GetMin<T>(nstats);
37 for (idx_t i = 0; i < count; i++) {
38 data[start_idx + i] = constant_value;
39 }
40}
41
42void ConstantScanPartialValidity(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result,
43 idx_t result_offset) {
44 ConstantFillFunctionValidity(segment, result, start_idx: result_offset, count: scan_count);
45}
46
47template <class T>
48void ConstantScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result,
49 idx_t result_offset) {
50 ConstantFillFunction<T>(segment, result, result_offset, scan_count);
51}
52
53//===--------------------------------------------------------------------===//
54// Scan base data
55//===--------------------------------------------------------------------===//
56void ConstantScanFunctionValidity(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result) {
57 auto &stats = segment.stats.statistics;
58 if (stats.CanHaveNull()) {
59 if (result.GetVectorType() == VectorType::CONSTANT_VECTOR) {
60 result.SetVectorType(VectorType::CONSTANT_VECTOR);
61 ConstantVector::SetNull(vector&: result, is_null: true);
62 } else {
63 result.Flatten(count: scan_count);
64 ConstantFillFunctionValidity(segment, result, start_idx: 0, count: scan_count);
65 }
66 }
67}
68
69template <class T>
70void ConstantScanFunction(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result) {
71 auto &nstats = segment.stats.statistics;
72
73 auto data = FlatVector::GetData<T>(result);
74 data[0] = NumericStats::GetMin<T>(nstats);
75 result.SetVectorType(VectorType::CONSTANT_VECTOR);
76}
77
78//===--------------------------------------------------------------------===//
79// Fetch
80//===--------------------------------------------------------------------===//
81void ConstantFetchRowValidity(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result,
82 idx_t result_idx) {
83 ConstantFillFunctionValidity(segment, result, start_idx: result_idx, count: 1);
84}
85
86template <class T>
87void ConstantFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) {
88 ConstantFillFunction<T>(segment, result, result_idx, 1);
89}
90
91//===--------------------------------------------------------------------===//
92// Get Function
93//===--------------------------------------------------------------------===//
94CompressionFunction ConstantGetFunctionValidity(PhysicalType data_type) {
95 D_ASSERT(data_type == PhysicalType::BIT);
96 return CompressionFunction(CompressionType::COMPRESSION_CONSTANT, data_type, nullptr, nullptr, nullptr, nullptr,
97 nullptr, nullptr, ConstantInitScan, ConstantScanFunctionValidity,
98 ConstantScanPartialValidity, ConstantFetchRowValidity, UncompressedFunctions::EmptySkip);
99}
100
101template <class T>
102CompressionFunction ConstantGetFunction(PhysicalType data_type) {
103 return CompressionFunction(CompressionType::COMPRESSION_CONSTANT, data_type, nullptr, nullptr, nullptr, nullptr,
104 nullptr, nullptr, ConstantInitScan, ConstantScanFunction<T>, ConstantScanPartial<T>,
105 ConstantFetchRow<T>, UncompressedFunctions::EmptySkip);
106}
107
108CompressionFunction ConstantFun::GetFunction(PhysicalType data_type) {
109 switch (data_type) {
110 case PhysicalType::BIT:
111 return ConstantGetFunctionValidity(data_type);
112 case PhysicalType::BOOL:
113 case PhysicalType::INT8:
114 return ConstantGetFunction<int8_t>(data_type);
115 case PhysicalType::INT16:
116 return ConstantGetFunction<int16_t>(data_type);
117 case PhysicalType::INT32:
118 return ConstantGetFunction<int32_t>(data_type);
119 case PhysicalType::INT64:
120 return ConstantGetFunction<int64_t>(data_type);
121 case PhysicalType::UINT8:
122 return ConstantGetFunction<uint8_t>(data_type);
123 case PhysicalType::UINT16:
124 return ConstantGetFunction<uint16_t>(data_type);
125 case PhysicalType::UINT32:
126 return ConstantGetFunction<uint32_t>(data_type);
127 case PhysicalType::UINT64:
128 return ConstantGetFunction<uint64_t>(data_type);
129 case PhysicalType::INT128:
130 return ConstantGetFunction<hugeint_t>(data_type);
131 case PhysicalType::FLOAT:
132 return ConstantGetFunction<float>(data_type);
133 case PhysicalType::DOUBLE:
134 return ConstantGetFunction<double>(data_type);
135 default:
136 throw InternalException("Unsupported type for ConstantUncompressed::GetFunction");
137 }
138}
139
140bool ConstantFun::TypeIsSupported(PhysicalType type) {
141 switch (type) {
142 case PhysicalType::BIT:
143 case PhysicalType::BOOL:
144 case PhysicalType::INT8:
145 case PhysicalType::INT16:
146 case PhysicalType::INT32:
147 case PhysicalType::INT64:
148 case PhysicalType::UINT8:
149 case PhysicalType::UINT16:
150 case PhysicalType::UINT32:
151 case PhysicalType::UINT64:
152 case PhysicalType::INT128:
153 case PhysicalType::FLOAT:
154 case PhysicalType::DOUBLE:
155 return true;
156 default:
157 throw InternalException("Unsupported type for constant function");
158 }
159}
160
161} // namespace duckdb
162