1 /*-------------------------------------------------------------------------
4 * Utilities for finding applicable merge clauses and pathkeys
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.17 1999/02/11 14:58:53 momjian Exp $
12 *-------------------------------------------------------------------------
16 #include "nodes/pg_list.h"
17 #include "nodes/relation.h"
19 #include "optimizer/internal.h"
20 #include "optimizer/paths.h"
21 #include "optimizer/clauses.h"
22 #include "optimizer/ordering.h"
25 * group-clauses-by-order--
26 * If a join clause node in 'restrictinfo-list' is mergejoinable, store
27 * it within a mergeinfo node containing other clause nodes with the same
30 * 'restrictinfo-list' is the list of restrictinfo nodes
31 * 'inner-relid' is the relid of the inner join relation
33 * Returns the new list of mergeinfo nodes.
37 group_clauses_by_order(List *restrictinfo_list,
40 List *mergeinfo_list = NIL;
41 List *xrestrictinfo = NIL;
43 foreach(xrestrictinfo, restrictinfo_list)
45 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(xrestrictinfo);
46 MergeOrder *merge_ordering = restrictinfo->mergejoinorder;
52 * Create a new mergeinfo node and add it to 'mergeinfo-list'
53 * if one does not yet exist for this merge ordering.
56 MergeInfo *xmergeinfo;
57 Expr *clause = restrictinfo->clause;
58 Var *leftop = get_leftop(clause);
59 Var *rightop = get_rightop(clause);
62 pathorder = makeNode(PathOrder);
63 pathorder->ordtype = MERGE_ORDER;
64 pathorder->ord.merge = merge_ordering;
65 xmergeinfo = match_order_mergeinfo(pathorder, mergeinfo_list);
66 if (inner_relid == leftop->varno)
68 jmkeys = makeNode(JoinKey);
69 jmkeys->outer = rightop;
70 jmkeys->inner = leftop;
74 jmkeys = makeNode(JoinKey);
75 jmkeys->outer = leftop;
76 jmkeys->inner = rightop;
79 if (xmergeinfo == NULL)
81 xmergeinfo = makeNode(MergeInfo);
83 xmergeinfo->m_ordering = merge_ordering;
84 mergeinfo_list = lcons(xmergeinfo,
88 ((JoinMethod *) xmergeinfo)->clauses = lcons(clause,
89 ((JoinMethod *) xmergeinfo)->clauses);
90 ((JoinMethod *) xmergeinfo)->jmkeys = lcons(jmkeys,
91 ((JoinMethod *) xmergeinfo)->jmkeys);
94 return mergeinfo_list;
99 * match-order-mergeinfo--
100 * Searches the list 'mergeinfo-list' for a mergeinfo node whose order
101 * field equals 'ordering'.
103 * Returns the node if it exists.
107 match_order_mergeinfo(PathOrder *ordering, List *mergeinfo_list)
109 MergeOrder *xmergeorder;
110 List *xmergeinfo = NIL;
112 foreach(xmergeinfo, mergeinfo_list)
114 MergeInfo *mergeinfo = (MergeInfo *) lfirst(xmergeinfo);
116 xmergeorder = mergeinfo->m_ordering;
118 if ((ordering->ordtype == MERGE_ORDER &&
119 equal_merge_ordering(ordering->ord.merge, xmergeorder)) ||
120 (ordering->ordtype == SORTOP_ORDER &&
121 equal_path_merge_ordering(ordering->ord.sortop, xmergeorder)))
127 return (MergeInfo *) NIL;