1 /*-------------------------------------------------------------------------
4 * Convenience routines for common queries in the system catalog cache.
6 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.74 2002/06/20 20:29:39 momjian Exp $
13 * Eventually, the index information should go through here, too.
14 *-------------------------------------------------------------------------
18 #include "access/tupmacs.h"
19 #include "catalog/pg_amop.h"
20 #include "catalog/pg_namespace.h"
21 #include "catalog/pg_opclass.h"
22 #include "catalog/pg_operator.h"
23 #include "catalog/pg_proc.h"
24 #include "catalog/pg_shadow.h"
25 #include "catalog/pg_statistic.h"
26 #include "catalog/pg_type.h"
27 #include "nodes/makefuncs.h"
28 #include "utils/array.h"
29 #include "utils/builtins.h"
30 #include "utils/lsyscache.h"
31 #include "utils/syscache.h"
34 /* ---------- AMOP CACHES ---------- */
39 * Return t iff operator 'opno' is in operator class 'opclass'.
42 op_in_opclass(Oid opno, Oid opclass)
44 return SearchSysCacheExists(AMOPOPID,
45 ObjectIdGetDatum(opclass),
46 ObjectIdGetDatum(opno),
53 * Return t if operator 'opno' requires a recheck when used as a
54 * member of opclass 'opclass' (ie, this opclass is lossy for this
57 * Caller should already have verified that opno is a member of opclass,
58 * therefore we raise an error if the tuple is not found.
61 op_requires_recheck(Oid opno, Oid opclass)
64 Form_pg_amop amop_tup;
67 tp = SearchSysCache(AMOPOPID,
68 ObjectIdGetDatum(opclass),
69 ObjectIdGetDatum(opno),
71 if (!HeapTupleIsValid(tp))
72 elog(ERROR, "op_requires_recheck: op %u is not a member of opclass %u",
74 amop_tup = (Form_pg_amop) GETSTRUCT(tp);
76 result = amop_tup->amopreqcheck;
81 /* ---------- ATTRIBUTE CACHES ---------- */
86 * Given the relation id and the attribute number,
87 * return the "attname" field from the attribute relation.
89 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
92 get_attname(Oid relid, AttrNumber attnum)
96 tp = SearchSysCache(ATTNUM,
97 ObjectIdGetDatum(relid),
98 Int16GetDatum(attnum),
100 if (HeapTupleIsValid(tp))
102 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
105 result = pstrdup(NameStr(att_tup->attname));
116 * Given the relation id and the attribute name,
117 * return the "attnum" field from the attribute relation.
120 get_attnum(Oid relid, char *attname)
124 tp = SearchSysCache(ATTNAME,
125 ObjectIdGetDatum(relid),
126 PointerGetDatum(attname),
128 if (HeapTupleIsValid(tp))
130 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
133 result = att_tup->attnum;
138 return InvalidAttrNumber;
144 * Given the relation OID and the attribute number with the relation,
145 * return the attribute type OID.
148 get_atttype(Oid relid, AttrNumber attnum)
152 tp = SearchSysCache(ATTNUM,
153 ObjectIdGetDatum(relid),
154 Int16GetDatum(attnum),
156 if (HeapTupleIsValid(tp))
158 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
161 result = att_tup->atttypid;
169 /* This routine uses the attname instead of the attnum because it
170 * replaces the routine find_atttype, which is called sometimes when
171 * only the attname, not the attno, is available.
174 get_attisset(Oid relid, char *attname)
178 tp = SearchSysCache(ATTNAME,
179 ObjectIdGetDatum(relid),
180 PointerGetDatum(attname),
182 if (HeapTupleIsValid(tp))
184 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
187 result = att_tup->attisset;
198 * Given the relation id and the attribute number,
199 * return the "atttypmod" field from the attribute relation.
202 get_atttypmod(Oid relid, AttrNumber attnum)
206 tp = SearchSysCache(ATTNUM,
207 ObjectIdGetDatum(relid),
208 Int16GetDatum(attnum),
210 if (HeapTupleIsValid(tp))
212 Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
215 result = att_tup->atttypmod;
226 * A two-fer: given the relation id and the attribute number,
227 * fetch both type OID and atttypmod in a single cache lookup.
229 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
230 * raises an error if it can't obtain the information.
233 get_atttypetypmod(Oid relid, AttrNumber attnum,
234 Oid *typid, int32 *typmod)
237 Form_pg_attribute att_tup;
239 tp = SearchSysCache(ATTNUM,
240 ObjectIdGetDatum(relid),
241 Int16GetDatum(attnum),
243 if (!HeapTupleIsValid(tp))
244 elog(ERROR, "cache lookup failed for relation %u attribute %d",
246 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
248 *typid = att_tup->atttypid;
249 *typmod = att_tup->atttypmod;
253 /* ---------- INDEX CACHE ---------- */
255 /* watch this space...
258 /* ---------- OPCLASS CACHE ---------- */
263 * Returns TRUE iff the specified opclass is associated with the
264 * btree index access method.
267 opclass_is_btree(Oid opclass)
270 Form_pg_opclass cla_tup;
273 tp = SearchSysCache(CLAOID,
274 ObjectIdGetDatum(opclass),
276 if (!HeapTupleIsValid(tp))
277 elog(ERROR, "cache lookup failed for opclass %u", opclass);
278 cla_tup = (Form_pg_opclass) GETSTRUCT(tp);
280 result = (cla_tup->opcamid == BTREE_AM_OID);
285 /* ---------- OPERATOR CACHE ---------- */
290 * Returns the regproc id of the routine used to implement an
291 * operator given the operator oid.
298 tp = SearchSysCache(OPEROID,
299 ObjectIdGetDatum(opno),
301 if (HeapTupleIsValid(tp))
303 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
306 result = optup->oprcode;
311 return (RegProcedure) InvalidOid;
316 * returns the name of the operator with the given opno
318 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
325 tp = SearchSysCache(OPEROID,
326 ObjectIdGetDatum(opno),
328 if (HeapTupleIsValid(tp))
330 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
333 result = pstrdup(NameStr(optup->oprname));
344 * Returns the left and right sort operators and types corresponding to a
345 * mergejoinable operator, or nil if the operator is not mergejoinable.
348 op_mergejoinable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
353 tp = SearchSysCache(OPEROID,
354 ObjectIdGetDatum(opno),
356 if (HeapTupleIsValid(tp))
358 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
360 if (optup->oprlsortop &&
362 optup->oprleft == ltype &&
363 optup->oprright == rtype)
365 *leftOp = optup->oprlsortop;
366 *rightOp = optup->oprrsortop;
375 * op_mergejoin_crossops
377 * Returns the cross-type comparison operators (ltype "<" rtype and
378 * ltype ">" rtype) for an operator previously determined to be
379 * mergejoinable. Optionally, fetches the regproc ids of these
380 * operators, as well as their operator OIDs.
383 op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
384 RegProcedure *ltproc, RegProcedure *gtproc)
387 Form_pg_operator optup;
390 * Get the declared comparison operators of the operator.
392 tp = SearchSysCache(OPEROID,
393 ObjectIdGetDatum(opno),
395 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
396 elog(ERROR, "op_mergejoin_crossops: operator %u not found", opno);
397 optup = (Form_pg_operator) GETSTRUCT(tp);
398 *ltop = optup->oprltcmpop;
399 *gtop = optup->oprgtcmpop;
402 /* Check < op provided */
403 if (!OidIsValid(*ltop))
404 elog(ERROR, "op_mergejoin_crossops: mergejoin operator %u has no matching < operator",
407 *ltproc = get_opcode(*ltop);
409 /* Check > op provided */
410 if (!OidIsValid(*gtop))
411 elog(ERROR, "op_mergejoin_crossops: mergejoin operator %u has no matching > operator",
414 *gtproc = get_opcode(*gtop);
420 * Returns the hash operator corresponding to a hashjoinable operator,
421 * or InvalidOid if the operator is not hashjoinable.
424 op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
427 Oid result = InvalidOid;
429 tp = SearchSysCache(OPEROID,
430 ObjectIdGetDatum(opno),
432 if (HeapTupleIsValid(tp))
434 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
436 if (optup->oprcanhash &&
437 optup->oprleft == ltype &&
438 optup->oprright == rtype)
448 * Get the provolatile flag for the operator's underlying function.
451 op_volatile(Oid opno)
453 RegProcedure funcid = get_opcode(opno);
455 if (funcid == (RegProcedure) InvalidOid)
456 elog(ERROR, "Operator OID %u does not exist", opno);
458 return func_volatile((Oid) funcid);
464 * Returns the corresponding commutator of an operator.
467 get_commutator(Oid opno)
471 tp = SearchSysCache(OPEROID,
472 ObjectIdGetDatum(opno),
474 if (HeapTupleIsValid(tp))
476 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
479 result = optup->oprcom;
490 * Returns the corresponding negator of an operator.
493 get_negator(Oid opno)
497 tp = SearchSysCache(OPEROID,
498 ObjectIdGetDatum(opno),
500 if (HeapTupleIsValid(tp))
502 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
505 result = optup->oprnegate;
516 * Returns procedure id for computing selectivity of an operator.
519 get_oprrest(Oid opno)
523 tp = SearchSysCache(OPEROID,
524 ObjectIdGetDatum(opno),
526 if (HeapTupleIsValid(tp))
528 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
531 result = optup->oprrest;
536 return (RegProcedure) InvalidOid;
542 * Returns procedure id for computing selectivity of a join.
545 get_oprjoin(Oid opno)
549 tp = SearchSysCache(OPEROID,
550 ObjectIdGetDatum(opno),
552 if (HeapTupleIsValid(tp))
554 Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);
557 result = optup->oprjoin;
562 return (RegProcedure) InvalidOid;
565 /* ---------- FUNCTION CACHE ---------- */
569 * returns the name of the function with the given funcid
571 * Note: returns a palloc'd copy of the string, or NULL if no such function.
574 get_func_name(Oid funcid)
578 tp = SearchSysCache(PROCOID,
579 ObjectIdGetDatum(funcid),
581 if (HeapTupleIsValid(tp))
583 Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
586 result = pstrdup(NameStr(functup->proname));
596 * Given procedure id, return the function's result type.
599 get_func_rettype(Oid funcid)
604 tp = SearchSysCache(PROCOID,
605 ObjectIdGetDatum(funcid),
607 if (!HeapTupleIsValid(tp))
608 elog(ERROR, "Function OID %u does not exist", funcid);
610 result = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
617 * Given procedure id, return the function's proretset flag.
620 get_func_retset(Oid funcid)
625 tp = SearchSysCache(PROCOID,
626 ObjectIdGetDatum(funcid),
628 if (!HeapTupleIsValid(tp))
629 elog(ERROR, "Function OID %u does not exist", funcid);
631 result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;
638 * Given procedure id, return the function's provolatile flag.
641 func_volatile(Oid funcid)
646 tp = SearchSysCache(PROCOID,
647 ObjectIdGetDatum(funcid),
649 if (!HeapTupleIsValid(tp))
650 elog(ERROR, "Function OID %u does not exist", funcid);
652 result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;
657 /* ---------- RELATION CACHE ---------- */
661 * Given name and namespace of a relation, look up the OID.
663 * Returns InvalidOid if there is no such relation.
666 get_relname_relid(const char *relname, Oid relnamespace)
668 return GetSysCacheOid(RELNAMENSP,
669 PointerGetDatum(relname),
670 ObjectIdGetDatum(relnamespace),
678 * Returns the number of attributes for a given relation.
681 get_relnatts(Oid relid)
685 tp = SearchSysCache(RELOID,
686 ObjectIdGetDatum(relid),
688 if (HeapTupleIsValid(tp))
690 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
693 result = reltup->relnatts;
698 return InvalidAttrNumber;
704 * Returns the name of a given relation.
706 * Returns a palloc'd copy of the string, or NULL if no such relation.
708 * NOTE: since relation name is not unique, be wary of code that uses this
709 * for anything except preparing error messages.
712 get_rel_name(Oid relid)
716 tp = SearchSysCache(RELOID,
717 ObjectIdGetDatum(relid),
719 if (HeapTupleIsValid(tp))
721 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
724 result = pstrdup(NameStr(reltup->relname));
735 * Returns the pg_namespace OID associated with a given relation.
738 get_rel_namespace(Oid relid)
742 tp = SearchSysCache(RELOID,
743 ObjectIdGetDatum(relid),
745 if (HeapTupleIsValid(tp))
747 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
750 result = reltup->relnamespace;
761 * Returns the pg_type OID associated with a given relation.
763 * Note: not all pg_class entries have associated pg_type OIDs; so be
764 * careful to check for InvalidOid result.
767 get_rel_type_id(Oid relid)
771 tp = SearchSysCache(RELOID,
772 ObjectIdGetDatum(relid),
774 if (HeapTupleIsValid(tp))
776 Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
779 result = reltup->reltype;
787 /* ---------- TYPE CACHE ---------- */
792 * Given the type OID, determine whether the type is defined
793 * (if not, it's only a shell).
796 get_typisdefined(Oid typid)
800 tp = SearchSysCache(TYPEOID,
801 ObjectIdGetDatum(typid),
803 if (HeapTupleIsValid(tp))
805 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
808 result = typtup->typisdefined;
819 * Given the type OID, return the length of the type.
822 get_typlen(Oid typid)
826 tp = SearchSysCache(TYPEOID,
827 ObjectIdGetDatum(typid),
829 if (HeapTupleIsValid(tp))
831 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
834 result = typtup->typlen;
845 * Given the type OID, determine whether the type is returned by value or
846 * not. Returns true if by value, false if by reference.
849 get_typbyval(Oid typid)
853 tp = SearchSysCache(TYPEOID,
854 ObjectIdGetDatum(typid),
856 if (HeapTupleIsValid(tp))
858 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
861 result = typtup->typbyval;
872 * A two-fer: given the type OID, return both typlen and typbyval.
874 * Since both pieces of info are needed to know how to copy a Datum,
875 * many places need both. Might as well get them with one cache lookup
876 * instead of two. Also, this routine raises an error instead of
877 * returning a bogus value when given a bad type OID.
880 get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
885 tp = SearchSysCache(TYPEOID,
886 ObjectIdGetDatum(typid),
888 if (!HeapTupleIsValid(tp))
889 elog(ERROR, "cache lookup failed for type %u", typid);
890 typtup = (Form_pg_type) GETSTRUCT(tp);
891 *typlen = typtup->typlen;
892 *typbyval = typtup->typbyval;
898 get_typalign(Oid typid)
902 tp = SearchSysCache(TYPEOID,
903 ObjectIdGetDatum(typid),
905 if (HeapTupleIsValid(tp))
907 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
910 result = typtup->typalign;
920 get_typstorage(Oid typid)
924 tp = SearchSysCache(TYPEOID,
925 ObjectIdGetDatum(typid),
927 if (HeapTupleIsValid(tp))
929 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
932 result = typtup->typstorage;
942 * Given a type OID, return the type's default value, if any.
944 * The result is a palloc'd expression node tree, or NULL if there
945 * is no defined default for the datatype.
947 * NB: caller should be prepared to coerce result to correct datatype;
948 * the returned expression tree might produce something of the wrong type.
951 get_typdefault(Oid typid)
959 typeTuple = SearchSysCache(TYPEOID,
960 ObjectIdGetDatum(typid),
962 if (!HeapTupleIsValid(typeTuple))
963 elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
964 type = (Form_pg_type) GETSTRUCT(typeTuple);
967 * typdefault and typdefaultbin are potentially null, so don't try to
968 * access 'em as struct fields. Must do it the hard way with
971 datum = SysCacheGetAttr(TYPEOID,
973 Anum_pg_type_typdefaultbin,
978 /* We have an expression default */
979 expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,
984 /* Perhaps we have a plain literal default */
985 datum = SysCacheGetAttr(TYPEOID,
987 Anum_pg_type_typdefault,
994 /* Convert text datum to C string */
995 strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
997 /* Convert C string to a value of the given type */
998 datum = OidFunctionCall3(type->typinput,
999 CStringGetDatum(strDefaultVal),
1000 ObjectIdGetDatum(type->typelem),
1002 /* Build a Const node containing the value */
1003 expr = (Node *) makeConst(typid,
1008 false, /* not a set */
1010 pfree(strDefaultVal);
1019 ReleaseSysCache(typeTuple);
1026 * If the given type is a domain, return its base type;
1027 * otherwise return the type's own OID.
1030 getBaseType(Oid typid)
1033 * We loop to find the bottom base type in a stack of domains.
1038 Form_pg_type typTup;
1040 tup = SearchSysCache(TYPEOID,
1041 ObjectIdGetDatum(typid),
1043 if (!HeapTupleIsValid(tup))
1044 elog(ERROR, "getBaseType: failed to lookup type %u", typid);
1045 typTup = (Form_pg_type) GETSTRUCT(tup);
1046 if (typTup->typtype != 'd')
1048 /* Not a domain, so done */
1049 ReleaseSysCache(tup);
1053 typid = typTup->typbasetype;
1054 ReleaseSysCache(tup);
1063 * Given a type OID and a typmod value (pass -1 if typmod is unknown),
1064 * estimate the average width of values of the type. This is used by
1065 * the planner, which doesn't require absolutely correct results;
1066 * it's OK (and expected) to guess if we don't know for sure.
1069 get_typavgwidth(Oid typid, int32 typmod)
1071 int typlen = get_typlen(typid);
1075 * Easy if it's a fixed-width type
1081 * type_maximum_size knows the encoding of typmod for some datatypes;
1082 * don't duplicate that knowledge here.
1084 maxwidth = type_maximum_size(typid, typmod);
1088 * For BPCHAR, the max width is also the only width. Otherwise we
1089 * need to guess about the typical data width given the max. A
1090 * sliding scale for percentage of max width seems reasonable.
1092 if (typid == BPCHAROID)
1095 return maxwidth; /* assume full width */
1096 if (maxwidth < 1000)
1097 return 32 + (maxwidth - 32) / 2; /* assume 50% */
1100 * Beyond 1000, assume we're looking at something like
1101 * "varchar(10000)" where the limit isn't actually reached often,
1102 * and use a fixed estimate.
1104 return 32 + (1000 - 32) / 2;
1108 * Ooops, we have no idea ... wild guess time.
1116 * Given the type OID, find if it is a basic type, a named relation
1117 * or the generic type 'relation'.
1118 * It returns the null char if the cache lookup fails...
1122 get_typtype(Oid typid)
1126 tp = SearchSysCache(TYPEOID,
1127 ObjectIdGetDatum(typid),
1129 if (HeapTupleIsValid(tp))
1131 Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
1134 result = typtup->typtype;
1135 ReleaseSysCache(tp);
1143 /* ---------- STATISTICS CACHE ---------- */
1148 * Given the table and attribute number of a column, get the average
1149 * width of entries in the column. Return zero if no data available.
1152 get_attavgwidth(Oid relid, AttrNumber attnum)
1156 tp = SearchSysCache(STATRELATT,
1157 ObjectIdGetDatum(relid),
1158 Int16GetDatum(attnum),
1160 if (HeapTupleIsValid(tp))
1162 int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
1164 ReleaseSysCache(tp);
1174 * Extract the contents of a "slot" of a pg_statistic tuple.
1175 * Returns TRUE if requested slot type was found, else FALSE.
1177 * Unlike other routines in this file, this takes a pointer to an
1178 * already-looked-up tuple in the pg_statistic cache. We do this since
1179 * most callers will want to extract more than one value from the cache
1180 * entry, and we don't want to repeat the cache lookup unnecessarily.
1182 * statstuple: pg_statistics tuple to be examined.
1183 * atttype: type OID of attribute.
1184 * atttypmod: typmod of attribute.
1185 * reqkind: STAKIND code for desired statistics slot kind.
1186 * reqop: STAOP value wanted, or InvalidOid if don't care.
1187 * values, nvalues: if not NULL, the slot's stavalues are extracted.
1188 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
1190 * If assigned, values and numbers are set to point to palloc'd arrays.
1191 * If the attribute type is pass-by-reference, the values referenced by
1192 * the values array are themselves palloc'd. The palloc'd stuff can be
1193 * freed by calling free_attstatsslot.
1196 get_attstatsslot(HeapTuple statstuple,
1197 Oid atttype, int32 atttypmod,
1198 int reqkind, Oid reqop,
1199 Datum **values, int *nvalues,
1200 float4 **numbers, int *nnumbers)
1202 Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
1207 ArrayType *statarray;
1209 HeapTuple typeTuple;
1213 for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
1215 if ((&stats->stakind1)[i] == reqkind &&
1216 (reqop == InvalidOid || (&stats->staop1)[i] == reqop))
1219 if (i >= STATISTIC_NUM_SLOTS)
1220 return false; /* not there */
1224 val = SysCacheGetAttr(STATRELATT, statstuple,
1225 Anum_pg_statistic_stavalues1 + i,
1228 elog(ERROR, "get_attstatsslot: stavalues is null");
1229 statarray = DatumGetArrayTypeP(val);
1232 * Do initial examination of the array. This produces a list of
1233 * text Datums --- ie, pointers into the text array value.
1235 deconstruct_array(statarray, false, -1, 'i', values, nvalues);
1236 narrayelem = *nvalues;
1239 * We now need to replace each text Datum by its internal
1242 * Get the type input proc and typelem for the column datatype.
1244 typeTuple = SearchSysCache(TYPEOID,
1245 ObjectIdGetDatum(atttype),
1247 if (!HeapTupleIsValid(typeTuple))
1248 elog(ERROR, "get_attstatsslot: Cache lookup failed for type %u",
1250 fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc);
1251 typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
1252 ReleaseSysCache(typeTuple);
1255 * Do the conversions. The palloc'd array of Datums is reused in
1258 for (j = 0; j < narrayelem; j++)
1262 strval = DatumGetCString(DirectFunctionCall1(textout,
1264 (*values)[j] = FunctionCall3(&inputproc,
1265 CStringGetDatum(strval),
1266 ObjectIdGetDatum(typelem),
1267 Int32GetDatum(atttypmod));
1272 * Free statarray if it's a detoasted copy.
1274 if ((Pointer) statarray != DatumGetPointer(val))
1280 val = SysCacheGetAttr(STATRELATT, statstuple,
1281 Anum_pg_statistic_stanumbers1 + i,
1284 elog(ERROR, "get_attstatsslot: stanumbers is null");
1285 statarray = DatumGetArrayTypeP(val);
1288 * We expect the array to be a 1-D float4 array; verify that. We
1289 * don't need to use deconstruct_array() since the array data is
1290 * just going to look like a C array of float4 values.
1292 narrayelem = ARR_DIMS(statarray)[0];
1293 if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
1294 ARR_SIZE(statarray) != (ARR_OVERHEAD(1) + narrayelem * sizeof(float4)))
1295 elog(ERROR, "get_attstatsslot: stanumbers is bogus");
1296 *numbers = (float4 *) palloc(narrayelem * sizeof(float4));
1297 memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
1298 *nnumbers = narrayelem;
1301 * Free statarray if it's a detoasted copy.
1303 if ((Pointer) statarray != DatumGetPointer(val))
1311 free_attstatsslot(Oid atttype,
1312 Datum *values, int nvalues,
1313 float4 *numbers, int nnumbers)
1317 if (!get_typbyval(atttype))
1321 for (i = 0; i < nvalues; i++)
1322 pfree(DatumGetPointer(values[i]));
1330 /* ---------- PG_NAMESPACE CACHE ---------- */
1333 * get_namespace_name
1334 * Returns the name of a given namespace
1336 * Returns a palloc'd copy of the string, or NULL if no such namespace.
1339 get_namespace_name(Oid nspid)
1343 tp = SearchSysCache(NAMESPACEOID,
1344 ObjectIdGetDatum(nspid),
1346 if (HeapTupleIsValid(tp))
1348 Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);
1351 result = pstrdup(NameStr(nsptup->nspname));
1352 ReleaseSysCache(tp);
1359 /* ---------- PG_SHADOW CACHE ---------- */
1364 * Given a user name, look up the user's sysid.
1365 * Raises an error if no such user (rather than returning zero,
1366 * which might possibly be a valid usesysid).
1368 * Note: the type of usesysid is currently int4, but may change to Oid
1369 * someday. It'd be reasonable to return zero on failure if we were
1373 get_usesysid(const char *username)
1378 userTup = SearchSysCache(SHADOWNAME,
1379 PointerGetDatum(username),
1381 if (!HeapTupleIsValid(userTup))
1382 elog(ERROR, "user \"%s\" does not exist", username);
1384 result = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
1386 ReleaseSysCache(userTup);