* Validates whether an index path descriptor * can be satisfied by the current index. */
| 832 | * can be satisfied by the current index. |
| 833 | */ |
| 834 | static bool |
| 835 | IsIndexIsValidForQuery(IndexPath *path) |
| 836 | { |
| 837 | if (IsA(path, IndexOnlyScan)) |
| 838 | { |
| 839 | /* We don't support index only scans in RUM */ |
| 840 | return false; |
| 841 | } |
| 842 | |
| 843 | if (path->indexorderbys != NIL && |
| 844 | !ValidateMatchForOrderbyQuals(path)) |
| 845 | { |
| 846 | /* Only return valid cost if the order by present |
| 847 | * matches the index fully |
| 848 | */ |
| 849 | return false; |
| 850 | } |
| 851 | |
| 852 | if (list_length(path->indexclauses) >= 1) |
| 853 | { |
| 854 | /* if there's at least one other index clause, |
| 855 | * then this index is already valid |
| 856 | */ |
| 857 | return true; |
| 858 | } |
| 859 | |
| 860 | if (path->indexinfo->indpred == NIL) |
| 861 | { |
| 862 | /* |
| 863 | * if the index is not a partial index, the useful_predicate |
| 864 | * clause does not apply. If there's no filter clauses, we |
| 865 | * can't really use this index (don't wanna do a full index scan) |
| 866 | */ |
| 867 | return false; |
| 868 | } |
| 869 | |
| 870 | if (path->indexinfo->indpred != NIL) |
| 871 | { |
| 872 | ListCell *cell; |
| 873 | foreach(cell, path->indexinfo->indpred) |
| 874 | { |
| 875 | Node *predQual = (Node *) lfirst(cell); |
| 876 | |
| 877 | /* walk the index predicates and check if they match the index */ |
| 878 | /* TODO: Do we need a query walk here */ |
| 879 | if (IsA(predQual, OpExpr)) |
| 880 | { |
| 881 | OpExpr *expr = (OpExpr *) predQual; |
| 882 | for (int32_t indexCol = 0; indexCol < path->indexinfo->nkeycolumns; |
| 883 | indexCol++) |
| 884 | { |
| 885 | if (MatchClauseWithIndexForFuncExpr(path, indexCol, expr->opfuncid, |
| 886 | expr->args)) |
| 887 | { |
| 888 | return true; |
| 889 | } |
| 890 | } |
| 891 | } |
no test coverage detected