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-2021, 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 	uint32		type_id_hash;	/* hashed value of the OID */
37 
38 	/* some subsidiary information copied from the pg_type row */
39 	int16		typlen;
40 	bool		typbyval;
41 	char		typalign;
42 	char		typstorage;
43 	char		typtype;
44 	Oid			typrelid;
45 	Oid			typsubscript;
46 	Oid			typelem;
47 	Oid			typcollation;
48 
49 	/*
50 	 * Information obtained from opfamily entries
51 	 *
52 	 * These will be InvalidOid if no match could be found, or if the
53 	 * information hasn't yet been requested.  Also note that for array and
54 	 * composite types, typcache.c checks that the contained types are
55 	 * comparable or hashable before allowing eq_opr etc to become set.
56 	 */
57 	Oid			btree_opf;		/* the default btree opclass' family */
58 	Oid			btree_opintype; /* the default btree opclass' opcintype */
59 	Oid			hash_opf;		/* the default hash opclass' family */
60 	Oid			hash_opintype;	/* the default hash opclass' opcintype */
61 	Oid			eq_opr;			/* the equality operator */
62 	Oid			lt_opr;			/* the less-than operator */
63 	Oid			gt_opr;			/* the greater-than operator */
64 	Oid			cmp_proc;		/* the btree comparison function */
65 	Oid			hash_proc;		/* the hash calculation function */
66 	Oid			hash_extended_proc; /* the extended hash calculation function */
67 
68 	/*
69 	 * Pre-set-up fmgr call info for the equality operator, the btree
70 	 * comparison function, and the hash calculation function.  These are kept
71 	 * in the type cache to avoid problems with memory leaks in repeated calls
72 	 * to functions such as array_eq, array_cmp, hash_array.  There is not
73 	 * currently a need to maintain call info for the lt_opr or gt_opr.
74 	 */
75 	FmgrInfo	eq_opr_finfo;
76 	FmgrInfo	cmp_proc_finfo;
77 	FmgrInfo	hash_proc_finfo;
78 	FmgrInfo	hash_extended_proc_finfo;
79 
80 	/*
81 	 * Tuple descriptor if it's a composite type (row type).  NULL if not
82 	 * composite or information hasn't yet been requested.  (NOTE: this is a
83 	 * reference-counted tupledesc.)
84 	 *
85 	 * To simplify caching dependent info, tupDesc_identifier is an identifier
86 	 * for this tupledesc that is unique for the life of the process, and
87 	 * changes anytime the tupledesc does.  Zero if not yet determined.
88 	 */
89 	TupleDesc	tupDesc;
90 	uint64		tupDesc_identifier;
91 
92 	/*
93 	 * Fields computed when TYPECACHE_RANGE_INFO is requested.  Zeroes if not
94 	 * a range type or information hasn't yet been requested.  Note that
95 	 * rng_cmp_proc_finfo could be different from the element type's default
96 	 * btree comparison function.
97 	 */
98 	struct TypeCacheEntry *rngelemtype; /* range's element type */
99 	Oid			rng_collation;	/* collation for comparisons, if any */
100 	FmgrInfo	rng_cmp_proc_finfo; /* comparison function */
101 	FmgrInfo	rng_canonical_finfo;	/* canonicalization function, if any */
102 	FmgrInfo	rng_subdiff_finfo;	/* difference function, if any */
103 
104 	/*
105 	 * Fields computed when TYPECACHE_MULTIRANGE_INFO is required.
106 	 */
107 	struct TypeCacheEntry *rngtype; /* multirange's range underlying type */
108 
109 	/*
110 	 * Domain's base type and typmod if it's a domain type.  Zeroes if not
111 	 * domain, or if information hasn't been requested.
112 	 */
113 	Oid			domainBaseType;
114 	int32		domainBaseTypmod;
115 
116 	/*
117 	 * Domain constraint data if it's a domain type.  NULL if not domain, or
118 	 * if domain has no constraints, or if information hasn't been requested.
119 	 */
120 	DomainConstraintCache *domainData;
121 
122 	/* Private data, for internal use of typcache.c only */
123 	int			flags;			/* flags about what we've computed */
124 
125 	/*
126 	 * Private information about an enum type.  NULL if not enum or
127 	 * information hasn't been requested.
128 	 */
129 	struct TypeCacheEnumData *enumData;
130 
131 	/* We also maintain a list of all known domain-type cache entries */
132 	struct TypeCacheEntry *nextDomain;
133 } TypeCacheEntry;
134 
135 /* Bit flags to indicate which fields a given caller needs to have set */
136 #define TYPECACHE_EQ_OPR			0x00001
137 #define TYPECACHE_LT_OPR			0x00002
138 #define TYPECACHE_GT_OPR			0x00004
139 #define TYPECACHE_CMP_PROC			0x00008
140 #define TYPECACHE_HASH_PROC			0x00010
141 #define TYPECACHE_EQ_OPR_FINFO		0x00020
142 #define TYPECACHE_CMP_PROC_FINFO	0x00040
143 #define TYPECACHE_HASH_PROC_FINFO	0x00080
144 #define TYPECACHE_TUPDESC			0x00100
145 #define TYPECACHE_BTREE_OPFAMILY	0x00200
146 #define TYPECACHE_HASH_OPFAMILY		0x00400
147 #define TYPECACHE_RANGE_INFO		0x00800
148 #define TYPECACHE_DOMAIN_BASE_INFO			0x01000
149 #define TYPECACHE_DOMAIN_CONSTR_INFO		0x02000
150 #define TYPECACHE_HASH_EXTENDED_PROC		0x04000
151 #define TYPECACHE_HASH_EXTENDED_PROC_FINFO	0x08000
152 #define TYPECACHE_MULTIRANGE_INFO			0x10000
153 
154 /* This value will not equal any valid tupledesc identifier, nor 0 */
155 #define INVALID_TUPLEDESC_IDENTIFIER ((uint64) 1)
156 
157 /*
158  * Callers wishing to maintain a long-lived reference to a domain's constraint
159  * set must store it in one of these.  Use InitDomainConstraintRef() and
160  * UpdateDomainConstraintRef() to manage it.  Note: DomainConstraintState is
161  * considered an executable expression type, so it's defined in execnodes.h.
162  */
163 typedef struct DomainConstraintRef
164 {
165 	List	   *constraints;	/* list of DomainConstraintState nodes */
166 	MemoryContext refctx;		/* context holding DomainConstraintRef */
167 	TypeCacheEntry *tcache;		/* typcache entry for domain type */
168 	bool		need_exprstate; /* does caller need check_exprstate? */
169 
170 	/* Management data --- treat these fields as private to typcache.c */
171 	DomainConstraintCache *dcc; /* current constraints, or NULL if none */
172 	MemoryContextCallback callback; /* used to release refcount when done */
173 } DomainConstraintRef;
174 
175 typedef struct SharedRecordTypmodRegistry SharedRecordTypmodRegistry;
176 
177 extern TypeCacheEntry *lookup_type_cache(Oid type_id, int flags);
178 
179 extern void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref,
180 									MemoryContext refctx, bool need_exprstate);
181 
182 extern void UpdateDomainConstraintRef(DomainConstraintRef *ref);
183 
184 extern bool DomainHasConstraints(Oid type_id);
185 
186 extern TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod);
187 
188 extern TupleDesc lookup_rowtype_tupdesc_noerror(Oid type_id, int32 typmod,
189 												bool noError);
190 
191 extern TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod);
192 
193 extern TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod,
194 											   bool noError);
195 
196 extern void assign_record_type_typmod(TupleDesc tupDesc);
197 
198 extern uint64 assign_record_type_identifier(Oid type_id, int32 typmod);
199 
200 extern int	compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2);
201 
202 extern size_t SharedRecordTypmodRegistryEstimate(void);
203 
204 extern void SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *,
205 										   dsm_segment *segment, dsa_area *area);
206 
207 extern void SharedRecordTypmodRegistryAttach(SharedRecordTypmodRegistry *);
208 
209 #endif							/* TYPCACHE_H */
210