1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * skey.h |
4 | * POSTGRES scan key definitions. |
5 | * |
6 | * |
7 | * Portions Copyright (c) 1996-2019, 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 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 | |