* add_partial_path * Like add_path, our goal here is to consider whether a path is worthy * of being kept around, but the considerations here are a bit different. * A partial path is one which can be executed in any number of workers in * parallel such that each worker will generate a subset of the path's * overall result. * * As in add_path, the partial_pathlist is kept sorted
| 843 | * referenced by partial BitmapHeapPaths. |
| 844 | */ |
| 845 | void |
| 846 | add_partial_path(RelOptInfo *parent_rel, Path *new_path) |
| 847 | { |
| 848 | bool accept_new = true; /* unless we find a superior old path */ |
| 849 | int insert_at = 0; /* where to insert new item */ |
| 850 | ListCell *p1; |
| 851 | |
| 852 | /* Check for query cancel. */ |
| 853 | CHECK_FOR_INTERRUPTS(); |
| 854 | |
| 855 | /* Path to be added must be parallel safe. */ |
| 856 | Assert(new_path->parallel_safe); |
| 857 | |
| 858 | /* Relation should be OK for parallelism, too. */ |
| 859 | Assert(parent_rel->consider_parallel); |
| 860 | |
| 861 | /* |
| 862 | * As in add_path, throw out any paths which are dominated by the new |
| 863 | * path, but throw out the new path if some existing path dominates it. |
| 864 | */ |
| 865 | foreach(p1, parent_rel->partial_pathlist) |
| 866 | { |
| 867 | Path *old_path = (Path *) lfirst(p1); |
| 868 | bool remove_old = false; /* unless new proves superior */ |
| 869 | PathKeysComparison keyscmp; |
| 870 | |
| 871 | /* Compare pathkeys. */ |
| 872 | keyscmp = compare_pathkeys(new_path->pathkeys, old_path->pathkeys); |
| 873 | |
| 874 | /* Unless pathkeys are incompatible, keep just one of the two paths. */ |
| 875 | if (keyscmp != PATHKEYS_DIFFERENT) |
| 876 | { |
| 877 | if (new_path->total_cost > old_path->total_cost * STD_FUZZ_FACTOR) |
| 878 | { |
| 879 | /* New path costs more; keep it only if pathkeys are better. */ |
| 880 | if (keyscmp != PATHKEYS_BETTER1) |
| 881 | accept_new = false; |
| 882 | } |
| 883 | else if (old_path->total_cost > new_path->total_cost |
| 884 | * STD_FUZZ_FACTOR) |
| 885 | { |
| 886 | /* Old path costs more; keep it only if pathkeys are better. */ |
| 887 | if (keyscmp != PATHKEYS_BETTER2) |
| 888 | remove_old = true; |
| 889 | } |
| 890 | else if (keyscmp == PATHKEYS_BETTER1) |
| 891 | { |
| 892 | /* Costs are about the same, new path has better pathkeys. */ |
| 893 | remove_old = true; |
| 894 | } |
| 895 | else if (keyscmp == PATHKEYS_BETTER2) |
| 896 | { |
| 897 | /* Costs are about the same, old path has better pathkeys. */ |
| 898 | accept_new = false; |
| 899 | } |
| 900 | else if (old_path->total_cost > new_path->total_cost * 1.0000000001) |
| 901 | { |
| 902 | /* Pathkeys are the same, and the old path costs more. */ |
no test coverage detected