diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execScan.c | 6 | ||||
-rw-r--r-- | src/backend/executor/nodeCustom.c | 34 | ||||
-rw-r--r-- | src/backend/executor/nodeForeignscan.c | 31 |
3 files changed, 50 insertions, 21 deletions
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c index 3f0d8093875..fa475014f13 100644 --- a/src/backend/executor/execScan.c +++ b/src/backend/executor/execScan.c @@ -251,6 +251,12 @@ ExecAssignScanProjectionInfo(ScanState *node) /* Vars in an index-only scan's tlist should be INDEX_VAR */ if (IsA(scan, IndexOnlyScan)) varno = INDEX_VAR; + /* Also foreign or custom scan on pseudo relation should be INDEX_VAR */ + else if (scan->scanrelid == 0) + { + Assert(IsA(scan, ForeignScan) || IsA(scan, CustomScan)); + varno = INDEX_VAR; + } else varno = scan->scanrelid; diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c index b07932b32e5..db1b4f2ffa4 100644 --- a/src/backend/executor/nodeCustom.c +++ b/src/backend/executor/nodeCustom.c @@ -23,7 +23,7 @@ CustomScanState * ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) { CustomScanState *css; - Relation scan_rel; + Index scan_relid = cscan->scan.scanrelid; /* populate a CustomScanState according to the CustomScan */ css = (CustomScanState *) cscan->methods->CreateCustomScanState(cscan); @@ -48,12 +48,26 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) ExecInitScanTupleSlot(estate, &css->ss); ExecInitResultTupleSlot(estate, &css->ss.ps); - /* initialize scan relation */ - scan_rel = ExecOpenScanRelation(estate, cscan->scan.scanrelid, eflags); - css->ss.ss_currentRelation = scan_rel; - css->ss.ss_currentScanDesc = NULL; /* set by provider */ - ExecAssignScanType(&css->ss, RelationGetDescr(scan_rel)); - + /* + * open the base relation and acquire an appropriate lock on it; + * also, get and assign the scan type + */ + if (scan_relid > 0) + { + Relation scan_rel; + + scan_rel = ExecOpenScanRelation(estate, scan_relid, eflags); + css->ss.ss_currentRelation = scan_rel; + css->ss.ss_currentScanDesc = NULL; /* set by provider */ + ExecAssignScanType(&css->ss, RelationGetDescr(scan_rel)); + } + else + { + TupleDesc ps_tupdesc; + + ps_tupdesc = ExecCleanTypeFromTL(cscan->custom_ps_tlist, false); + ExecAssignScanType(&css->ss, ps_tupdesc); + } css->ss.ps.ps_TupFromTlist = false; /* @@ -89,11 +103,11 @@ ExecEndCustomScan(CustomScanState *node) /* Clean out the tuple table */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); - if (node->ss.ss_ScanTupleSlot) - ExecClearTuple(node->ss.ss_ScanTupleSlot); + ExecClearTuple(node->ss.ss_ScanTupleSlot); /* Close the heap relation */ - ExecCloseScanRelation(node->ss.ss_currentRelation); + if (node->ss.ss_currentRelation) + ExecCloseScanRelation(node->ss.ss_currentRelation); } void diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index 7399053ae7d..fa553ace5d6 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -102,7 +102,7 @@ ForeignScanState * ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) { ForeignScanState *scanstate; - Relation currentRelation; + Index scanrelid = node->scan.scanrelid; FdwRoutine *fdwroutine; /* check for unsupported flags */ @@ -141,16 +141,24 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) ExecInitScanTupleSlot(estate, &scanstate->ss); /* - * open the base relation and acquire appropriate lock on it. + * open the base relation and acquire an appropriate lock on it; + * also, get and assign the scan type */ - currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); - scanstate->ss.ss_currentRelation = currentRelation; + if (scanrelid > 0) + { + Relation currentRelation; - /* - * get the scan type from the relation descriptor. (XXX at some point we - * might want to let the FDW editorialize on the scan tupdesc.) - */ - ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); + currentRelation = ExecOpenScanRelation(estate, scanrelid, eflags); + scanstate->ss.ss_currentRelation = currentRelation; + ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); + } + else + { + TupleDesc ps_tupdesc; + + ps_tupdesc = ExecCleanTypeFromTL(node->fdw_ps_tlist, false); + ExecAssignScanType(&scanstate->ss, ps_tupdesc); + } /* * Initialize result tuple type and projection info. @@ -161,7 +169,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) /* * Acquire function pointers from the FDW's handler, and init fdw_state. */ - fdwroutine = GetFdwRoutineForRelation(currentRelation, true); + fdwroutine = GetFdwRoutine(node->fdw_handler); scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; @@ -193,7 +201,8 @@ ExecEndForeignScan(ForeignScanState *node) ExecClearTuple(node->ss.ss_ScanTupleSlot); /* close the relation. */ - ExecCloseScanRelation(node->ss.ss_currentRelation); + if (node->ss.ss_currentRelation) + ExecCloseScanRelation(node->ss.ss_currentRelation); } /* ---------------------------------------------------------------- |