1 /*-------------------------------------------------------------------------
4 * strategy map data for GiSTs.
7 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/access/gist/Attic/giststrat.c,v 1.21 2003/08/04 02:39:57 momjian Exp $
13 *-------------------------------------------------------------------------
17 #include "access/gist.h"
18 #include "access/istrat.h"
22 * Note: negate, commute, and negatecommute all assume that operators are
23 * ordered as follows in the strategy map:
25 * contains, contained-by
27 * The negate, commute, and negatecommute arrays are used by the planner
28 * to plan indexed scans over data that appears in the qualificiation in
29 * a boolean negation, or whose operands appear in the wrong order. For
30 * example, if the operator "<%" means "contains", and the user says
32 * where not rel.box <% "(10,10,20,20)"::box
34 * the planner can plan an index scan by noting that GiST indices have
35 * an operator in their operator class for negating <%.
37 * Similarly, if the user says something like
39 * where "(10,10,20,20)"::box <% rel.box
41 * the planner can see that the GiST index on rel.box has an operator in
42 * its opclass for commuting <%, and plan the scan using that operator.
43 * This added complexity in the access methods makes the planner a lot easier
47 /* if a op b, what operator tells us if (not a op b)? */
48 static StrategyNumber GISTNegate[GISTNStrategies] = {
54 /* if a op_1 b, what is the operator op_2 such that b op_2 a? */
55 static StrategyNumber GISTCommute[GISTNStrategies] = {
61 /* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
62 static StrategyNumber GISTNegateCommute[GISTNStrategies] = {
69 * GiSTs do not currently support TermData (see rtree/rtstrat.c for
71 * TermData) -- such logic must be encoded in the user's Consistent function.
74 static StrategyExpression GISTEvaluationExpressions[GISTNStrategies] = {
81 * If you were sufficiently attentive to detail, you would go through
82 * the ExpressionData pain above for every one of the strategies
83 * we defined. I am not. Now we declare the StrategyEvaluationData
84 * structure that gets shipped around to help the planner and the access
85 * method decide what sort of scan it should do, based on (a) what the
86 * user asked for, (b) what operators are defined for a particular opclass,
87 * and (c) the reams of information we supplied above.
89 * The idea of all of this initialized data is to make life easier on the
90 * user when he defines a new operator class to use this access method.
91 * By filling in all the data, we let him get away with leaving holes in his
92 * operator class, and still let him use the index. The added complexity
93 * in the access methods just isn't worth the trouble, though.
96 static StrategyEvaluationData GISTEvaluationData = {
97 GISTNStrategies, /* # of strategies */
98 (StrategyTransformMap) GISTNegate, /* how to do (not qual) */
99 (StrategyTransformMap) GISTCommute, /* how to swap operands */
100 (StrategyTransformMap) GISTNegateCommute, /* how to do both */
101 GISTEvaluationExpressions
106 RelationGetGISTStrategy(Relation r,
110 return RelationGetStrategy(r, attnum, &GISTEvaluationData, proc);
115 RelationInvokeGISTStrategy(Relation r,
121 return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,