* create_append_path * Creates a path corresponding to an Append plan, returning the * pathnode. * * Note that we must handle subpaths = NIL, representing a dummy access path. * Also, there are callers that pass root = NULL. */
| 1392 | * Also, there are callers that pass root = NULL. |
| 1393 | */ |
| 1394 | AppendPath * |
| 1395 | create_append_path(PlannerInfo *root, |
| 1396 | RelOptInfo *rel, |
| 1397 | List *subpaths, List *partial_subpaths, |
| 1398 | List *pathkeys, Relids required_outer, |
| 1399 | int parallel_workers, bool parallel_aware, |
| 1400 | double rows) |
| 1401 | { |
| 1402 | AppendPath *pathnode = makeNode(AppendPath); |
| 1403 | ListCell *l; |
| 1404 | |
| 1405 | /* |
| 1406 | * CBDB_PARALLEL_FIXME: it still cannot be opened after we deal with append. |
| 1407 | * Because we currently allow path with non parallel_workers been added to |
| 1408 | * partial_path. |
| 1409 | */ |
| 1410 | #if 0 |
| 1411 | Assert(!parallel_aware || parallel_workers > 0); |
| 1412 | #endif |
| 1413 | |
| 1414 | |
| 1415 | pathnode->path.pathtype = T_Append; |
| 1416 | pathnode->path.parent = rel; |
| 1417 | pathnode->path.pathtarget = rel->reltarget; |
| 1418 | |
| 1419 | /* |
| 1420 | * When generating an Append path for a partitioned table, there may be |
| 1421 | * parameterized quals that are useful for run-time pruning. Hence, |
| 1422 | * compute path.param_info the same way as for any other baserel, so that |
| 1423 | * such quals will be available for make_partition_pruneinfo(). (This |
| 1424 | * would not work right for a non-baserel, ie a scan on a non-leaf child |
| 1425 | * partition, and it's not necessary anyway in that case. Must skip it if |
| 1426 | * we don't have "root", too.) |
| 1427 | */ |
| 1428 | if (root && rel->reloptkind == RELOPT_BASEREL && IS_PARTITIONED_REL(rel)) |
| 1429 | pathnode->path.param_info = get_baserel_parampathinfo(root, |
| 1430 | rel, |
| 1431 | required_outer); |
| 1432 | else |
| 1433 | pathnode->path.param_info = get_appendrel_parampathinfo(rel, |
| 1434 | required_outer); |
| 1435 | |
| 1436 | pathnode->path.parallel_aware = parallel_aware; |
| 1437 | pathnode->path.parallel_safe = rel->consider_parallel; |
| 1438 | pathnode->path.parallel_workers = parallel_workers; |
| 1439 | pathnode->path.pathkeys = pathkeys; |
| 1440 | |
| 1441 | pathnode->path.motionHazard = false; |
| 1442 | pathnode->path.barrierHazard = false; |
| 1443 | pathnode->path.rescannable = true; |
| 1444 | |
| 1445 | /* |
| 1446 | * For parallel append, non-partial paths are sorted by descending total |
| 1447 | * costs. That way, the total time to finish all non-partial paths is |
| 1448 | * minimized. Also, the partial paths are sorted by descending startup |
| 1449 | * costs. There may be some paths that require to do startup work by a |
| 1450 | * single worker. In such case, it's better for workers to choose the |
| 1451 | * expensive ones first, whereas the leader should choose the cheapest |
no test coverage detected