1 /*-------------------------------------------------------------------------
2  *
3  * skey.h
4  *	  POSTGRES scan key definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/access/skey.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef SKEY_H
15 #define SKEY_H
16 
17 #include "access/attnum.h"
18 #include "access/stratnum.h"
19 #include "fmgr.h"
20 
21 
22 /*
23  * A ScanKey represents the application of a comparison operator between
24  * a table or index column and a constant.  When it's part of an array of
25  * ScanKeys, the comparison conditions are implicitly ANDed.  The index
26  * column is the left argument of the operator, if it's a binary operator.
27  * (The data structure can support unary indexable operators too; in that
28  * case sk_argument would go unused.  This is not currently implemented.)
29  *
30  * For an index scan, sk_strategy and sk_subtype must be set correctly for
31  * the operator.  When using a ScanKey in a heap scan, these fields are not
32  * used and may be set to InvalidStrategy/InvalidOid.
33  *
34  * If the operator is collation-sensitive, sk_collation must be set
35  * correctly as well.
36  *
37  * A ScanKey can also represent a ScalarArrayOpExpr, that is a condition
38  * "column op ANY(ARRAY[...])".  This is signaled by the SK_SEARCHARRAY
39  * flag bit.  The sk_argument is not a value of the operator's right-hand
40  * argument type, but rather an array of such values, and the per-element
41  * comparisons are to be ORed together.
42  *
43  * A ScanKey can also represent a condition "column IS NULL" or "column
44  * IS NOT NULL"; these cases are signaled by the SK_SEARCHNULL and
45  * SK_SEARCHNOTNULL flag bits respectively.  The argument is always NULL,
46  * and the sk_strategy, sk_subtype, sk_collation, and sk_func fields are
47  * not used (unless set by the index AM).
48  *
49  * SK_SEARCHARRAY, SK_SEARCHNULL and SK_SEARCHNOTNULL are supported only
50  * for index scans, not heap scans; and not all index AMs support them,
51  * only those that set amsearcharray or amsearchnulls respectively.
52  *
53  * A ScanKey can also represent an ordering operator invocation, that is
54  * an ordering requirement "ORDER BY indexedcol op constant".  This looks
55  * the same as a comparison operator, except that the operator doesn't
56  * (usually) yield boolean.  We mark such ScanKeys with SK_ORDER_BY.
57  * SK_SEARCHARRAY, SK_SEARCHNULL, SK_SEARCHNOTNULL cannot be used here.
58  *
59  * Note: in some places, ScanKeys are used as a convenient representation
60  * for the invocation of an access method support procedure.  In this case
61  * sk_strategy/sk_subtype are not meaningful (but sk_collation can be); and
62  * sk_func may refer to a function that returns something other than boolean.
63  */
64 typedef struct ScanKeyData
65 {
66 	int			sk_flags;		/* flags, see below */
67 	AttrNumber	sk_attno;		/* table or index column number */
68 	StrategyNumber sk_strategy; /* operator strategy number */
69 	Oid			sk_subtype;		/* strategy subtype */
70 	Oid			sk_collation;	/* collation to use, if needed */
71 	FmgrInfo	sk_func;		/* lookup info for function to call */
72 	Datum		sk_argument;	/* data to compare */
73 } ScanKeyData;
74 
75 typedef ScanKeyData *ScanKey;
76 
77 /*
78  * About row comparisons:
79  *
80  * The ScanKey data structure also supports row comparisons, that is ordered
81  * tuple comparisons like (x, y) > (c1, c2), having the SQL-spec semantics
82  * "x > c1 OR (x = c1 AND y > c2)".  Note that this is currently only
83  * implemented for btree index searches, not for heapscans or any other index
84  * type.  A row comparison is represented by a "header" ScanKey entry plus
85  * a separate array of ScanKeys, one for each column of the row comparison.
86  * The header entry has these properties:
87  *		sk_flags = SK_ROW_HEADER
88  *		sk_attno = index column number for leading column of row comparison
89  *		sk_strategy = btree strategy code for semantics of row comparison
90  *				(ie, < <= > or >=)
91  *		sk_subtype, sk_collation, sk_func: not used
92  *		sk_argument: pointer to subsidiary ScanKey array
93  * If the header is part of a ScanKey array that's sorted by attno, it
94  * must be sorted according to the leading column number.
95  *
96  * The subsidiary ScanKey array appears in logical column order of the row
97  * comparison, which may be different from index column order.  The array
98  * elements are like a normal ScanKey array except that:
99  *		sk_flags must include SK_ROW_MEMBER, plus SK_ROW_END in the last
100  *				element (needed since row header does not include a count)
101  *		sk_func points to the btree comparison support function for the
102  *				opclass, NOT the operator's implementation function.
103  * sk_strategy must be the same in all elements of the subsidiary array,
104  * that is, the same as in the header entry.
105  * SK_SEARCHARRAY, SK_SEARCHNULL, SK_SEARCHNOTNULL cannot be used here.
106  */
107 
108 /*
109  * ScanKeyData sk_flags
110  *
111  * sk_flags bits 0-15 are reserved for system-wide use (symbols for those
112  * bits should be defined here).  Bits 16-31 are reserved for use within
113  * individual index access methods.
114  */
115 #define SK_ISNULL			0x0001	/* sk_argument is NULL */
116 #define SK_UNARY			0x0002	/* unary operator (not supported!) */
117 #define SK_ROW_HEADER		0x0004	/* row comparison header (see above) */
118 #define SK_ROW_MEMBER		0x0008	/* row comparison member (see above) */
119 #define SK_ROW_END			0x0010	/* last row comparison member */
120 #define SK_SEARCHARRAY		0x0020	/* scankey represents ScalarArrayOp */
121 #define SK_SEARCHNULL		0x0040	/* scankey represents "col IS NULL" */
122 #define SK_SEARCHNOTNULL	0x0080	/* scankey represents "col IS NOT NULL" */
123 #define SK_ORDER_BY			0x0100	/* scankey is for ORDER BY op */
124 
125 
126 /*
127  * prototypes for functions in access/common/scankey.c
128  */
129 extern void ScanKeyInit(ScanKey entry,
130 			AttrNumber attributeNumber,
131 			StrategyNumber strategy,
132 			RegProcedure procedure,
133 			Datum argument);
134 extern void ScanKeyEntryInitialize(ScanKey entry,
135 					   int flags,
136 					   AttrNumber attributeNumber,
137 					   StrategyNumber strategy,
138 					   Oid subtype,
139 					   Oid collation,
140 					   RegProcedure procedure,
141 					   Datum argument);
142 extern void ScanKeyEntryInitializeWithInfo(ScanKey entry,
143 							   int flags,
144 							   AttrNumber attributeNumber,
145 							   StrategyNumber strategy,
146 							   Oid subtype,
147 							   Oid collation,
148 							   FmgrInfo *finfo,
149 							   Datum argument);
150 
151 #endif							/* SKEY_H */
152