MCPcopy Create free account
hub / github.com/apache/cloudberry / GetCachedPlan

Function GetCachedPlan

src/backend/utils/cache/plancache.c:1248–1358  ·  view source on GitHub ↗

* GetCachedPlan: get a cached plan from a CachedPlanSource. * * This function hides the logic that decides whether to use a generic * plan or a custom plan for the given parameters: the caller does not know * which it will get. * * On return, the plan is valid and we have sufficient locks to begin * execution. * * On return, the refcount of the plan has been incremented; a later * Releas

Source from the content-addressed store, hash-verified

1246 * therefore also forces the plan to be re-planned on next call.
1247 */
1248CachedPlan *
1249GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams,
1250 ResourceOwner owner, QueryEnvironment *queryEnv, IntoClause *intoClause)
1251{
1252 CachedPlan *plan = NULL;
1253 List *qlist;
1254 bool customplan;
1255
1256 /* Assert caller is doing things in a sane order */
1257 Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC);
1258 Assert(plansource->is_complete);
1259 /* This seems worth a real test, though */
1260 if (owner && !plansource->is_saved)
1261 elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan");
1262
1263 /* Make sure the querytree list is valid and we have parse-time locks */
1264 qlist = RevalidateCachedQuery(plansource, queryEnv, intoClause);
1265
1266 /* Decide whether to use a custom plan */
1267 customplan = choose_custom_plan(plansource, boundParams, intoClause);
1268
1269 if (!customplan)
1270 {
1271 if (CheckCachedPlan(plansource))
1272 {
1273 /* We want a generic plan, and we already have a valid one */
1274 plan = plansource->gplan;
1275 Assert(plan->magic == CACHEDPLAN_MAGIC);
1276 }
1277 else
1278 {
1279 /* Build a new generic plan */
1280 plan = BuildCachedPlan(plansource, qlist, NULL, queryEnv, NULL);
1281 /* Just make real sure plansource->gplan is clear */
1282 ReleaseGenericPlan(plansource);
1283 /* Link the new generic plan into the plansource */
1284 plansource->gplan = plan;
1285 plan->refcount++;
1286 /* Immediately reparent into appropriate context */
1287 if (plansource->is_saved)
1288 {
1289 /* saved plans all live under CacheMemoryContext */
1290 MemoryContextSetParent(plan->context, CacheMemoryContext);
1291 plan->is_saved = true;
1292 }
1293 else
1294 {
1295 /* otherwise, it should be a sibling of the plansource */
1296 MemoryContextSetParent(plan->context,
1297 MemoryContextGetParent(plansource->context));
1298 }
1299 /* Update generic_cost whenever we make a new generic plan */
1300 plansource->generic_cost = cached_plan_cost(plan, false);
1301
1302 /*
1303 * If, based on the now-known value of generic_cost, we'd not have
1304 * chosen to use a generic plan, then forget it and make a custom
1305 * plan. This is a bit of a wart but is necessary to avoid a

Callers 6

exec_bind_messageFunction · 0.85
ExecuteQueryFunction · 0.85
ExplainExecuteQueryFunction · 0.85
SPI_cursor_open_internalFunction · 0.85
SPI_plan_get_cached_planFunction · 0.85
_SPI_execute_planFunction · 0.85

Calls 10

RevalidateCachedQueryFunction · 0.85
choose_custom_planFunction · 0.85
CheckCachedPlanFunction · 0.85
BuildCachedPlanFunction · 0.85
ReleaseGenericPlanFunction · 0.85
MemoryContextSetParentFunction · 0.85
MemoryContextGetParentFunction · 0.85
cached_plan_costFunction · 0.85

Tested by

no test coverage detected