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 */
64typedef 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
75typedef 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 */
129extern void ScanKeyInit(ScanKey entry,
130 AttrNumber attributeNumber,
131 StrategyNumber strategy,
132 RegProcedure procedure,
133 Datum argument);
134extern 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);
142extern 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