| 643 | |
| 644 | |
| 645 | void |
| 646 | extension_rumcostestimate_core(PlannerInfo *root, IndexPath *path, double loop_count, |
| 647 | Cost *indexStartupCost, Cost *indexTotalCost, |
| 648 | Selectivity *indexSelectivity, double *indexCorrelation, |
| 649 | double *indexPages, IndexAmRoutine *coreRoutine, |
| 650 | bool forceIndexPushdownCostToZero, bool |
| 651 | enableCompositePlannerCosts, |
| 652 | OrderedCostEstimateCoreFunc orderedCostEstimateCoreFunc) |
| 653 | { |
| 654 | if (!IsIndexIsValidForQuery(path)) |
| 655 | { |
| 656 | /* This index is not a match for the given query paths */ |
| 657 | /* In this code path, we set the total cost to infinity */ |
| 658 | /* As the planner walks through all other plans, one will be less */ |
| 659 | /* than infinity (the SeqScan) which will be picked in the worst case */ |
| 660 | *indexStartupCost = 0; |
| 661 | *indexTotalCost = INFINITY; |
| 662 | *indexSelectivity = 0; |
| 663 | *indexCorrelation = 0; |
| 664 | *indexPages = 0; |
| 665 | return; |
| 666 | } |
| 667 | |
| 668 | double totalNumTuples = 0; |
| 669 | Selectivity boundarySelectivity = 0; |
| 670 | int numBoundaryQuals = 0; |
| 671 | double dataPagesProportionFetched = 0; |
| 672 | bool convertedToIndexOnlyScan = false; |
| 673 | |
| 674 | bool isCompositeOpFamily = IsCompositeOpFamilyOid(path->indexinfo->relam, |
| 675 | path->indexinfo->opfamily[0]); |
| 676 | if (isCompositeOpFamily) |
| 677 | { |
| 678 | bool canSupportIndexOnlyScan = false; |
| 679 | bool firstColumnSpecified = TraverseIndexPathForCompositeIndex(path, root, |
| 680 | & |
| 681 | canSupportIndexOnlyScan); |
| 682 | |
| 683 | /* If this is a composite index, then we need to ensure that |
| 684 | * the first column of the index matches the query path. |
| 685 | * This is because using the composite index would require specifying |
| 686 | * the first column. |
| 687 | */ |
| 688 | if (!firstColumnSpecified) |
| 689 | { |
| 690 | *indexStartupCost = 0; |
| 691 | *indexTotalCost = INFINITY; |
| 692 | *indexSelectivity = 0; |
| 693 | *indexCorrelation = 0; |
| 694 | *indexPages = 0; |
| 695 | return; |
| 696 | } |
| 697 | |
| 698 | if (canSupportIndexOnlyScan && path->path.pathtype != T_IndexOnlyScan) |
| 699 | { |
| 700 | /* We copy the index opt info to a new allocated memory as we can't modify |
| 701 | * memory we don't own, we should let PG handle that memory. */ |
| 702 | IndexOptInfo *oldIndexInfo = path->indexinfo; |
no test coverage detected