| 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 | |