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