* reparameterize_path_by_child * Given a path parameterized by the parent of the given child relation, * translate the path to be parameterized by the given child relation. * * The function creates a new path of the same type as the given path, but * parameterized by the given child relation. Most fields from the original * path can simply be flat-copied, but any expressions must be adj
| 6327 | * If the given path can not be reparameterized, the function returns NULL. |
| 6328 | */ |
| 6329 | Path * |
| 6330 | reparameterize_path_by_child(PlannerInfo *root, Path *path, |
| 6331 | RelOptInfo *child_rel) |
| 6332 | { |
| 6333 | |
| 6334 | #define FLAT_COPY_PATH(newnode, node, nodetype) \ |
| 6335 | ( (newnode) = makeNode(nodetype), \ |
| 6336 | memcpy((newnode), (node), sizeof(nodetype)) ) |
| 6337 | |
| 6338 | #define ADJUST_CHILD_ATTRS(node) \ |
| 6339 | ((node) = \ |
| 6340 | (List *) adjust_appendrel_attrs_multilevel(root, (Node *) (node), \ |
| 6341 | child_rel->relids, \ |
| 6342 | child_rel->top_parent_relids)) |
| 6343 | |
| 6344 | #define REPARAMETERIZE_CHILD_PATH(path) \ |
| 6345 | do { \ |
| 6346 | (path) = reparameterize_path_by_child(root, (path), child_rel); \ |
| 6347 | if ((path) == NULL) \ |
| 6348 | return NULL; \ |
| 6349 | } while(0) |
| 6350 | |
| 6351 | #define REPARAMETERIZE_CHILD_PATH_LIST(pathlist) \ |
| 6352 | do { \ |
| 6353 | if ((pathlist) != NIL) \ |
| 6354 | { \ |
| 6355 | (pathlist) = reparameterize_pathlist_by_child(root, (pathlist), \ |
| 6356 | child_rel); \ |
| 6357 | if ((pathlist) == NIL) \ |
| 6358 | return NULL; \ |
| 6359 | } \ |
| 6360 | } while(0) |
| 6361 | |
| 6362 | Path *new_path; |
| 6363 | ParamPathInfo *new_ppi; |
| 6364 | ParamPathInfo *old_ppi; |
| 6365 | Relids required_outer; |
| 6366 | |
| 6367 | /* |
| 6368 | * If the path is not parameterized by parent of the given relation, it |
| 6369 | * doesn't need reparameterization. |
| 6370 | */ |
| 6371 | if (!path->param_info || |
| 6372 | !bms_overlap(PATH_REQ_OUTER(path), child_rel->top_parent_relids)) |
| 6373 | return path; |
| 6374 | |
| 6375 | /* |
| 6376 | * If possible, reparameterize the given path, making a copy. |
| 6377 | * |
| 6378 | * This function is currently only applied to the inner side of a nestloop |
| 6379 | * join that is being partitioned by the partitionwise-join code. Hence, |
| 6380 | * we need only support path types that plausibly arise in that context. |
| 6381 | * (In particular, supporting sorted path types would be a waste of code |
| 6382 | * and cycles: even if we translated them here, they'd just lose in |
| 6383 | * subsequent cost comparisons.) If we do see an unsupported path type, |
| 6384 | * that just means we won't be able to generate a partitionwise-join plan |
| 6385 | * using that path type. |
| 6386 | */ |
no test coverage detected