---------------- * FreeExecutorState * * Release an EState along with all remaining working storage. * * Note: this is not responsible for releasing non-memory resources, such as * open relations or buffer pins. But it will shut down any still-active * ExprContexts within the EState and deallocate associated JITed expressions. * That is sufficient cleanup for situations where the EState
| 238 | * ---------------- |
| 239 | */ |
| 240 | void |
| 241 | FreeExecutorState(EState *estate) |
| 242 | { |
| 243 | /* |
| 244 | * Shut down and free any remaining ExprContexts. We do this explicitly |
| 245 | * to ensure that any remaining shutdown callbacks get called (since they |
| 246 | * might need to release resources that aren't simply memory within the |
| 247 | * per-query memory context). |
| 248 | */ |
| 249 | while (estate->es_exprcontexts) |
| 250 | { |
| 251 | /* |
| 252 | * XXX: seems there ought to be a faster way to implement this than |
| 253 | * repeated list_delete(), no? |
| 254 | */ |
| 255 | FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts), |
| 256 | true); |
| 257 | /* FreeExprContext removed the list link for us */ |
| 258 | } |
| 259 | |
| 260 | estate->dispatcherState = NULL; |
| 261 | |
| 262 | /* release JIT context, if allocated */ |
| 263 | if (estate->es_jit) |
| 264 | { |
| 265 | jit_release_context(estate->es_jit); |
| 266 | estate->es_jit = NULL; |
| 267 | } |
| 268 | |
| 269 | /* release partition directory, if allocated */ |
| 270 | if (estate->es_partition_directory) |
| 271 | { |
| 272 | DestroyPartitionDirectory(estate->es_partition_directory); |
| 273 | estate->es_partition_directory = NULL; |
| 274 | } |
| 275 | |
| 276 | /* |
| 277 | * Free the per-query memory context, thereby releasing all working |
| 278 | * memory, including the EState node itself. |
| 279 | */ |
| 280 | MemoryContextDelete(estate->es_query_cxt); |
| 281 | } |
| 282 | |
| 283 | /* |
| 284 | * Internal implementation for CreateExprContext() and CreateWorkExprContext() |