---------------------------------------------------------------- * ExecInitWorkTableScan * ---------------------------------------------------------------- */
| 99 | * ---------------------------------------------------------------- |
| 100 | */ |
| 101 | WorkTableScanState * |
| 102 | ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags) |
| 103 | { |
| 104 | WorkTableScanState *scanstate; |
| 105 | ParamExecData *param; |
| 106 | |
| 107 | /* check for unsupported flags */ |
| 108 | /* |
| 109 | * RECURSIVE_CTE_FIXME: Make sure we don't require EXEC_FLAG_BACKWARD |
| 110 | * in GPDB. |
| 111 | */ |
| 112 | Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); |
| 113 | |
| 114 | /* |
| 115 | * WorkTableScan should not have any children. |
| 116 | */ |
| 117 | Assert(outerPlan(node) == NULL); |
| 118 | Assert(innerPlan(node) == NULL); |
| 119 | |
| 120 | /* |
| 121 | * create new WorkTableScanState for node |
| 122 | */ |
| 123 | scanstate = makeNode(WorkTableScanState); |
| 124 | scanstate->ss.ps.plan = (Plan *) node; |
| 125 | scanstate->ss.ps.state = estate; |
| 126 | scanstate->ss.ps.ExecProcNode = ExecWorkTableScan; |
| 127 | |
| 128 | /* In postgres, it can generate CTE SubPlans for WITH subqueries, if a CTE subplan have outer |
| 129 | * recursive refs with outer recursive CTE, it will exist a WorkTable in subplan. And initialize |
| 130 | * state information for subplans will be before initialize on the main query tree, so there are |
| 131 | * corner cases where we'll get the init call before the RecursiveUnion does. |
| 132 | * IN GPDB, we don't have CTE scan node, so we won't generate CTE subplan for WITH subqueries, |
| 133 | * also we won't call the ExecInitWorkTableScan func before ExecInitRecursiveUnion. Set rustate |
| 134 | * in the INIT step. |
| 135 | */ |
| 136 | param = &(estate->es_param_exec_vals[node->wtParam]); |
| 137 | Assert(param->execPlan == NULL); |
| 138 | Assert(!param->isnull); |
| 139 | scanstate->rustate = castNode(RecursiveUnionState, DatumGetPointer(param->value)); |
| 140 | if (scanstate->rustate->refcount == 0) |
| 141 | scanstate->readptr = 0; |
| 142 | else |
| 143 | { |
| 144 | /* during node init, the work table hasn't been scanned yet, it must be at start, don't need to rescan here*/ |
| 145 | scanstate->readptr = tuplestore_alloc_read_pointer(scanstate->rustate->working_table, EXEC_FLAG_REWIND); |
| 146 | } |
| 147 | scanstate->rustate->refcount++; |
| 148 | |
| 149 | /* |
| 150 | * Miscellaneous initialization |
| 151 | * |
| 152 | * create expression context for node |
| 153 | */ |
| 154 | ExecAssignExprContext(estate, &scanstate->ss.ps); |
| 155 | |
| 156 | /* |
| 157 | * tuple table initialization |
| 158 | */ |
no test coverage detected