aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/pathkeys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/pathkeys.c')
-rw-r--r--src/backend/optimizer/path/pathkeys.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 44a7b614b69..41a3ff35b48 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.14 1999/08/16 02:17:52 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.15 1999/08/21 03:49:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,6 +20,7 @@
#include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/parsetree.h"
+#include "parser/parse_func.h"
#include "utils/lsyscache.h"
static PathKeyItem *makePathKeyItem(Node *key, Oid sortop);
@@ -89,6 +90,11 @@ static List *build_join_pathkey(List *pathkeys, List *join_rel_tlist,
* executor might have to split the join into multiple batches. Therefore
* a Hashjoin is always given NIL pathkeys.
*
+ * Pathkeys are also useful to represent an ordering that we wish to achieve,
+ * since they are easily compared to the pathkeys of a potential candidate
+ * path. So, SortClause lists are turned into pathkeys lists for use inside
+ * the optimizer.
+ *
* -- bjm & tgl
*--------------------
*/
@@ -254,9 +260,11 @@ pathkeys_contained_in(List *keys1, List *keys2)
*
* 'paths' is a list of possible paths (either inner or outer)
* 'pathkeys' represents a required ordering
+ * if 'indexpaths_only' is true, only IndexPaths will be considered.
*/
Path *
-get_cheapest_path_for_pathkeys(List *paths, List *pathkeys)
+get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
+ bool indexpaths_only)
{
Path *matched_path = NULL;
List *i;
@@ -265,6 +273,9 @@ get_cheapest_path_for_pathkeys(List *paths, List *pathkeys)
{
Path *path = (Path *) lfirst(i);
+ if (indexpaths_only && ! IsA(path, IndexPath))
+ continue;
+
if (pathkeys_contained_in(pathkeys, path->pathkeys))
{
if (matched_path == NULL ||
@@ -314,7 +325,8 @@ build_index_pathkeys(Query *root, RelOptInfo *rel, RelOptInfo *index)
funcnode->funcisindex = false;
funcnode->funcsize = 0;
funcnode->func_fcache = NULL;
- funcnode->func_tlist = NIL;
+ /* we assume here that the function returns a base type... */
+ funcnode->func_tlist = setup_base_tlist(funcnode->functype);
funcnode->func_planlist = NIL;
while (*indexkeys != 0)
@@ -516,6 +528,70 @@ build_join_pathkey(List *pathkey,
return new_pathkey;
}
+/*
+ * commute_pathkeys
+ * Attempt to commute the operators in a set of pathkeys, producing
+ * pathkeys that describe the reverse sort order (DESC instead of ASC).
+ * Returns TRUE if successful (all the operators have commutators).
+ *
+ * CAUTION: given pathkeys are modified in place, even if not successful!!
+ * Usually, caller should have just built or copied the pathkeys list to
+ * ensure there are no unwanted side-effects.
+ */
+bool
+commute_pathkeys(List *pathkeys)
+{
+ List *i;
+
+ foreach(i, pathkeys)
+ {
+ List *pathkey = lfirst(i);
+ List *j;
+
+ foreach(j, pathkey)
+ {
+ PathKeyItem *key = lfirst(j);
+
+ key->sortop = get_commutator(key->sortop);
+ if (key->sortop == InvalidOid)
+ return false;
+ }
+ }
+ return true; /* successful */
+}
+
+/****************************************************************************
+ * PATHKEYS AND SORT CLAUSES
+ ****************************************************************************/
+
+/*
+ * make_pathkeys_for_sortclauses
+ * Generate a pathkeys list that represents the sort order specified
+ * by a list of SortClauses (GroupClauses will work too!)
+ *
+ * 'sortclauses' is a list of SortClause or GroupClause nodes
+ * 'tlist' is the targetlist to find the referenced tlist entries in
+ */
+List *
+make_pathkeys_for_sortclauses(List *sortclauses, List *tlist)
+{
+ List *pathkeys = NIL;
+ List *i;
+
+ foreach(i, sortclauses)
+ {
+ SortClause *sortcl = (SortClause *) lfirst(i);
+ Node *sortkey;
+ PathKeyItem *pathkey;
+
+ sortkey = get_sortgroupclause_expr(sortcl, tlist);
+ pathkey = makePathKeyItem(sortkey, sortcl->sortop);
+ /* pathkey becomes a one-element sublist */
+ pathkeys = lappend(pathkeys, lcons(pathkey, NIL));
+ }
+ return pathkeys;
+}
+
/****************************************************************************
* PATHKEYS AND MERGECLAUSES
****************************************************************************/