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