@@ -974,14 +974,20 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
974
974
}
975
975
else if (index -> amcanorderbyop && pathkeys_possibly_useful )
976
976
{
977
- /* see if we can generate ordering operators for query_pathkeys */
977
+ /*
978
+ * See if we can generate ordering operators for query_pathkeys or at
979
+ * least some prefix thereof. Matching to just a prefix of the
980
+ * query_pathkeys will allow an incremental sort to be considered on
981
+ * the index's partially sorted results.
982
+ */
978
983
match_pathkeys_to_index (index , root -> query_pathkeys ,
979
984
& orderbyclauses ,
980
985
& orderbyclausecols );
981
- if (orderbyclauses )
986
+ if (list_length ( root -> query_pathkeys ) == list_length ( orderbyclauses ) )
982
987
useful_pathkeys = root -> query_pathkeys ;
983
988
else
984
- useful_pathkeys = NIL ;
989
+ useful_pathkeys = list_copy_head (root -> query_pathkeys ,
990
+ list_length (orderbyclauses ));
985
991
}
986
992
else
987
993
{
@@ -3051,24 +3057,24 @@ expand_indexqual_rowcompare(PlannerInfo *root,
3051
3057
3052
3058
/*
3053
3059
* match_pathkeys_to_index
3054
- * Test whether an index can produce output ordered according to the
3055
- * given pathkeys using "ordering operators".
3056
- *
3057
- * If it can, return a list of suitable ORDER BY expressions, each of the form
3058
- * "indexedcol operator pseudoconstant", along with an integer list of the
3059
- * index column numbers (zero based) that each clause would be used with.
3060
- * NIL lists are returned if the ordering is not achievable this way.
3061
- *
3062
- * On success, the result list is ordered by pathkeys, and in fact is
3063
- * one-to-one with the requested pathkeys.
3060
+ * For the given 'index' and 'pathkeys', output a list of suitable ORDER
3061
+ * BY expressions, each of the form "indexedcol operator pseudoconstant",
3062
+ * along with an integer list of the index column numbers (zero based)
3063
+ * that each clause would be used with.
3064
+ *
3065
+ * This attempts to find an ORDER BY and index column number for all items in
3066
+ * the pathkey list, however, if we're unable to match any given pathkey to an
3067
+ * index column, we return just the ones matched by the function so far. This
3068
+ * allows callers who are interested in partial matches to get them. Callers
3069
+ * can determine a partial match vs a full match by checking the outputted
3070
+ * list lengths. A full match will have one item in the output lists for each
3071
+ * item in the given 'pathkeys' list.
3064
3072
*/
3065
3073
static void
3066
3074
match_pathkeys_to_index (IndexOptInfo * index , List * pathkeys ,
3067
3075
List * * orderby_clauses_p ,
3068
3076
List * * clause_columns_p )
3069
3077
{
3070
- List * orderby_clauses = NIL ;
3071
- List * clause_columns = NIL ;
3072
3078
ListCell * lc1 ;
3073
3079
3074
3080
* orderby_clauses_p = NIL ; /* set default results */
@@ -3084,10 +3090,6 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
3084
3090
bool found = false;
3085
3091
ListCell * lc2 ;
3086
3092
3087
- /*
3088
- * Note: for any failure to match, we just return NIL immediately.
3089
- * There is no value in matching just some of the pathkeys.
3090
- */
3091
3093
3092
3094
/* Pathkey must request default sort order for the target opfamily */
3093
3095
if (pathkey -> pk_strategy != BTLessStrategyNumber ||
@@ -3133,8 +3135,8 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
3133
3135
pathkey -> pk_opfamily );
3134
3136
if (expr )
3135
3137
{
3136
- orderby_clauses = lappend (orderby_clauses , expr );
3137
- clause_columns = lappend_int (clause_columns , indexcol );
3138
+ * orderby_clauses_p = lappend (* orderby_clauses_p , expr );
3139
+ * clause_columns_p = lappend_int (* clause_columns_p , indexcol );
3138
3140
found = true;
3139
3141
break ;
3140
3142
}
@@ -3144,12 +3146,13 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
3144
3146
break ;
3145
3147
}
3146
3148
3147
- if (!found ) /* fail if no match for this pathkey */
3149
+ /*
3150
+ * Return the matches found so far when this pathkey couldn't be
3151
+ * matched to the index.
3152
+ */
3153
+ if (!found )
3148
3154
return ;
3149
3155
}
3150
-
3151
- * orderby_clauses_p = orderby_clauses ; /* success! */
3152
- * clause_columns_p = clause_columns ;
3153
3156
}
3154
3157
3155
3158
/*
0 commit comments