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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers