| 189 | |
| 190 | |
| 191 | TupleTableSlot * |
| 192 | ExecDynamicForeignScan(PlanState *pstate) |
| 193 | { |
| 194 | DynamicForeignScanState *node = castNode(DynamicForeignScanState, pstate); |
| 195 | TupleTableSlot *slot = NULL; |
| 196 | |
| 197 | DynamicForeignScan *plan = (DynamicForeignScan *) node->ss.ps.plan; |
| 198 | node->as_valid_subplans = NULL; |
| 199 | if (NULL != plan->join_prune_paramids && !node->did_pruning) |
| 200 | { |
| 201 | node->did_pruning = true; |
| 202 | node->as_valid_subplans = |
| 203 | ExecFindMatchingSubPlans(node->as_prune_state, |
| 204 | node->ss.ps.state, |
| 205 | list_length(plan->partOids), |
| 206 | plan->join_prune_paramids); |
| 207 | |
| 208 | int i = 0; |
| 209 | int partOidIdx = -1; |
| 210 | node->nOids = bms_num_members(node->as_valid_subplans); |
| 211 | List *newPartOids = NIL; |
| 212 | void **new_fdw_private_array; /* array of fdw_private*/ |
| 213 | ListCell *lc; |
| 214 | /* Need to re-populate fdw_private_array based on dynamically eliminated partitions */ |
| 215 | new_fdw_private_array = (void **) palloc(node->nOids * sizeof(void *)); |
| 216 | for(i = 0; i < node->nOids; i++) |
| 217 | { |
| 218 | partOidIdx = bms_next_member(node->as_valid_subplans, partOidIdx); |
| 219 | newPartOids = lappend_oid(newPartOids, node->partOids[partOidIdx]); |
| 220 | new_fdw_private_array[i] = node->fdw_private_array[partOidIdx]; |
| 221 | } |
| 222 | pfree(node->partOids); |
| 223 | pfree(node->fdw_private_array); |
| 224 | node->partOids = palloc(sizeof(Oid) * node->nOids); |
| 225 | foreach_with_count(lc, newPartOids, i) |
| 226 | node->partOids[i] = lfirst_oid(lc); |
| 227 | node->fdw_private_array = new_fdw_private_array; |
| 228 | } |
| 229 | |
| 230 | /* |
| 231 | * Scan the table to find next tuple to return. If the current table |
| 232 | * is finished, close it and open the next table for scan. |
| 233 | */ |
| 234 | for (;;) |
| 235 | { |
| 236 | if (!node->foreignScanState) |
| 237 | { |
| 238 | /* No partition open. Open the next one, if any. */ |
| 239 | if (!initNextTableToScan(node)) |
| 240 | break; |
| 241 | } |
| 242 | |
| 243 | slot = ExecProcNode(&node->foreignScanState->ss.ps); |
| 244 | |
| 245 | if (!TupIsNull(slot)) |
| 246 | break; |
| 247 | |
| 248 | /* No more tuples from this partition. Move to next one. */ |
nothing calls this directly
no test coverage detected