diff --git a/src/Storages/StorageMerge.cpp b/src/Storages/StorageMerge.cpp index 1bf585771ff..36c92129177 100644 --- a/src/Storages/StorageMerge.cpp +++ b/src/Storages/StorageMerge.cpp @@ -1295,38 +1295,35 @@ std::tuple StorageMerge::evaluateDatabaseName(cons bool StorageMerge::supportsTrivialCountOptimization() const { - bool supported = true; - forEachTable([&](const auto & table) - { - supported &= table->supportsTrivialCountOptimization(); - }); - return supported; + return getFirstTable([&](const auto & table) { return !table->supportsTrivialCountOptimization(); }) == nullptr; } std::optional StorageMerge::totalRows(const Settings & settings) const { - UInt64 total_rows = 0; - forEachTable([&](const auto & table) - { - std::optional rows = table->totalRows(settings); - if (rows) - total_rows += *rows; - }); - return {total_rows}; + return totalRowsOrBytes([&](const auto & table) { return table->totalRows(settings); }); } std::optional StorageMerge::totalBytes(const Settings & settings) const { - UInt64 total_bytes = 0; - forEachTable([&](const auto & table) - { - std::optional bytes = table->totalBytes(settings); - if (bytes) - total_bytes += *bytes; - }); - return {total_bytes}; + return totalRowsOrBytes([&](const auto & table) { return table->totalBytes(settings); }); } +template +std::optional StorageMerge::totalRowsOrBytes(F && func) const +{ + UInt64 total_rows_or_bytes = 0; + auto first_table = getFirstTable([&](const auto & table) + { + if (auto rows_or_bytes = func(table)) + { + total_rows_or_bytes += *rows_or_bytes; + return false; + } + return true; + }); + + return first_table ? std::nullopt : std::make_optional(total_rows_or_bytes); +} void registerStorageMerge(StorageFactory & factory) { diff --git a/src/Storages/StorageMerge.h b/src/Storages/StorageMerge.h index 762dc71ab83..2455eb678bb 100644 --- a/src/Storages/StorageMerge.h +++ b/src/Storages/StorageMerge.h @@ -79,8 +79,8 @@ public: bool supportsTrivialCountOptimization() const override; - std::optional totalRows(const Settings &) const override; - std::optional totalBytes(const Settings &) const override; + std::optional totalRows(const Settings & settings) const override; + std::optional totalBytes(const Settings & settings) const override; private: std::optional source_database_regexp; @@ -118,6 +118,9 @@ private: bool tableSupportsPrewhere() const; + template + std::optional totalRowsOrBytes(F && func) const; + friend class ReadFromMerge; };