| 224 | } |
| 225 | |
| 226 | void ColumnChunkData::updateStats(const ValueVector* vector, const SelectionView& selView) { |
| 227 | if (selView.isUnfiltered()) { |
| 228 | updateInMemoryStats(inMemoryStats, *vector); |
| 229 | } else { |
| 230 | TypeUtils::visit( |
| 231 | getDataType().getPhysicalType(), |
| 232 | [&]<StorageValueType T>(T) { |
| 233 | std::optional<T> firstValue; |
| 234 | // ValueVector::firstNonNull uses the vector's builtin selection vector, not the one |
| 235 | // passed as an argument |
| 236 | selView.forEachBreakWhenFalse([&](auto i) { |
| 237 | if (vector->isNull(i)) { |
| 238 | return true; |
| 239 | } else { |
| 240 | firstValue = vector->getValue<T>(i); |
| 241 | return false; |
| 242 | } |
| 243 | }); |
| 244 | if (!firstValue) { |
| 245 | return; |
| 246 | } |
| 247 | T min = *firstValue, max = *firstValue; |
| 248 | auto update = [&](sel_t pos) { |
| 249 | const auto val = vector->getValue<T>(pos); |
| 250 | if (val < min) { |
| 251 | min = val; |
| 252 | } else if (val > max) { |
| 253 | max = val; |
| 254 | } |
| 255 | }; |
| 256 | if (vector->hasNoNullsGuarantee()) { |
| 257 | selView.forEach(update); |
| 258 | } else { |
| 259 | selView.forEach([&](auto pos) { |
| 260 | if (!vector->isNull(pos)) { |
| 261 | update(pos); |
| 262 | } |
| 263 | }); |
| 264 | } |
| 265 | inMemoryStats.update(StorageValue(min), StorageValue(max), |
| 266 | getDataType().getPhysicalType()); |
| 267 | }, |
| 268 | []<typename T>(T) { static_assert(!StorageValueType<T>); }); |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | void ColumnChunkData::resetInMemoryStats() { |
| 273 | inMemoryStats.reset(); |
nothing calls this directly
no test coverage detected