To save cycles, I modified create_foreignscan_plan so that it detects
whether any system columns are requested if scanning a base relation.
Also, I revised other code there a little bit.
For ExecInitForeignScan, I simplified the code there to determine the
scan tuple type, whith seems to me complex beyound necessity. Maybe
that might be nitpicking, though.
Best regards,
Etsuro Fujita
*** a/src/backend/executor/nodeForeignscan.c
--- b/src/backend/executor/nodeForeignscan.c
***************
*** 159,182 **** ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
}
/*
! * Determine the scan tuple type. If the FDW provided a targetlist
! * describing the scan tuples, use that; else use base relation's rowtype.
*/
! if (node->fdw_scan_tlist != NIL || currentRelation == NULL)
{
TupleDesc scan_tupdesc;
scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false);
ExecAssignScanType(&scanstate->ss, scan_tupdesc);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */
tlistvarno = INDEX_VAR;
}
- else
- {
- ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation));
- /* Node's targetlist will contain Vars with varno = scanrelid */
- tlistvarno = scanrelid;
- }
/*
* Initialize result tuple type and projection info.
--- 159,183 ----
}
/*
! * Determine the scan tuple type.
*/
! if (scanrelid > 0)
! {
! /* Use base relation's rowtype */
! ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation));
! /* Node's targetlist will contain Vars with varno = scanrelid */
! tlistvarno = scanrelid;
! }
! else
{
TupleDesc scan_tupdesc;
+ /* Use targetlist provided by the FDW */
scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false);
ExecAssignScanType(&scanstate->ss, scan_tupdesc);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */
tlistvarno = INDEX_VAR;
}
/*
* Initialize result tuple type and projection info.
*** a/src/backend/optimizer/plan/createplan.c
--- b/src/backend/optimizer/plan/createplan.c
***************
*** 2050,2058 **** create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
RelOptInfo *rel = best_path->path.parent;
Index scan_relid = rel->relid;
Oid rel_oid = InvalidOid;
- Bitmapset *attrs_used = NULL;
- ListCell *lc;
- int i;
Assert(rel->fdwroutine != NULL);
--- 2050,2055 ----
***************
*** 2112,2147 **** create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
}
/*
! * Detect whether any system columns are requested from rel. This is a
! * bit of a kluge and might go away someday, so we intentionally leave it
! * out of the API presented to FDWs.
! *
! * First, examine all the attributes needed for joins or final output.
! * Note: we must look at reltargetlist, not the attr_needed data, because
! * attr_needed isn't computed for inheritance child rels.
*/
! pull_varattnos((Node *) rel->reltargetlist, rel->relid, &attrs_used);
!
! /* Add all the attributes used by restriction clauses. */
! foreach(lc, rel->baserestrictinfo)
{
! RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
! pull_varattnos((Node *) rinfo->clause, rel->relid, &attrs_used);
! }
! /* Now, are any system columns requested from rel? */
! scan_plan->fsSystemCol = false;
! for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
! {
! if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber, attrs_used))
{
! scan_plan->fsSystemCol = true;
! break;
}
- }
! bms_free(attrs_used);
return scan_plan;
}
--- 2109,2153 ----
}
/*
! * If we're scanning a base relation, detect whether any system columns
! * are requested from the rel. (Irrelevant if scanning a join relation.)
! * This is a bit of a kluge and might go away someday, so we intentionally
! * leave it out of the API presented to FDWs.
*/
! scan_plan->fsSystemCol = false;
! if (scan_relid > 0)
{
! Bitmapset *attrs_used = NULL;
! ListCell *lc;
! int i;
! /*
! * First, examine all the attributes needed for joins or final output.
! * Note: we must look at reltargetlist, not the attr_needed data,
! * because attr_needed isn't computed for inheritance child rels.
! */
! pull_varattnos((Node *) rel->reltargetlist, scan_relid, &attrs_used);
! /* Add all the attributes used by restriction clauses. */
! foreach(lc, rel->baserestrictinfo)
{
! RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
!
! pull_varattnos((Node *) rinfo->clause, scan_relid, &attrs_used);
}
! /* Now, are any system columns requested from rel? */
! for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
! {
! if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber, attrs_used))
! {
! scan_plan->fsSystemCol = true;
! break;
! }
! }
!
! bms_free(attrs_used);
! }
return scan_plan;
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers