@ -974,14 +974,20 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
}
else if ( index - > amcanorderbyop & & pathkeys_possibly_useful )
{
/* see if we can generate ordering operators for query_pathkeys */
/*
* See if we can generate ordering operators for query_pathkeys or at
* least some prefix thereof . Matching to just a prefix of the
* query_pathkeys will allow an incremental sort to be considered on
* the index ' s partially sorted results .
*/
match_pathkeys_to_index ( index , root - > query_pathkeys ,
& orderbyclauses ,
& orderbyclausecols ) ;
if ( orderbyclauses )
if ( list_length ( root - > query_pathkeys ) = = list_length ( orderbyclauses ) )
useful_pathkeys = root - > query_pathkeys ;
else
useful_pathkeys = NIL ;
useful_pathkeys = list_copy_head ( root - > query_pathkeys ,
list_length ( orderbyclauses ) ) ;
}
else
{
@ -3051,24 +3057,24 @@ expand_indexqual_rowcompare(PlannerInfo *root,
/*
* match_pathkeys_to_index
* Test whether an index can produce output ordered according to the
* given pathkeys using " ordering operators " .
*
* If it can , return a list of suitable ORDER BY expressions , each of the form
* " indexedcol operator pseudoconstant " , along with an integer list of the
* index column numbers ( zero based ) that each clause would be used with .
* NIL lists are returned if the ordering is not achievable this way .
*
* On success , the result list is ordered by pathkeys , and in fact is
* one - to - one with the requested pathkeys .
* For the given ' index ' and ' pathkeys ' , output a list of suitable ORDER
* BY expressions , each of the form " indexedcol operator pseudoconstant " ,
* along with an integer list of the index column numbers ( zero based )
* that each clause would be used with .
*
* This attempts to find an ORDER BY and index column number for all items in
* the pathkey list , however , if we ' re unable to match any given pathkey to an
* index column , we return just the ones matched by the function so far . This
* allows callers who are interested in partial matches to get them . Callers
* can determine a partial match vs a full match by checking the outputted
* list lengths . A full match will have one item in the output lists for each
* item in the given ' pathkeys ' list .
*/
static void
match_pathkeys_to_index ( IndexOptInfo * index , List * pathkeys ,
List * * orderby_clauses_p ,
List * * clause_columns_p )
{
List * orderby_clauses = NIL ;
List * clause_columns = NIL ;
ListCell * lc1 ;
* orderby_clauses_p = NIL ; /* set default results */
@ -3084,10 +3090,6 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
bool found = false ;
ListCell * lc2 ;
/*
* Note : for any failure to match , we just return NIL immediately .
* There is no value in matching just some of the pathkeys .
*/
/* Pathkey must request default sort order for the target opfamily */
if ( pathkey - > pk_strategy ! = BTLessStrategyNumber | |
@ -3133,8 +3135,8 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
pathkey - > pk_opfamily ) ;
if ( expr )
{
orderby_clauses = lappend ( orderby_clauses , expr ) ;
clause_columns = lappend_int ( clause_columns , indexcol ) ;
* orderby_clauses_p = lappend ( * orderby_clauses_p , expr ) ;
* clause_columns_p = lappend_int ( * clause_columns_p , indexcol ) ;
found = true ;
break ;
}
@ -3144,12 +3146,13 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
break ;
}
if ( ! found ) /* fail if no match for this pathkey */
/*
* Return the matches found so far when this pathkey couldn ' t be
* matched to the index .
*/
if ( ! found )
return ;
}
* orderby_clauses_p = orderby_clauses ; /* success! */
* clause_columns_p = clause_columns ;
}
/*