* ExecFindPartition -- Return the ResultRelInfo for the leaf partition that * the tuple contained in *slot should belong to. * * If the partition's ResultRelInfo does not yet exist in 'proute' then we set * one up or reuse one from mtstate's resultRelInfo array. When reusing a * ResultRelInfo from the mtstate we verify that the relation is a valid * target for INSERTs and initialize tuple r
| 263 | * is not a valid target for an INSERT. |
| 264 | */ |
| 265 | ResultRelInfo * |
| 266 | ExecFindPartition(ModifyTableState *mtstate, |
| 267 | ResultRelInfo *rootResultRelInfo, |
| 268 | PartitionTupleRouting *proute, |
| 269 | TupleTableSlot *slot, EState *estate) |
| 270 | { |
| 271 | PartitionDispatch *pd = proute->partition_dispatch_info; |
| 272 | Datum values[PARTITION_MAX_KEYS]; |
| 273 | bool isnull[PARTITION_MAX_KEYS]; |
| 274 | Relation rel; |
| 275 | PartitionDispatch dispatch; |
| 276 | PartitionDesc partdesc; |
| 277 | ExprContext *ecxt = GetPerTupleExprContext(estate); |
| 278 | TupleTableSlot *ecxt_scantuple_saved = ecxt->ecxt_scantuple; |
| 279 | TupleTableSlot *rootslot = slot; |
| 280 | TupleTableSlot *myslot = NULL; |
| 281 | MemoryContext oldcxt; |
| 282 | ResultRelInfo *rri = NULL; |
| 283 | |
| 284 | /* use per-tuple context here to avoid leaking memory */ |
| 285 | oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); |
| 286 | |
| 287 | /* |
| 288 | * First check the root table's partition constraint, if any. No point in |
| 289 | * routing the tuple if it doesn't belong in the root table itself. |
| 290 | */ |
| 291 | if (rootResultRelInfo->ri_RelationDesc->rd_rel->relispartition) |
| 292 | ExecPartitionCheck(rootResultRelInfo, slot, estate, true); |
| 293 | |
| 294 | /* start with the root partitioned table */ |
| 295 | dispatch = pd[0]; |
| 296 | while (dispatch != NULL) |
| 297 | { |
| 298 | int partidx = -1; |
| 299 | bool is_leaf; |
| 300 | |
| 301 | CHECK_FOR_INTERRUPTS(); |
| 302 | |
| 303 | rel = dispatch->reldesc; |
| 304 | partdesc = dispatch->partdesc; |
| 305 | |
| 306 | /* |
| 307 | * Extract partition key from tuple. Expression evaluation machinery |
| 308 | * that FormPartitionKeyDatum() invokes expects ecxt_scantuple to |
| 309 | * point to the correct tuple slot. The slot might have changed from |
| 310 | * what was used for the parent table if the table of the current |
| 311 | * partitioning level has different tuple descriptor from the parent. |
| 312 | * So update ecxt_scantuple accordingly. |
| 313 | */ |
| 314 | ecxt->ecxt_scantuple = slot; |
| 315 | /* |
| 316 | * If the operation is delete and its child is a dynamic scan, |
| 317 | * then we need to remap the the attributes from the tuple to the relation. |
| 318 | * This is because the tuple descriptor's columns do not exactly match |
| 319 | * the relation attributes in the catalog--the tuple has a subset of the attrs. |
| 320 | * FormPartitionKeyDatum uses this map to get the partition key index in |
| 321 | * the tuple descriptor, and the values at that index within the tuple. |
| 322 | */ |
no test coverage detected