1
/*-------------------------------------------------------------------------
4
* Convenience routines for common queries in the system catalog cache.
6
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
10
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.119 2004-12-31 22:01:25 pgsql Exp $
13
* Eventually, the index information should go through here, too.
14
*-------------------------------------------------------------------------
17
#include "miscadmin.h"
19
#include "access/hash.h"
20
#include "access/tupmacs.h"
21
#include "catalog/pg_amop.h"
22
#include "catalog/pg_amproc.h"
23
#include "catalog/pg_namespace.h"
24
#include "catalog/pg_opclass.h"
25
#include "catalog/pg_operator.h"
26
#include "catalog/pg_proc.h"
27
#include "catalog/pg_shadow.h"
28
#include "catalog/pg_statistic.h"
29
#include "catalog/pg_type.h"
30
#include "nodes/makefuncs.h"
31
#include "utils/array.h"
32
#include "utils/builtins.h"
33
#include "utils/catcache.h"
34
#include "utils/datum.h"
35
#include "utils/lsyscache.h"
36
#include "utils/syscache.h"
39
/* ---------- AMOP CACHES ---------- */
44
* Return t iff operator 'opno' is in operator class 'opclass'.
47
op_in_opclass(Oid opno, Oid opclass)
49
return SearchSysCacheExists(AMOPOPID,
50
ObjectIdGetDatum(opno),
51
ObjectIdGetDatum(opclass),
56
* get_op_opclass_properties
58
* Get the operator's strategy number, subtype, and recheck (lossy) flag
59
* within the specified opclass.
61
* Caller should already have verified that opno is a member of opclass,
62
* therefore we raise an error if the tuple is not found.
65
get_op_opclass_properties(Oid opno, Oid opclass,
66
int *strategy, Oid *subtype, bool *recheck)
69
Form_pg_amop amop_tup;
71
tp = SearchSysCache(AMOPOPID,
72
ObjectIdGetDatum(opno),
73
ObjectIdGetDatum(opclass),
75
if (!HeapTupleIsValid(tp))
76
elog(ERROR, "operator %u is not a member of opclass %u",
78
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
79
*strategy = amop_tup->amopstrategy;
80
*subtype = amop_tup->amopsubtype;
81
*recheck = amop_tup->amopreqcheck;
87
* Get the OID of the operator that implements the specified strategy
88
* with the specified subtype for the specified opclass.
90
* Returns InvalidOid if there is no pg_amop entry for the given keys.
93
get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
96
Form_pg_amop amop_tup;
99
tp = SearchSysCache(AMOPSTRATEGY,
100
ObjectIdGetDatum(opclass),
101
ObjectIdGetDatum(subtype),
102
Int16GetDatum(strategy),
104
if (!HeapTupleIsValid(tp))
106
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
107
result = amop_tup->amopopr;
113
* get_op_hash_function
114
* Get the OID of the datatype-specific hash function associated with
115
* a hashable equality operator.
117
* Returns InvalidOid if no hash function can be found. (This indicates
118
* that the operator should not have been marked oprcanhash.)
121
get_op_hash_function(Oid opno)
125
Oid opclass = InvalidOid;
128
* Search pg_amop to see if the target operator is registered as the
129
* "=" operator of any hash opclass. If the operator is registered in
130
* multiple opclasses, assume we can use the associated hash function
133
catlist = SearchSysCacheList(AMOPOPID, 1,
134
ObjectIdGetDatum(opno),
137
for (i = 0; i < catlist->n_members; i++)
139
HeapTuple tuple = &catlist->members[i]->tuple;
140
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
142
if (aform->amopstrategy == HTEqualStrategyNumber &&
143
opclass_is_hash(aform->amopclaid))
145
opclass = aform->amopclaid;
150
ReleaseSysCacheList(catlist);
152
if (OidIsValid(opclass))
154
/* Found a suitable opclass, get its default hash support function */
155
return get_opclass_proc(opclass, InvalidOid, HASHPROC);
158
/* Didn't find a match... */
163
/* ---------- AMPROC CACHES ---------- */
167
* Get the OID of the specified support function
168
* for the specified opclass and subtype.
170
* Returns InvalidOid if there is no pg_amproc entry for the given keys.
173
get_opclass_proc(Oid opclass, Oid subtype, int16 procnum)
176
Form_pg_amproc amproc_tup;
179
tp = SearchSysCache(AMPROCNUM,
180
ObjectIdGetDatum(opclass),
181
ObjectIdGetDatum(subtype),
182
Int16GetDatum(procnum),
184
if (!HeapTupleIsValid(tp))
186
amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
187
result = amproc_tup->amproc;
193
/* ---------- ATTRIBUTE CACHES ---------- */
197
* Given the relation id and the attribute number,
198
* return the "attname" field from the attribute relation.
200
* Note: returns a palloc'd copy of the string, or NULL if no such attribute.
203
get_attname(Oid relid, AttrNumber attnum)
207
tp = SearchSysCache(ATTNUM,
208
ObjectIdGetDatum(relid),
209
Int16GetDatum(attnum),
211
if (HeapTupleIsValid(tp))
213
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
216
result = pstrdup(NameStr(att_tup->attname));
225
* get_relid_attribute_name
227
* Same as above routine get_attname(), except that error
228
* is handled by elog() instead of returning NULL.
231
get_relid_attribute_name(Oid relid, AttrNumber attnum)
235
attname = get_attname(relid, attnum);
237
elog(ERROR, "cache lookup failed for attribute %d of relation %u",
245
* Given the relation id and the attribute name,
246
* return the "attnum" field from the attribute relation.
248
* Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
251
get_attnum(Oid relid, const char *attname)
255
tp = SearchSysCacheAttName(relid, attname);
256
if (HeapTupleIsValid(tp))
258
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
261
result = att_tup->attnum;
266
return InvalidAttrNumber;
272
* Given the relation OID and the attribute number with the relation,
273
* return the attribute type OID.
276
get_atttype(Oid relid, AttrNumber attnum)
280
tp = SearchSysCache(ATTNUM,
281
ObjectIdGetDatum(relid),
282
Int16GetDatum(attnum),
284
if (HeapTupleIsValid(tp))
286
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
289
result = att_tup->atttypid;
300
* Given the relation id and the attribute number,
301
* return the "atttypmod" field from the attribute relation.
304
get_atttypmod(Oid relid, AttrNumber attnum)
308
tp = SearchSysCache(ATTNUM,
309
ObjectIdGetDatum(relid),
310
Int16GetDatum(attnum),
312
if (HeapTupleIsValid(tp))
314
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
317
result = att_tup->atttypmod;
328
* A two-fer: given the relation id and the attribute number,
329
* fetch both type OID and atttypmod in a single cache lookup.
331
* Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
332
* raises an error if it can't obtain the information.
335
get_atttypetypmod(Oid relid, AttrNumber attnum,
336
Oid *typid, int32 *typmod)
339
Form_pg_attribute att_tup;
341
tp = SearchSysCache(ATTNUM,
342
ObjectIdGetDatum(relid),
343
Int16GetDatum(attnum),
345
if (!HeapTupleIsValid(tp))
346
elog(ERROR, "cache lookup failed for attribute %d of relation %u",
348
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
350
*typid = att_tup->atttypid;
351
*typmod = att_tup->atttypmod;
355
/* ---------- INDEX CACHE ---------- */
357
/* watch this space...
360
/* ---------- OPCLASS CACHE ---------- */
365
* Returns TRUE iff the specified opclass is associated with the
366
* btree index access method.
369
opclass_is_btree(Oid opclass)
372
Form_pg_opclass cla_tup;
375
tp = SearchSysCache(CLAOID,
376
ObjectIdGetDatum(opclass),
378
if (!HeapTupleIsValid(tp))
379
elog(ERROR, "cache lookup failed for opclass %u", opclass);
380
cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
382
result = (cla_tup->opcamid == BTREE_AM_OID);
390
* Returns TRUE iff the specified opclass is associated with the
391
* hash index access method.
394
opclass_is_hash(Oid opclass)
397
Form_pg_opclass cla_tup;
400
tp = SearchSysCache(CLAOID,
401
ObjectIdGetDatum(opclass),
403
if (!HeapTupleIsValid(tp))
404
elog(ERROR, "cache lookup failed for opclass %u", opclass);
405
cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
407
result = (cla_tup->opcamid == HASH_AM_OID);
412
/* ---------- OPERATOR CACHE ---------- */
417
* Returns the regproc id of the routine used to implement an
418
* operator given the operator oid.
425
tp = SearchSysCache(OPEROID,
426
ObjectIdGetDatum(opno),
428
if (HeapTupleIsValid(tp))
430
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
433
result = optup->oprcode;
438
return (RegProcedure) InvalidOid;
443
* returns the name of the operator with the given opno
445
* Note: returns a palloc'd copy of the string, or NULL if no such operator.
452
tp = SearchSysCache(OPEROID,
453
ObjectIdGetDatum(opno),
455
if (HeapTupleIsValid(tp))
457
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
460
result = pstrdup(NameStr(optup->oprname));
471
* Returns the left and right input datatypes for an operator
472
* (InvalidOid if not relevant).
475
op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
478
Form_pg_operator optup;
480
tp = SearchSysCache(OPEROID,
481
ObjectIdGetDatum(opno),
483
if (!HeapTupleIsValid(tp)) /* shouldn't happen */
484
elog(ERROR, "cache lookup failed for operator %u", opno);
485
optup = (Form_pg_operator) GETSTRUCT(tp);
486
*lefttype = optup->oprleft;
487
*righttype = optup->oprright;
494
* Returns the left and right sort operators corresponding to a
495
* mergejoinable operator, or false if the operator is not mergejoinable.
498
op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp)
503
tp = SearchSysCache(OPEROID,
504
ObjectIdGetDatum(opno),
506
if (HeapTupleIsValid(tp))
508
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
510
if (optup->oprlsortop &&
513
*leftOp = optup->oprlsortop;
514
*rightOp = optup->oprrsortop;
523
* op_mergejoin_crossops
525
* Returns the cross-type comparison operators (ltype "<" rtype and
526
* ltype ">" rtype) for an operator previously determined to be
527
* mergejoinable. Optionally, fetches the regproc ids of these
528
* operators, as well as their operator OIDs.
531
op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
532
RegProcedure *ltproc, RegProcedure *gtproc)
535
Form_pg_operator optup;
538
* Get the declared comparison operators of the operator.
540
tp = SearchSysCache(OPEROID,
541
ObjectIdGetDatum(opno),
543
if (!HeapTupleIsValid(tp)) /* shouldn't happen */
544
elog(ERROR, "cache lookup failed for operator %u", opno);
545
optup = (Form_pg_operator) GETSTRUCT(tp);
546
*ltop = optup->oprltcmpop;
547
*gtop = optup->oprgtcmpop;
550
/* Check < op provided */
551
if (!OidIsValid(*ltop))
552
elog(ERROR, "mergejoin operator %u has no matching < operator",
555
*ltproc = get_opcode(*ltop);
557
/* Check > op provided */
558
if (!OidIsValid(*gtop))
559
elog(ERROR, "mergejoin operator %u has no matching > operator",
562
*gtproc = get_opcode(*gtop);
568
* Returns true if the operator is hashjoinable.
571
op_hashjoinable(Oid opno)
576
tp = SearchSysCache(OPEROID,
577
ObjectIdGetDatum(opno),
579
if (HeapTupleIsValid(tp))
581
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
583
result = optup->oprcanhash;
592
* Get the proisstrict flag for the operator's underlying function.
597
RegProcedure funcid = get_opcode(opno);
599
if (funcid == (RegProcedure) InvalidOid)
600
elog(ERROR, "operator %u does not exist", opno);
602
return func_strict((Oid) funcid);
608
* Get the provolatile flag for the operator's underlying function.
611
op_volatile(Oid opno)
613
RegProcedure funcid = get_opcode(opno);
615
if (funcid == (RegProcedure) InvalidOid)
616
elog(ERROR, "operator %u does not exist", opno);
618
return func_volatile((Oid) funcid);
624
* Returns the corresponding commutator of an operator.
627
get_commutator(Oid opno)
631
tp = SearchSysCache(OPEROID,
632
ObjectIdGetDatum(opno),
634
if (HeapTupleIsValid(tp))
636
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
639
result = optup->oprcom;
650
* Returns the corresponding negator of an operator.
653
get_negator(Oid opno)
657
tp = SearchSysCache(OPEROID,
658
ObjectIdGetDatum(opno),
660
if (HeapTupleIsValid(tp))
662
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
665
result = optup->oprnegate;
676
* Returns procedure id for computing selectivity of an operator.
679
get_oprrest(Oid opno)
683
tp = SearchSysCache(OPEROID,
684
ObjectIdGetDatum(opno),
686
if (HeapTupleIsValid(tp))
688
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
691
result = optup->oprrest;
696
return (RegProcedure) InvalidOid;
702
* Returns procedure id for computing selectivity of a join.
705
get_oprjoin(Oid opno)
709
tp = SearchSysCache(OPEROID,
710
ObjectIdGetDatum(opno),
712
if (HeapTupleIsValid(tp))
714
Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
717
result = optup->oprjoin;
722
return (RegProcedure) InvalidOid;
725
/* ---------- FUNCTION CACHE ---------- */
729
* returns the name of the function with the given funcid
731
* Note: returns a palloc'd copy of the string, or NULL if no such function.
734
get_func_name(Oid funcid)
738
tp = SearchSysCache(PROCOID,
739
ObjectIdGetDatum(funcid),
741
if (HeapTupleIsValid(tp))
743
Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
746
result = pstrdup(NameStr(functup->proname));
756
* Given procedure id, return the function's result type.
759
get_func_rettype(Oid funcid)
764
tp = SearchSysCache(PROCOID,
765
ObjectIdGetDatum(funcid),
767
if (!HeapTupleIsValid(tp))
768
elog(ERROR, "cache lookup failed for function %u", funcid);
770
result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
777
* Given procedure id, return the function's argument and result types.
778
* (The return value is the result type.)
780
* argtypes must point to a vector of size FUNC_MAX_ARGS.
783
get_func_signature(Oid funcid, Oid *argtypes, int *nargs)
786
Form_pg_proc procstruct;
789
tp = SearchSysCache(PROCOID,
790
ObjectIdGetDatum(funcid),
792
if (!HeapTupleIsValid(tp))
793
elog(ERROR, "cache lookup failed for function %u", funcid);
795
procstruct = (Form_pg_proc) GETSTRUCT(tp);
797
result = procstruct->prorettype;
798
memcpy(argtypes, procstruct->proargtypes, FUNC_MAX_ARGS * sizeof(Oid));
799
*nargs = (int) procstruct->pronargs;
807
* Given procedure id, return the function's proretset flag.
810
get_func_retset(Oid funcid)
815
tp = SearchSysCache(PROCOID,
816
ObjectIdGetDatum(funcid),
818
if (!HeapTupleIsValid(tp))
819
elog(ERROR, "cache lookup failed for function %u", funcid);
821
result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
828
* Given procedure id, return the function's proisstrict flag.
831
func_strict(Oid funcid)
836
tp = SearchSysCache(PROCOID,
837
ObjectIdGetDatum(funcid),
839
if (!HeapTupleIsValid(tp))
840
elog(ERROR, "cache lookup failed for function %u", funcid);
842
result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;
849
* Given procedure id, return the function's provolatile flag.
852
func_volatile(Oid funcid)
857
tp = SearchSysCache(PROCOID,
858
ObjectIdGetDatum(funcid),
860
if (!HeapTupleIsValid(tp))
861
elog(ERROR, "cache lookup failed for function %u", funcid);
863
result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
868
/* ---------- RELATION CACHE ---------- */
872
* Given name and namespace of a relation, look up the OID.
874
* Returns InvalidOid if there is no such relation.
877
get_relname_relid(const char *relname, Oid relnamespace)
879
return GetSysCacheOid(RELNAMENSP,
880
PointerGetDatum(relname),
881
ObjectIdGetDatum(relnamespace),
886
* get_system_catalog_relid
887
* Get the OID of a system catalog identified by name.
890
get_system_catalog_relid(const char *catname)
894
relid = GetSysCacheOid(RELNAMENSP,
895
PointerGetDatum(catname),
896
ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
898
if (!OidIsValid(relid))
899
elog(ERROR, "cache lookup failed for system relation %s", catname);
908
* Returns the number of attributes for a given relation.
911
get_relnatts(Oid relid)
915
tp = SearchSysCache(RELOID,
916
ObjectIdGetDatum(relid),
918
if (HeapTupleIsValid(tp))
920
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
923
result = reltup->relnatts;
928
return InvalidAttrNumber;
934
* Returns the name of a given relation.
936
* Returns a palloc'd copy of the string, or NULL if no such relation.
938
* NOTE: since relation name is not unique, be wary of code that uses this
939
* for anything except preparing error messages.
942
get_rel_name(Oid relid)
946
tp = SearchSysCache(RELOID,
947
ObjectIdGetDatum(relid),
949
if (HeapTupleIsValid(tp))
951
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
954
result = pstrdup(NameStr(reltup->relname));
965
* Returns the pg_namespace OID associated with a given relation.
968
get_rel_namespace(Oid relid)
972
tp = SearchSysCache(RELOID,
973
ObjectIdGetDatum(relid),
975
if (HeapTupleIsValid(tp))
977
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
980
result = reltup->relnamespace;
991
* Returns the pg_type OID associated with a given relation.
993
* Note: not all pg_class entries have associated pg_type OIDs; so be
994
* careful to check for InvalidOid result.
997
get_rel_type_id(Oid relid)
1001
tp = SearchSysCache(RELOID,
1002
ObjectIdGetDatum(relid),
1004
if (HeapTupleIsValid(tp))
1006
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1009
result = reltup->reltype;
1010
ReleaseSysCache(tp);
1020
* Returns the relkind associated with a given relation.
1023
get_rel_relkind(Oid relid)
1027
tp = SearchSysCache(RELOID,
1028
ObjectIdGetDatum(relid),
1030
if (HeapTupleIsValid(tp))
1032
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
1035
result = reltup->relkind;
1036
ReleaseSysCache(tp);
1044
/* ---------- TYPE CACHE ---------- */
1049
* Given the type OID, determine whether the type is defined
1050
* (if not, it's only a shell).
1053
get_typisdefined(Oid typid)
1057
tp = SearchSysCache(TYPEOID,
1058
ObjectIdGetDatum(typid),
1060
if (HeapTupleIsValid(tp))
1062
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1065
result = typtup->typisdefined;
1066
ReleaseSysCache(tp);
1076
* Given the type OID, return the length of the type.
1079
get_typlen(Oid typid)
1083
tp = SearchSysCache(TYPEOID,
1084
ObjectIdGetDatum(typid),
1086
if (HeapTupleIsValid(tp))
1088
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1091
result = typtup->typlen;
1092
ReleaseSysCache(tp);
1102
* Given the type OID, determine whether the type is returned by value or
1103
* not. Returns true if by value, false if by reference.
1106
get_typbyval(Oid typid)
1110
tp = SearchSysCache(TYPEOID,
1111
ObjectIdGetDatum(typid),
1113
if (HeapTupleIsValid(tp))
1115
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1118
result = typtup->typbyval;
1119
ReleaseSysCache(tp);
1129
* A two-fer: given the type OID, return both typlen and typbyval.
1131
* Since both pieces of info are needed to know how to copy a Datum,
1132
* many places need both. Might as well get them with one cache lookup
1133
* instead of two. Also, this routine raises an error instead of
1134
* returning a bogus value when given a bad type OID.
1137
get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
1140
Form_pg_type typtup;
1142
tp = SearchSysCache(TYPEOID,
1143
ObjectIdGetDatum(typid),
1145
if (!HeapTupleIsValid(tp))
1146
elog(ERROR, "cache lookup failed for type %u", typid);
1147
typtup = (Form_pg_type) GETSTRUCT(tp);
1148
*typlen = typtup->typlen;
1149
*typbyval = typtup->typbyval;
1150
ReleaseSysCache(tp);
1154
* get_typlenbyvalalign
1156
* A three-fer: given the type OID, return typlen, typbyval, typalign.
1159
get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
1163
Form_pg_type typtup;
1165
tp = SearchSysCache(TYPEOID,
1166
ObjectIdGetDatum(typid),
1168
if (!HeapTupleIsValid(tp))
1169
elog(ERROR, "cache lookup failed for type %u", typid);
1170
typtup = (Form_pg_type) GETSTRUCT(tp);
1171
*typlen = typtup->typlen;
1172
*typbyval = typtup->typbyval;
1173
*typalign = typtup->typalign;
1174
ReleaseSysCache(tp);
1179
* Given a pg_type row, select the type OID to pass to I/O functions
1181
* Formerly, all I/O functions were passed pg_type.typelem as their second
1182
* parameter, but we now have a more complex rule about what to pass.
1183
* This knowledge is intended to be centralized here --- direct references
1184
* to typelem elsewhere in the code are wrong, if they are associated with
1185
* I/O calls and not with actual subscripting operations! (But see
1186
* bootstrap.c, which can't conveniently use this routine.)
1189
getTypeIOParam(HeapTuple typeTuple)
1191
Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1194
* Composite types get their own OID as parameter; array types get
1195
* their typelem as parameter; everybody else gets zero.
1197
if (typeStruct->typtype == 'c')
1198
return HeapTupleGetOid(typeTuple);
1200
return typeStruct->typelem;
1206
* A six-fer: given the type OID, return typlen, typbyval, typalign,
1207
* typdelim, typioparam, and IO function OID. The IO function
1208
* returned is controlled by IOFuncSelector
1211
get_type_io_data(Oid typid,
1212
IOFuncSelector which_func,
1220
HeapTuple typeTuple;
1221
Form_pg_type typeStruct;
1223
typeTuple = SearchSysCache(TYPEOID,
1224
ObjectIdGetDatum(typid),
1226
if (!HeapTupleIsValid(typeTuple))
1227
elog(ERROR, "cache lookup failed for type %u", typid);
1228
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1230
*typlen = typeStruct->typlen;
1231
*typbyval = typeStruct->typbyval;
1232
*typalign = typeStruct->typalign;
1233
*typdelim = typeStruct->typdelim;
1234
*typioparam = getTypeIOParam(typeTuple);
1238
*func = typeStruct->typinput;
1241
*func = typeStruct->typoutput;
1243
case IOFunc_receive:
1244
*func = typeStruct->typreceive;
1247
*func = typeStruct->typsend;
1250
ReleaseSysCache(typeTuple);
1255
get_typalign(Oid typid)
1259
tp = SearchSysCache(TYPEOID,
1260
ObjectIdGetDatum(typid),
1262
if (HeapTupleIsValid(tp))
1264
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1267
result = typtup->typalign;
1268
ReleaseSysCache(tp);
1277
get_typstorage(Oid typid)
1281
tp = SearchSysCache(TYPEOID,
1282
ObjectIdGetDatum(typid),
1284
if (HeapTupleIsValid(tp))
1286
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1289
result = typtup->typstorage;
1290
ReleaseSysCache(tp);
1300
* Given the type OID, return the typtypmod field (domain's typmod
1304
get_typtypmod(Oid typid)
1308
tp = SearchSysCache(TYPEOID,
1309
ObjectIdGetDatum(typid),
1311
if (HeapTupleIsValid(tp))
1313
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1316
result = typtup->typtypmod;
1317
ReleaseSysCache(tp);
1326
* Given a type OID, return the type's default value, if any.
1328
* The result is a palloc'd expression node tree, or NULL if there
1329
* is no defined default for the datatype.
1331
* NB: caller should be prepared to coerce result to correct datatype;
1332
* the returned expression tree might produce something of the wrong type.
1335
get_typdefault(Oid typid)
1337
HeapTuple typeTuple;
1343
typeTuple = SearchSysCache(TYPEOID,
1344
ObjectIdGetDatum(typid),
1346
if (!HeapTupleIsValid(typeTuple))
1347
elog(ERROR, "cache lookup failed for type %u", typid);
1348
type = (Form_pg_type) GETSTRUCT(typeTuple);
1351
* typdefault and typdefaultbin are potentially null, so don't try to
1352
* access 'em as struct fields. Must do it the hard way with
1355
datum = SysCacheGetAttr(TYPEOID,
1357
Anum_pg_type_typdefaultbin,
1362
/* We have an expression default */
1363
expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
1368
/* Perhaps we have a plain literal default */
1369
datum = SysCacheGetAttr(TYPEOID,
1371
Anum_pg_type_typdefault,
1376
char *strDefaultVal;
1378
/* Convert text datum to C string */
1379
strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
1381
/* Convert C string to a value of the given type */
1382
datum = OidFunctionCall3(type->typinput,
1383
CStringGetDatum(strDefaultVal),
1384
ObjectIdGetDatum(getTypeIOParam(typeTuple)),
1386
/* Build a Const node containing the value */
1387
expr = (Node *) makeConst(typid,
1392
pfree(strDefaultVal);
1401
ReleaseSysCache(typeTuple);
1408
* If the given type is a domain, return its base type;
1409
* otherwise return the type's own OID.
1412
getBaseType(Oid typid)
1415
* We loop to find the bottom base type in a stack of domains.
1420
Form_pg_type typTup;
1422
tup = SearchSysCache(TYPEOID,
1423
ObjectIdGetDatum(typid),
1425
if (!HeapTupleIsValid(tup))
1426
elog(ERROR, "cache lookup failed for type %u", typid);
1427
typTup = (Form_pg_type) GETSTRUCT(tup);
1428
if (typTup->typtype != 'd')
1430
/* Not a domain, so done */
1431
ReleaseSysCache(tup);
1435
typid = typTup->typbasetype;
1436
ReleaseSysCache(tup);
1445
* Given a type OID and a typmod value (pass -1 if typmod is unknown),
1446
* estimate the average width of values of the type. This is used by
1447
* the planner, which doesn't require absolutely correct results;
1448
* it's OK (and expected) to guess if we don't know for sure.
1451
get_typavgwidth(Oid typid, int32 typmod)
1453
int typlen = get_typlen(typid);
1457
* Easy if it's a fixed-width type
1463
* type_maximum_size knows the encoding of typmod for some datatypes;
1464
* don't duplicate that knowledge here.
1466
maxwidth = type_maximum_size(typid, typmod);
1470
* For BPCHAR, the max width is also the only width. Otherwise we
1471
* need to guess about the typical data width given the max. A
1472
* sliding scale for percentage of max width seems reasonable.
1474
if (typid == BPCHAROID)
1477
return maxwidth; /* assume full width */
1478
if (maxwidth < 1000)
1479
return 32 + (maxwidth - 32) / 2; /* assume 50% */
1482
* Beyond 1000, assume we're looking at something like
1483
* "varchar(10000)" where the limit isn't actually reached often,
1484
* and use a fixed estimate.
1486
return 32 + (1000 - 32) / 2;
1490
* Ooops, we have no idea ... wild guess time.
1498
* Given the type OID, find if it is a basic type, a complex type, etc.
1499
* It returns the null char if the cache lookup fails...
1502
get_typtype(Oid typid)
1506
tp = SearchSysCache(TYPEOID,
1507
ObjectIdGetDatum(typid),
1509
if (HeapTupleIsValid(tp))
1511
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1514
result = typtup->typtype;
1515
ReleaseSysCache(tp);
1523
* get_type_func_class
1525
* Given the type OID, obtain its TYPEFUNC classification.
1527
* This is intended to centralize a bunch of formerly ad-hoc code for
1528
* classifying types. The categories used here are useful for deciding
1529
* how to handle functions returning the datatype.
1532
get_type_func_class(Oid typid)
1534
switch (get_typtype(typid))
1537
return TYPEFUNC_COMPOSITE;
1540
return TYPEFUNC_SCALAR;
1542
if (typid == RECORDOID)
1543
return TYPEFUNC_RECORD;
1545
* We treat VOID and CSTRING as legitimate scalar datatypes,
1546
* mostly for the convenience of the JDBC driver (which wants
1547
* to be able to do "SELECT * FROM foo()" for all legitimately
1548
* user-callable functions).
1550
if (typid == VOIDOID || typid == CSTRINGOID)
1551
return TYPEFUNC_SCALAR;
1552
return TYPEFUNC_OTHER;
1554
/* shouldn't get here, probably */
1555
return TYPEFUNC_OTHER;
1561
* Given the type OID, get the typrelid (InvalidOid if not a complex
1565
get_typ_typrelid(Oid typid)
1569
tp = SearchSysCache(TYPEOID,
1570
ObjectIdGetDatum(typid),
1572
if (HeapTupleIsValid(tp))
1574
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1577
result = typtup->typrelid;
1578
ReleaseSysCache(tp);
1588
* Given the type OID, get the typelem (InvalidOid if not an array type).
1590
* NB: this only considers varlena arrays to be true arrays; InvalidOid is
1591
* returned if the input is a fixed-length array type.
1594
get_element_type(Oid typid)
1598
tp = SearchSysCache(TYPEOID,
1599
ObjectIdGetDatum(typid),
1601
if (HeapTupleIsValid(tp))
1603
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1606
if (typtup->typlen == -1)
1607
result = typtup->typelem;
1609
result = InvalidOid;
1610
ReleaseSysCache(tp);
1620
* Given the type OID, get the corresponding array type.
1621
* Returns InvalidOid if no array type can be found.
1623
* NB: this only considers varlena arrays to be true arrays.
1626
get_array_type(Oid typid)
1630
tp = SearchSysCache(TYPEOID,
1631
ObjectIdGetDatum(typid),
1633
if (HeapTupleIsValid(tp))
1635
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1636
char *array_typename;
1639
array_typename = makeArrayTypeName(NameStr(typtup->typname));
1640
namespaceId = typtup->typnamespace;
1641
ReleaseSysCache(tp);
1643
tp = SearchSysCache(TYPENAMENSP,
1644
PointerGetDatum(array_typename),
1645
ObjectIdGetDatum(namespaceId),
1648
pfree(array_typename);
1650
if (HeapTupleIsValid(tp))
1654
typtup = (Form_pg_type) GETSTRUCT(tp);
1655
if (typtup->typlen == -1 && typtup->typelem == typid)
1656
result = HeapTupleGetOid(tp);
1658
result = InvalidOid;
1659
ReleaseSysCache(tp);
1669
* Get info needed for converting values of a type to internal form
1672
getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
1674
HeapTuple typeTuple;
1677
typeTuple = SearchSysCache(TYPEOID,
1678
ObjectIdGetDatum(type),
1680
if (!HeapTupleIsValid(typeTuple))
1681
elog(ERROR, "cache lookup failed for type %u", type);
1682
pt = (Form_pg_type) GETSTRUCT(typeTuple);
1684
if (!pt->typisdefined)
1686
(errcode(ERRCODE_UNDEFINED_OBJECT),
1687
errmsg("type %s is only a shell",
1688
format_type_be(type))));
1689
if (!OidIsValid(pt->typinput))
1691
(errcode(ERRCODE_UNDEFINED_FUNCTION),
1692
errmsg("no input function available for type %s",
1693
format_type_be(type))));
1695
*typInput = pt->typinput;
1696
*typIOParam = getTypeIOParam(typeTuple);
1698
ReleaseSysCache(typeTuple);
1704
* Get info needed for printing values of a type
1707
getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typIOParam,
1710
HeapTuple typeTuple;
1713
typeTuple = SearchSysCache(TYPEOID,
1714
ObjectIdGetDatum(type),
1716
if (!HeapTupleIsValid(typeTuple))
1717
elog(ERROR, "cache lookup failed for type %u", type);
1718
pt = (Form_pg_type) GETSTRUCT(typeTuple);
1720
if (!pt->typisdefined)
1722
(errcode(ERRCODE_UNDEFINED_OBJECT),
1723
errmsg("type %s is only a shell",
1724
format_type_be(type))));
1725
if (!OidIsValid(pt->typoutput))
1727
(errcode(ERRCODE_UNDEFINED_FUNCTION),
1728
errmsg("no output function available for type %s",
1729
format_type_be(type))));
1731
*typOutput = pt->typoutput;
1732
*typIOParam = getTypeIOParam(typeTuple);
1733
*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
1735
ReleaseSysCache(typeTuple);
1739
* getTypeBinaryInputInfo
1741
* Get info needed for binary input of values of a type
1744
getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
1746
HeapTuple typeTuple;
1749
typeTuple = SearchSysCache(TYPEOID,
1750
ObjectIdGetDatum(type),
1752
if (!HeapTupleIsValid(typeTuple))
1753
elog(ERROR, "cache lookup failed for type %u", type);
1754
pt = (Form_pg_type) GETSTRUCT(typeTuple);
1756
if (!pt->typisdefined)
1758
(errcode(ERRCODE_UNDEFINED_OBJECT),
1759
errmsg("type %s is only a shell",
1760
format_type_be(type))));
1761
if (!OidIsValid(pt->typreceive))
1763
(errcode(ERRCODE_UNDEFINED_FUNCTION),
1764
errmsg("no binary input function available for type %s",
1765
format_type_be(type))));
1767
*typReceive = pt->typreceive;
1768
*typIOParam = getTypeIOParam(typeTuple);
1770
ReleaseSysCache(typeTuple);
1774
* getTypeBinaryOutputInfo
1776
* Get info needed for binary output of values of a type
1779
getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typIOParam,
1782
HeapTuple typeTuple;
1785
typeTuple = SearchSysCache(TYPEOID,
1786
ObjectIdGetDatum(type),
1788
if (!HeapTupleIsValid(typeTuple))
1789
elog(ERROR, "cache lookup failed for type %u", type);
1790
pt = (Form_pg_type) GETSTRUCT(typeTuple);
1792
if (!pt->typisdefined)
1794
(errcode(ERRCODE_UNDEFINED_OBJECT),
1795
errmsg("type %s is only a shell",
1796
format_type_be(type))));
1797
if (!OidIsValid(pt->typsend))
1799
(errcode(ERRCODE_UNDEFINED_FUNCTION),
1800
errmsg("no binary output function available for type %s",
1801
format_type_be(type))));
1803
*typSend = pt->typsend;
1804
*typIOParam = getTypeIOParam(typeTuple);
1805
*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
1807
ReleaseSysCache(typeTuple);
1811
/* ---------- STATISTICS CACHE ---------- */
1816
* Given the table and attribute number of a column, get the average
1817
* width of entries in the column. Return zero if no data available.
1820
get_attavgwidth(Oid relid, AttrNumber attnum)
1824
tp = SearchSysCache(STATRELATT,
1825
ObjectIdGetDatum(relid),
1826
Int16GetDatum(attnum),
1828
if (HeapTupleIsValid(tp))
1830
int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
1832
ReleaseSysCache(tp);
1842
* Extract the contents of a "slot" of a pg_statistic tuple.
1843
* Returns TRUE if requested slot type was found, else FALSE.
1845
* Unlike other routines in this file, this takes a pointer to an
1846
* already-looked-up tuple in the pg_statistic cache. We do this since
1847
* most callers will want to extract more than one value from the cache
1848
* entry, and we don't want to repeat the cache lookup unnecessarily.
1850
* statstuple: pg_statistics tuple to be examined.
1851
* atttype: type OID of attribute.
1852
* atttypmod: typmod of attribute.
1853
* reqkind: STAKIND code for desired statistics slot kind.
1854
* reqop: STAOP value wanted, or InvalidOid if don't care.
1855
* values, nvalues: if not NULL, the slot's stavalues are extracted.
1856
* numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
1858
* If assigned, values and numbers are set to point to palloc'd arrays.
1859
* If the attribute type is pass-by-reference, the values referenced by
1860
* the values array are themselves palloc'd. The palloc'd stuff can be
1861
* freed by calling free_attstatsslot.
1864
get_attstatsslot(HeapTuple statstuple,
1865
Oid atttype, int32 atttypmod,
1866
int reqkind, Oid reqop,
1867
Datum **values, int *nvalues,
1868
float4 **numbers, int *nnumbers)
1870
Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
1875
ArrayType *statarray;
1877
HeapTuple typeTuple;
1878
Form_pg_type typeForm;
1880
for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
1882
if ((&stats->stakind1)[i] == reqkind &&
1883
(reqop == InvalidOid || (&stats->staop1)[i] == reqop))
1886
if (i >= STATISTIC_NUM_SLOTS)
1887
return false; /* not there */
1891
val = SysCacheGetAttr(STATRELATT, statstuple,
1892
Anum_pg_statistic_stavalues1 + i,
1895
elog(ERROR, "stavalues is null");
1896
statarray = DatumGetArrayTypeP(val);
1898
/* Need to get info about the array element type */
1899
typeTuple = SearchSysCache(TYPEOID,
1900
ObjectIdGetDatum(atttype),
1902
if (!HeapTupleIsValid(typeTuple))
1903
elog(ERROR, "cache lookup failed for type %u", atttype);
1904
typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
1906
/* Deconstruct array into Datum elements */
1907
deconstruct_array(statarray,
1915
* If the element type is pass-by-reference, we now have a bunch
1916
* of Datums that are pointers into the syscache value. Copy them
1917
* to avoid problems if syscache decides to drop the entry.
1919
if (!typeForm->typbyval)
1921
for (j = 0; j < *nvalues; j++)
1923
(*values)[j] = datumCopy((*values)[j],
1929
ReleaseSysCache(typeTuple);
1932
* Free statarray if it's a detoasted copy.
1934
if ((Pointer) statarray != DatumGetPointer(val))
1940
val = SysCacheGetAttr(STATRELATT, statstuple,
1941
Anum_pg_statistic_stanumbers1 + i,
1944
elog(ERROR, "stanumbers is null");
1945
statarray = DatumGetArrayTypeP(val);
1948
* We expect the array to be a 1-D float4 array; verify that. We
1949
* don't need to use deconstruct_array() since the array data is
1950
* just going to look like a C array of float4 values.
1952
narrayelem = ARR_DIMS(statarray)[0];
1953
if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
1954
ARR_ELEMTYPE(statarray) != FLOAT4OID)
1955
elog(ERROR, "stanumbers is not a 1-D float4 array");
1956
*numbers = (float4 *) palloc(narrayelem * sizeof(float4));
1957
memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
1958
*nnumbers = narrayelem;
1961
* Free statarray if it's a detoasted copy.
1963
if ((Pointer) statarray != DatumGetPointer(val))
1971
free_attstatsslot(Oid atttype,
1972
Datum *values, int nvalues,
1973
float4 *numbers, int nnumbers)
1977
if (!get_typbyval(atttype))
1981
for (i = 0; i < nvalues; i++)
1982
pfree(DatumGetPointer(values[i]));
1990
/* ---------- PG_NAMESPACE CACHE ---------- */
1993
* get_namespace_name
1994
* Returns the name of a given namespace
1996
* Returns a palloc'd copy of the string, or NULL if no such namespace.
1999
get_namespace_name(Oid nspid)
2003
tp = SearchSysCache(NAMESPACEOID,
2004
ObjectIdGetDatum(nspid),
2006
if (HeapTupleIsValid(tp))
2008
Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
2011
result = pstrdup(NameStr(nsptup->nspname));
2012
ReleaseSysCache(tp);
2019
/* ---------- PG_SHADOW CACHE ---------- */
2024
* Given a user name, look up the user's sysid.
2025
* Raises an error if no such user (rather than returning zero,
2026
* which might possibly be a valid usesysid).
2028
* Note: the type of usesysid is currently int4, but may change to Oid
2029
* someday. It'd be reasonable to return zero on failure if we were
2033
get_usesysid(const char *username)
2038
userTup = SearchSysCache(SHADOWNAME,
2039
PointerGetDatum(username),
2041
if (!HeapTupleIsValid(userTup))
2043
(errcode(ERRCODE_UNDEFINED_OBJECT),
2044
errmsg("user \"%s\" does not exist", username)));
2046
result = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
2048
ReleaseSysCache(userTup);