1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * typcache.h |
4 | * Type cache definitions. |
5 | * |
6 | * The type cache exists to speed lookup of certain information about data |
7 | * types that is not directly available from a type's pg_type row. |
8 | * |
9 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
10 | * Portions Copyright (c) 1994, Regents of the University of California |
11 | * |
12 | * src/include/utils/typcache.h |
13 | * |
14 | *------------------------------------------------------------------------- |
15 | */ |
16 | #ifndef TYPCACHE_H |
17 | #define TYPCACHE_H |
18 | |
19 | #include "access/tupdesc.h" |
20 | #include "fmgr.h" |
21 | #include "storage/dsm.h" |
22 | #include "utils/dsa.h" |
23 | |
24 | |
25 | /* DomainConstraintCache is an opaque struct known only within typcache.c */ |
26 | typedef struct DomainConstraintCache DomainConstraintCache; |
27 | |
28 | /* TypeCacheEnumData is an opaque struct known only within typcache.c */ |
29 | struct TypeCacheEnumData; |
30 | |
31 | typedef struct TypeCacheEntry |
32 | { |
33 | /* typeId is the hash lookup key and MUST BE FIRST */ |
34 | Oid type_id; /* OID of the data type */ |
35 | |
36 | /* some subsidiary information copied from the pg_type row */ |
37 | int16 typlen; |
38 | bool typbyval; |
39 | char typalign; |
40 | char typstorage; |
41 | char typtype; |
42 | Oid typrelid; |
43 | Oid typelem; |
44 | Oid typcollation; |
45 | |
46 | /* |
47 | * Information obtained from opfamily entries |
48 | * |
49 | * These will be InvalidOid if no match could be found, or if the |
50 | * information hasn't yet been requested. Also note that for array and |
51 | * composite types, typcache.c checks that the contained types are |
52 | * comparable or hashable before allowing eq_opr etc to become set. |
53 | */ |
54 | Oid btree_opf; /* the default btree opclass' family */ |
55 | Oid btree_opintype; /* the default btree opclass' opcintype */ |
56 | Oid hash_opf; /* the default hash opclass' family */ |
57 | Oid hash_opintype; /* the default hash opclass' opcintype */ |
58 | Oid eq_opr; /* the equality operator */ |
59 | Oid lt_opr; /* the less-than operator */ |
60 | Oid gt_opr; /* the greater-than operator */ |
61 | Oid cmp_proc; /* the btree comparison function */ |
62 | Oid hash_proc; /* the hash calculation function */ |
63 | Oid hash_extended_proc; /* the extended hash calculation function */ |
64 | |
65 | /* |
66 | * Pre-set-up fmgr call info for the equality operator, the btree |
67 | * comparison function, and the hash calculation function. These are kept |
68 | * in the type cache to avoid problems with memory leaks in repeated calls |
69 | * to functions such as array_eq, array_cmp, hash_array. There is not |
70 | * currently a need to maintain call info for the lt_opr or gt_opr. |
71 | */ |
72 | FmgrInfo eq_opr_finfo; |
73 | FmgrInfo cmp_proc_finfo; |
74 | FmgrInfo hash_proc_finfo; |
75 | FmgrInfo hash_extended_proc_finfo; |
76 | |
77 | /* |
78 | * Tuple descriptor if it's a composite type (row type). NULL if not |
79 | * composite or information hasn't yet been requested. (NOTE: this is a |
80 | * reference-counted tupledesc.) |
81 | * |
82 | * To simplify caching dependent info, tupDesc_identifier is an identifier |
83 | * for this tupledesc that is unique for the life of the process, and |
84 | * changes anytime the tupledesc does. Zero if not yet determined. |
85 | */ |
86 | TupleDesc tupDesc; |
87 | uint64 tupDesc_identifier; |
88 | |
89 | /* |
90 | * Fields computed when TYPECACHE_RANGE_INFO is requested. Zeroes if not |
91 | * a range type or information hasn't yet been requested. Note that |
92 | * rng_cmp_proc_finfo could be different from the element type's default |
93 | * btree comparison function. |
94 | */ |
95 | struct TypeCacheEntry *rngelemtype; /* range's element type */ |
96 | Oid rng_collation; /* collation for comparisons, if any */ |
97 | FmgrInfo rng_cmp_proc_finfo; /* comparison function */ |
98 | FmgrInfo rng_canonical_finfo; /* canonicalization function, if any */ |
99 | FmgrInfo rng_subdiff_finfo; /* difference function, if any */ |
100 | |
101 | /* |
102 | * Domain's base type and typmod if it's a domain type. Zeroes if not |
103 | * domain, or if information hasn't been requested. |
104 | */ |
105 | Oid domainBaseType; |
106 | int32 domainBaseTypmod; |
107 | |
108 | /* |
109 | * Domain constraint data if it's a domain type. NULL if not domain, or |
110 | * if domain has no constraints, or if information hasn't been requested. |
111 | */ |
112 | DomainConstraintCache *domainData; |
113 | |
114 | /* Private data, for internal use of typcache.c only */ |
115 | int flags; /* flags about what we've computed */ |
116 | |
117 | /* |
118 | * Private information about an enum type. NULL if not enum or |
119 | * information hasn't been requested. |
120 | */ |
121 | struct TypeCacheEnumData *enumData; |
122 | |
123 | /* We also maintain a list of all known domain-type cache entries */ |
124 | struct TypeCacheEntry *nextDomain; |
125 | } TypeCacheEntry; |
126 | |
127 | /* Bit flags to indicate which fields a given caller needs to have set */ |
128 | #define TYPECACHE_EQ_OPR 0x0001 |
129 | #define TYPECACHE_LT_OPR 0x0002 |
130 | #define TYPECACHE_GT_OPR 0x0004 |
131 | #define TYPECACHE_CMP_PROC 0x0008 |
132 | #define TYPECACHE_HASH_PROC 0x0010 |
133 | #define TYPECACHE_EQ_OPR_FINFO 0x0020 |
134 | #define TYPECACHE_CMP_PROC_FINFO 0x0040 |
135 | #define TYPECACHE_HASH_PROC_FINFO 0x0080 |
136 | #define TYPECACHE_TUPDESC 0x0100 |
137 | #define TYPECACHE_BTREE_OPFAMILY 0x0200 |
138 | #define TYPECACHE_HASH_OPFAMILY 0x0400 |
139 | #define TYPECACHE_RANGE_INFO 0x0800 |
140 | #define TYPECACHE_DOMAIN_BASE_INFO 0x1000 |
141 | #define TYPECACHE_DOMAIN_CONSTR_INFO 0x2000 |
142 | #define TYPECACHE_HASH_EXTENDED_PROC 0x4000 |
143 | #define TYPECACHE_HASH_EXTENDED_PROC_FINFO 0x8000 |
144 | |
145 | /* This value will not equal any valid tupledesc identifier, nor 0 */ |
146 | #define INVALID_TUPLEDESC_IDENTIFIER ((uint64) 1) |
147 | |
148 | /* |
149 | * Callers wishing to maintain a long-lived reference to a domain's constraint |
150 | * set must store it in one of these. Use InitDomainConstraintRef() and |
151 | * UpdateDomainConstraintRef() to manage it. Note: DomainConstraintState is |
152 | * considered an executable expression type, so it's defined in execnodes.h. |
153 | */ |
154 | typedef struct DomainConstraintRef |
155 | { |
156 | List *constraints; /* list of DomainConstraintState nodes */ |
157 | MemoryContext refctx; /* context holding DomainConstraintRef */ |
158 | TypeCacheEntry *tcache; /* typcache entry for domain type */ |
159 | bool need_exprstate; /* does caller need check_exprstate? */ |
160 | |
161 | /* Management data --- treat these fields as private to typcache.c */ |
162 | DomainConstraintCache *dcc; /* current constraints, or NULL if none */ |
163 | MemoryContextCallback callback; /* used to release refcount when done */ |
164 | } DomainConstraintRef; |
165 | |
166 | typedef struct SharedRecordTypmodRegistry SharedRecordTypmodRegistry; |
167 | |
168 | extern TypeCacheEntry *lookup_type_cache(Oid type_id, int flags); |
169 | |
170 | extern void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref, |
171 | MemoryContext refctx, bool need_exprstate); |
172 | |
173 | extern void UpdateDomainConstraintRef(DomainConstraintRef *ref); |
174 | |
175 | extern bool DomainHasConstraints(Oid type_id); |
176 | |
177 | extern TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod); |
178 | |
179 | extern TupleDesc lookup_rowtype_tupdesc_noerror(Oid type_id, int32 typmod, |
180 | bool noError); |
181 | |
182 | extern TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod); |
183 | |
184 | extern TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, |
185 | bool noError); |
186 | |
187 | extern void assign_record_type_typmod(TupleDesc tupDesc); |
188 | |
189 | extern uint64 assign_record_type_identifier(Oid type_id, int32 typmod); |
190 | |
191 | extern int compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2); |
192 | |
193 | extern size_t SharedRecordTypmodRegistryEstimate(void); |
194 | |
195 | extern void SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *, |
196 | dsm_segment *segment, dsa_area *area); |
197 | |
198 | extern void SharedRecordTypmodRegistryAttach(SharedRecordTypmodRegistry *); |
199 | |
200 | #endif /* TYPCACHE_H */ |
201 | |