* Sets up the required infrastructure for backend workers to perform * execution and return results to the main backend. */
| 588 | * execution and return results to the main backend. |
| 589 | */ |
| 590 | ParallelExecutorInfo * |
| 591 | ExecInitParallelPlan(PlanState *planstate, EState *estate, |
| 592 | Bitmapset *sendParams, int nworkers, |
| 593 | int64 tuples_needed) |
| 594 | { |
| 595 | ParallelExecutorInfo *pei; |
| 596 | ParallelContext *pcxt; |
| 597 | ExecParallelEstimateContext e; |
| 598 | ExecParallelInitializeDSMContext d; |
| 599 | FixedParallelExecutorState *fpes; |
| 600 | char *pstmt_data; |
| 601 | char *pstmt_space; |
| 602 | char *paramlistinfo_space; |
| 603 | BufferUsage *bufusage_space; |
| 604 | WalUsage *walusage_space; |
| 605 | SharedExecutorInstrumentation *instrumentation = NULL; |
| 606 | SharedJitInstrumentation *jit_instrumentation = NULL; |
| 607 | int pstmt_len; |
| 608 | int paramlistinfo_len; |
| 609 | int instrumentation_len = 0; |
| 610 | int jit_instrumentation_len = 0; |
| 611 | int instrument_offset = 0; |
| 612 | Size dsa_minsize = dsa_minimum_size(); |
| 613 | char *query_string; |
| 614 | int query_len; |
| 615 | |
| 616 | /* |
| 617 | * Force any initplan outputs that we're going to pass to workers to be |
| 618 | * evaluated, if they weren't already. |
| 619 | * |
| 620 | * For simplicity, we use the EState's per-output-tuple ExprContext here. |
| 621 | * That risks intra-query memory leakage, since we might pass through here |
| 622 | * many times before that ExprContext gets reset; but ExecSetParamPlan |
| 623 | * doesn't normally leak any memory in the context (see its comments), so |
| 624 | * it doesn't seem worth complicating this function's API to pass it a |
| 625 | * shorter-lived ExprContext. This might need to change someday. |
| 626 | */ |
| 627 | ExecSetParamPlanMulti(sendParams, GetPerTupleExprContext(estate), NULL); |
| 628 | |
| 629 | /* Allocate object for return value. */ |
| 630 | pei = palloc0(sizeof(ParallelExecutorInfo)); |
| 631 | pei->finished = false; |
| 632 | pei->planstate = planstate; |
| 633 | |
| 634 | /* Fix up and serialize plan to be sent to workers. */ |
| 635 | pstmt_data = ExecSerializePlan(planstate->plan, estate); |
| 636 | |
| 637 | /* Create a parallel context. */ |
| 638 | pcxt = CreateParallelContext("postgres", "ParallelQueryMain", nworkers); |
| 639 | pei->pcxt = pcxt; |
| 640 | |
| 641 | /* |
| 642 | * Before telling the parallel context to create a dynamic shared memory |
| 643 | * segment, we need to figure out how big it should be. Estimate space |
| 644 | * for the various things we need to store. |
| 645 | */ |
| 646 | |
| 647 | /* Estimate space for fixed-size state. */ |
no test coverage detected