MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / buildPlanForQueryNode

Method buildPlanForQueryNode

src/Planner/Planner.cpp:2093–2701  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2091}
2092
2093void Planner::buildPlanForQueryNode()
2094{
2095 ProfileEvents::increment(ProfileEvents::SelectQueriesWithSubqueries);
2096 ProfileEvents::increment(ProfileEvents::QueriesWithSubqueries);
2097
2098 auto & query_node = query_tree->as<QueryNode &>();
2099 const auto & query_context = planner_context->getQueryContext();
2100 if (query_node.hasWhere())
2101 {
2102 auto condition_constant = tryExtractConstantFromConditionNode(query_node.getWhere());
2103 if (condition_constant.has_value() && *condition_constant)
2104 query_node.getWhere() = {};
2105 }
2106
2107 SelectQueryInfo select_query_info = buildSelectQueryInfo();
2108 const Settings & settings = query_context->getSettingsRef();
2109
2110 QueryResultCachePtr query_result_cache = planner_context->getMutableQueryContext()->getQueryResultCache();
2111 bool can_use_query_result_cache = query_context->getCanUseQueryResultCache();
2112 ASTPtr ast = select_query_info.query;
2113
2114 /// Determine if the query result cache should be used for this query node (with `is_subquery = true` key).
2115 /// The Planner-level cache is separate from the `executeQuery`-level cache (`is_subquery = false`).
2116 /// Rules:
2117 /// 1. For actual subqueries: explicit SETTINGS `use_query_cache` on the node wins
2118 /// 2. `query_cache_for_subqueries` propagates from outer query (applies to all Planner invocations)
2119 /// 3. By default, `use_query_cache` does NOT propagate from outer query to subqueries
2120 bool should_cache = shouldUseQueryCacheForSubquery(query_node, can_use_query_result_cache, settings,
2121 select_query_options.is_subquery, query_context);
2122
2123 /// Query result cache must actually exist
2124 if (should_cache && !query_result_cache)
2125 should_cache = false;
2126
2127 /// For explicit per-subquery opt-in, we track cache eligibility locally
2128 /// without mutating the shared query context (which would leak to the outer query).
2129 bool local_can_use_cache = can_use_query_result_cache || should_cache;
2130
2131 /// If the query runs with "use_query_cache = 1", we first probe if the query cache already contains the query result (if yes:
2132 /// return result from cache). If doesn't, we execute the query normally and write the result into the query cache. Both steps use a
2133 /// hash of the AST, the current database and the settings as cache key. Unfortunately, the settings are in some places internally
2134 /// modified between steps 1 and 2 (= during query execution) - this is silly but hard to forbid. As a result, the hashes no longer
2135 /// match and the cache is rendered ineffective. Therefore make a copy of the settings and use it for steps 1 and 2.
2136 std::optional<Settings> settings_copy;
2137 if (local_can_use_cache)
2138 settings_copy = settings;
2139
2140 /// If it is a non-internal SELECT, and passive (read) use of the query cache is enabled, and the cache knows the query, then add a ReadFromQueryResultCacheStep instead of building the rest of the plan.
2141 if (should_cache && settings[Setting::enable_reads_from_query_cache])
2142 {
2143 QueryResultCache::Key key(ast, query_context->getCurrentDatabase(), *settings_copy, query_context->getCurrentQueryId(), query_context->getUserID(), query_context->getCurrentRoles(), /* is_subquery = */ true);
2144 auto reader = std::make_shared<QueryResultCacheReader>(query_result_cache->createReader(key));
2145 if (reader->hasCacheEntryForKey())
2146 {
2147 addReadFromQueryResultCacheStep(query_plan, reader->getSource(), reader->getSourceTotals(), reader->getSourceExtremes());
2148 return;
2149 }
2150 }

Callers

nothing calls this directly

Calls 15

buildSelectQueryInfoFunction · 0.85
buildStorageLimitsFunction · 0.85
hasWindowFunctionNodesFunction · 0.85
mergeConditionNodesFunction · 0.85
collectSetsFunction · 0.85
collectMaterializedCTEsFunction · 0.85

Tested by

no test coverage detected