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.14 1999/02/08 04:29:12 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 path_order.ordtype = MERGE_ORDER;
63 path_order.ord.merge = merge_ordering;
64 xmergeinfo = match_order_mergeinfo(&path_order, mergeinfo_list);
65 if (inner_relid == leftop->varno)
67 keys = makeNode(JoinKey);
68 keys->outer = rightop;
73 keys = makeNode(JoinKey);
75 keys->inner = rightop;
78 if (xmergeinfo == NULL)
80 xmergeinfo = makeNode(MergeInfo);
82 xmergeinfo->m_ordering = merge_ordering;
83 mergeinfo_list = lcons(xmergeinfo,
87 ((JoinMethod *) xmergeinfo)->clauses = lcons(clause,
88 ((JoinMethod *) xmergeinfo)->clauses);
89 ((JoinMethod *) xmergeinfo)->jmkeys = lcons(keys,
90 ((JoinMethod *) xmergeinfo)->jmkeys);
93 return mergeinfo_list;
98 * match-order-mergeinfo--
99 * Searches the list 'mergeinfo-list' for a mergeinfo node whose order
100 * field equals 'ordering'.
102 * Returns the node if it exists.
106 match_order_mergeinfo(PathOrder *ordering, List *mergeinfo_list)
108 MergeOrder *xmergeorder;
109 List *xmergeinfo = NIL;
111 foreach(xmergeinfo, mergeinfo_list)
113 MergeInfo *mergeinfo = (MergeInfo *) lfirst(xmergeinfo);
115 xmergeorder = mergeinfo->m_ordering;
117 if ((ordering->ordtype == MERGE_ORDER &&
118 equal_merge_ordering(ordering->ord.merge, xmergeorder)) ||
119 (ordering->ordtype == SORTOP_ORDER &&
120 equal_path_merge_ordering(ordering->ord.sortop, xmergeorder)))
126 return (MergeInfo *) NIL;