* ExecScanReScan * * This must be called within the ReScan function of any plan node type * that uses ExecScan(). */
| 311 | * that uses ExecScan(). |
| 312 | */ |
| 313 | void |
| 314 | ExecScanReScan(ScanState *node) |
| 315 | { |
| 316 | EState *estate = node->ps.state; |
| 317 | |
| 318 | /* |
| 319 | * We must clear the scan tuple so that observers (e.g., execCurrent.c) |
| 320 | * can tell that this plan node is not positioned on a tuple. |
| 321 | */ |
| 322 | ExecClearTuple(node->ss_ScanTupleSlot); |
| 323 | |
| 324 | /* Rescan EvalPlanQual tuple if we're inside an EvalPlanQual recheck */ |
| 325 | if (estate->es_epq_active != NULL) |
| 326 | { |
| 327 | EPQState *epqstate = estate->es_epq_active; |
| 328 | Index scanrelid = ((Scan *) node->ps.plan)->scanrelid; |
| 329 | |
| 330 | if (scanrelid > 0) |
| 331 | epqstate->relsubs_done[scanrelid - 1] = false; |
| 332 | else |
| 333 | { |
| 334 | Bitmapset *relids; |
| 335 | int rtindex = -1; |
| 336 | |
| 337 | /* |
| 338 | * If an FDW or custom scan provider has replaced the join with a |
| 339 | * scan, there are multiple RTIs; reset the epqScanDone flag for |
| 340 | * all of them. |
| 341 | */ |
| 342 | if (IsA(node->ps.plan, ForeignScan)) |
| 343 | relids = ((ForeignScan *) node->ps.plan)->fs_relids; |
| 344 | else if (IsA(node->ps.plan, CustomScan)) |
| 345 | relids = ((CustomScan *) node->ps.plan)->custom_relids; |
| 346 | else |
| 347 | elog(ERROR, "unexpected scan node: %d", |
| 348 | (int) nodeTag(node->ps.plan)); |
| 349 | |
| 350 | while ((rtindex = bms_next_member(relids, rtindex)) >= 0) |
| 351 | { |
| 352 | Assert(rtindex > 0); |
| 353 | epqstate->relsubs_done[rtindex - 1] = false; |
| 354 | } |
| 355 | } |
| 356 | } |
| 357 | } |
no test coverage detected