* initNextTableToScan * Find the next table to scan and initiate the scan if the previous table * is finished. * * If scanning on the current table is not finished, or a new table is found, * this function returns true. * If no more tables are found, this function returns false. */
| 123 | * If no more tables are found, this function returns false. |
| 124 | */ |
| 125 | static bool |
| 126 | initNextTableToScan(DynamicForeignScanState *node) |
| 127 | { |
| 128 | ScanState *scanState = (ScanState *) node; |
| 129 | DynamicForeignScan *plan = (DynamicForeignScan *) scanState->ps.plan; |
| 130 | EState *estate = scanState->ps.state; |
| 131 | Relation lastScannedRel; |
| 132 | TupleDesc partTupDesc; |
| 133 | TupleDesc lastTupDesc; |
| 134 | AttrMap *attMap; |
| 135 | Oid *pid; |
| 136 | Relation currentRelation; |
| 137 | |
| 138 | if (++node->whichPart < node->nOids) |
| 139 | pid = &node->partOids[node->whichPart]; |
| 140 | else |
| 141 | return false; |
| 142 | |
| 143 | /* Collect number of partitions scanned in EXPLAIN ANALYZE */ |
| 144 | if (NULL != scanState->ps.instrument) |
| 145 | { |
| 146 | Instrumentation *instr = scanState->ps.instrument; |
| 147 | instr->numPartScanned++; |
| 148 | } |
| 149 | |
| 150 | currentRelation = scanState->ss_currentRelation = |
| 151 | table_open(node->partOids[node->whichPart], AccessShareLock); |
| 152 | |
| 153 | if (currentRelation->rd_rel->relkind != RELKIND_FOREIGN_TABLE) |
| 154 | { |
| 155 | /* shouldn't happen */ |
| 156 | elog(ERROR, "unexpected relkind in Dynamic Foreign Scan: %c", currentRelation->rd_rel->relkind); |
| 157 | } |
| 158 | lastScannedRel = table_open(node->lastRelOid, AccessShareLock); |
| 159 | lastTupDesc = RelationGetDescr(lastScannedRel); |
| 160 | partTupDesc = RelationGetDescr(scanState->ss_currentRelation); |
| 161 | /* |
| 162 | * FIXME: should we use execute_attr_map_tuple instead? Seems like a |
| 163 | * higher level abstraction that fits the bill |
| 164 | */ |
| 165 | attMap = build_attrmap_by_name_if_req(partTupDesc, lastTupDesc); |
| 166 | table_close(lastScannedRel, AccessShareLock); |
| 167 | |
| 168 | /* If attribute remapping is not necessary, then do not change the varattno */ |
| 169 | if (attMap) |
| 170 | { |
| 171 | change_varattnos_of_a_varno((Node*)scanState->ps.plan->qual, attMap->attnums, node->scanrelid); |
| 172 | change_varattnos_of_a_varno((Node*)scanState->ps.plan->targetlist, attMap->attnums, node->scanrelid); |
| 173 | |
| 174 | /* |
| 175 | * Now that the varattno mapping has been changed, change the relation that |
| 176 | * the new varnos correspond to |
| 177 | */ |
| 178 | node->lastRelOid = *pid; |
| 179 | free_attrmap(attMap); |
| 180 | } |
| 181 | |
| 182 | RangeTblEntry *rte = exec_rt_fetch(node->scanrelid, estate); |
no test coverage detected