| 155 | } |
| 156 | |
| 157 | bool PlanCacheManager::addPlanToCache(UInt128 query_hash, QueryPlanPtr & plan, AnalysisPtr analysis, ContextMutablePtr & context) |
| 158 | { |
| 159 | if (!context->getPlanCacheManager()) |
| 160 | throw Exception("plan cache has to be initialized", ErrorCodes::LOGICAL_ERROR); |
| 161 | |
| 162 | auto & cache = context->getPlanCacheManager()->instance(); |
| 163 | auto root = plan->getPlanNode(); |
| 164 | UInt32 size = QueryPlan::getPlanNodeCount(root); |
| 165 | |
| 166 | if (size > context->getSettingsRef().max_plannode_count) |
| 167 | return false; |
| 168 | |
| 169 | PlanNodeId max_id; |
| 170 | PlanCacheManager::PlanObjectValue plan_object{}; |
| 171 | plan_object.plan_root = PlanCacheManager::getNewPlanNode(root, context, true, max_id); |
| 172 | |
| 173 | for (const auto & cte : plan->getCTEInfo().getCTEs()) |
| 174 | plan_object.cte_map.emplace(cte.first, PlanCacheManager::getNewPlanNode(cte.second, context, true, max_id)); |
| 175 | |
| 176 | plan_object.query_info = std::make_shared<PlanCacheManager::QueryInfo>(); |
| 177 | const auto & used_columns_map = analysis->getUsedColumns(); |
| 178 | for (const auto & [table_ast, storage_analysis] : analysis->getStorages()) |
| 179 | { |
| 180 | if (!storage_analysis.storage) |
| 181 | continue; |
| 182 | auto storage_id = storage_analysis.storage->getStorageID(); |
| 183 | if (auto it = used_columns_map.find(storage_analysis.storage->getStorageID()); it != used_columns_map.end()) |
| 184 | { |
| 185 | for (const auto & column : it->second) |
| 186 | plan_object.query_info->query_access_info[backQuoteIfNeed(storage_id.getDatabaseName())][storage_id.getFullTableName()].emplace_back(column); |
| 187 | } |
| 188 | |
| 189 | Statistics::StatsTableIdentifier table_identifier{storage_id}; |
| 190 | auto version_value = Statistics::getVersion(context, table_identifier); |
| 191 | Int64 version = version_value.has_value() ? version_value.value().convertTo<Int64>() : 0; |
| 192 | plan_object.query_info->stats_version[storage_id] = version; |
| 193 | } |
| 194 | cache.add(query_hash, plan_object); |
| 195 | return true; |
| 196 | } |
| 197 | |
| 198 | bool PlanCacheManager::enableCachePlan(const ASTPtr & query_ast, ContextPtr context) |
| 199 | { |
nothing calls this directly
no test coverage detected