MCPcopy Create free account
hub / github.com/apache/cloudberry / add_path_precheck

Function add_path_precheck

src/backend/optimizer/util/pathnode.c:740–804  ·  view source on GitHub ↗

* add_path_precheck * Check whether a proposed new path could possibly get accepted. * We assume we know the path's pathkeys and parameterization accurately, * and have lower bounds for its costs. * * Note that we do not know the path's rowcount, since getting an estimate for * that is too expensive to do before prechecking. We assume here that paths * of a superset parameterization

Source from the content-addressed store, hash-verified

738 * so the required information has to be passed piecemeal.
739 */
740bool
741add_path_precheck(RelOptInfo *parent_rel,
742 Cost startup_cost, Cost total_cost,
743 List *pathkeys, Relids required_outer)
744{
745 List *new_path_pathkeys;
746 bool consider_startup;
747 ListCell *p1;
748
749 /* Pretend parameterized paths have no pathkeys, per add_path policy */
750 new_path_pathkeys = required_outer ? NIL : pathkeys;
751
752 /* Decide whether new path's startup cost is interesting */
753 consider_startup = required_outer ? parent_rel->consider_param_startup : parent_rel->consider_startup;
754
755 foreach(p1, parent_rel->pathlist)
756 {
757 Path *old_path = (Path *) lfirst(p1);
758 PathKeysComparison keyscmp;
759
760 /*
761 * We are looking for an old_path with the same parameterization (and
762 * by assumption the same rowcount) that dominates the new path on
763 * pathkeys as well as both cost metrics. If we find one, we can
764 * reject the new path.
765 *
766 * Cost comparisons here should match compare_path_costs_fuzzily.
767 */
768 if (total_cost > old_path->total_cost * STD_FUZZ_FACTOR)
769 {
770 /* new path can win on startup cost only if consider_startup */
771 if (startup_cost > old_path->startup_cost * STD_FUZZ_FACTOR ||
772 !consider_startup)
773 {
774 /* new path loses on cost, so check pathkeys... */
775 List *old_path_pathkeys;
776
777 old_path_pathkeys = old_path->param_info ? NIL : old_path->pathkeys;
778 keyscmp = compare_pathkeys(new_path_pathkeys,
779 old_path_pathkeys);
780 if (keyscmp == PATHKEYS_EQUAL ||
781 keyscmp == PATHKEYS_BETTER2)
782 {
783 /* new path does not win on pathkeys... */
784 if (bms_equal(required_outer, PATH_REQ_OUTER(old_path)))
785 {
786 /* Found an old path that dominates the new one */
787 return false;
788 }
789 }
790 }
791 }
792 else
793 {
794 /*
795 * Since the pathlist is sorted by total_cost, we can stop looking
796 * once we reach a path with a total_cost larger than the new
797 * path's.

Callers 4

try_nestloop_pathFunction · 0.85
try_mergejoin_pathFunction · 0.85
try_hashjoin_pathFunction · 0.85

Calls 3

compare_pathkeysFunction · 0.85
bms_equalFunction · 0.85
foreachFunction · 0.50

Tested by

no test coverage detected