PostgreSQL Source Code git master
Loading...
Searching...
No Matches
objectaddress.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * objectaddress.c
4 * functions for working with ObjectAddresses
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/catalog/objectaddress.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include "access/genam.h"
19#include "access/htup_details.h"
20#include "access/relation.h"
21#include "access/table.h"
22#include "catalog/catalog.h"
24#include "catalog/pg_am.h"
25#include "catalog/pg_amop.h"
26#include "catalog/pg_amproc.h"
27#include "catalog/pg_attrdef.h"
28#include "catalog/pg_authid.h"
30#include "catalog/pg_cast.h"
34#include "catalog/pg_database.h"
40#include "catalog/pg_language.h"
44#include "catalog/pg_opclass.h"
45#include "catalog/pg_operator.h"
46#include "catalog/pg_opfamily.h"
48#include "catalog/pg_policy.h"
49#include "catalog/pg_proc.h"
58#include "catalog/pg_rewrite.h"
63#include "catalog/pg_trigger.h"
65#include "catalog/pg_ts_dict.h"
68#include "catalog/pg_type.h"
70#include "commands/defrem.h"
72#include "commands/extension.h"
73#include "commands/policy.h"
74#include "commands/proclang.h"
75#include "commands/tablespace.h"
76#include "commands/trigger.h"
77#include "foreign/foreign.h"
78#include "funcapi.h"
79#include "miscadmin.h"
80#include "parser/parse_func.h"
81#include "parser/parse_oper.h"
82#include "parser/parse_type.h"
85#include "storage/lmgr.h"
86#include "storage/sinval.h"
87#include "utils/acl.h"
88#include "utils/builtins.h"
89#include "utils/fmgroids.h"
90#include "utils/lsyscache.h"
91#include "utils/memutils.h"
92#include "utils/regproc.h"
93#include "utils/syscache.h"
94
95/*
96 * ObjectProperty
97 *
98 * This array provides a common part of system object structure; to help
99 * consolidate routines to handle various kind of object classes.
100 */
101typedef struct
102{
103 const char *class_descr; /* string describing the catalog, for internal
104 * error messages */
105 Oid class_oid; /* oid of catalog */
106 Oid oid_index_oid; /* oid of index on system oid column */
107 SysCacheIdentifier oid_catcache_id; /* id of catcache on system oid column */
109 * (name,namespace), or (name) if
110 * the object does not live in a
111 * namespace */
112 AttrNumber attnum_oid; /* attribute number of oid column */
113 AttrNumber attnum_name; /* attnum of name field */
114 AttrNumber attnum_namespace; /* attnum of namespace field */
115 AttrNumber attnum_owner; /* attnum of owner field */
116 AttrNumber attnum_acl; /* attnum of acl field */
117 ObjectType objtype; /* OBJECT_* of this object type */
118 bool is_nsp_name_unique; /* can the nsp/name combination (or name
119 * alone, if there's no namespace) be
120 * considered a unique identifier for an
121 * object of this class? */
123
125{
126 {
127 "access method",
130 AMOID,
131 AMNAME,
138 true
139 },
140 {
141 "access method operator",
152 false
153 },
154 {
155 "access method procedure",
166 false
167 },
168 {
169 "cast",
180 false
181 },
182 {
183 "collation",
186 COLLOID,
187 SYSCACHEID_INVALID, /* COLLNAMEENCNSP also takes encoding */
194 true
195 },
196 {
197 "constraint",
200 CONSTROID,
207 -1,
208 false
209 },
210 {
211 "conversion",
214 CONVOID,
222 true
223 },
224 {
225 "database",
236 true
237 },
238 {
239 "default ACL",
250 false
251 },
252 {
253 "extension",
260 InvalidAttrNumber, /* extension doesn't belong to extnamespace */
264 true
265 },
266 {
267 "foreign-data wrapper",
278 true
279 },
280 {
281 "foreign server",
292 true
293 },
294 {
295 "function",
298 PROCOID,
299 SYSCACHEID_INVALID, /* PROCNAMEARGSNSP also takes argument types */
306 false
307 },
308 {
309 "language",
312 LANGOID,
313 LANGNAME,
320 true
321 },
322 {
323 "large object metadata",
334 false
335 },
336 {
337 "operator class",
340 CLAOID,
341 SYSCACHEID_INVALID, /* CLAAMNAMENSP also takes opcmethod */
348 true
349 },
350 {
351 "operator",
354 OPEROID,
355 SYSCACHEID_INVALID, /* OPERNAMENSP also takes left and right type */
362 false
363 },
364 {
365 "operator family",
369 SYSCACHEID_INVALID, /* OPFAMILYAMNAMENSP also takes opfmethod */
376 true
377 },
378 {
379 "property graph element",
389 -1,
390 false
391 },
392 {
393 "property graph element label",
396 -1,
397 -1,
403 -1,
404 false
405 },
406 {
407 "property graph label",
417 -1,
418 false
419 },
420 {
421 "property graph label property",
424 -1,
425 -1,
431 -1,
432 false
433 },
434 {
435 "property graph property",
438 -1,
445 -1,
446 false
447 },
448 {
449 "role",
452 AUTHOID,
453 AUTHNAME,
460 true
461 },
462 {
463 "role membership",
473 -1,
474 true
475 },
476 {
477 "rule",
488 false
489 },
490 {
491 "schema",
502 true
503 },
504 {
505 "relation",
508 RELOID,
516 true
517 },
518 {
519 "tablespace",
530 true
531 },
532 {
533 "transform",
536 TRFOID,
544 false
545 },
546 {
547 "trigger",
558 false
559 },
560 {
561 "policy",
572 false
573 },
574 {
575 "event trigger",
586 true
587 },
588 {
589 "text search configuration",
600 true
601 },
602 {
603 "text search dictionary",
606 TSDICTOID,
614 true
615 },
616 {
617 "text search parser",
628 true
629 },
630 {
631 "text search template",
642 true,
643 },
644 {
645 "type",
648 TYPEOID,
656 true
657 },
658 {
659 "publication",
670 true
671 },
672 {
673 "subscription",
684 true
685 },
686 {
687 "extended statistics",
696 InvalidAttrNumber, /* no ACL (same as relation) */
698 true
699 },
700 {
701 "user mapping",
712 false
713 },
714};
715
716/*
717 * This struct maps the string object types as returned by
718 * getObjectTypeDescription into ObjectType enum values. Note that some enum
719 * values can be obtained by different names, and that some string object types
720 * do not have corresponding values in the output enum. The user of this map
721 * must be careful to test for invalid values being returned.
722 *
723 * To ease maintenance, this follows the order of getObjectTypeDescription.
724 */
725static const struct object_type_map
726{
727 const char *tm_name;
729}
730
731 ObjectTypeMap[] =
732{
733 {
734 "table", OBJECT_TABLE
735 },
736 {
737 "index", OBJECT_INDEX
738 },
739 {
740 "sequence", OBJECT_SEQUENCE
741 },
742 {
743 "toast table", -1
744 }, /* unmapped */
745 {
746 "view", OBJECT_VIEW
747 },
748 {
749 "materialized view", OBJECT_MATVIEW
750 },
751 {
752 "composite type", -1
753 }, /* unmapped */
754 {
755 "foreign table", OBJECT_FOREIGN_TABLE
756 },
757 {
758 "property graph", OBJECT_PROPGRAPH
759 },
760 {
761 "table column", OBJECT_COLUMN
762 },
763 {
764 "index column", -1
765 }, /* unmapped */
766 {
767 "sequence column", -1
768 }, /* unmapped */
769 {
770 "toast table column", -1
771 }, /* unmapped */
772 {
773 "view column", -1
774 }, /* unmapped */
775 {
776 "materialized view column", -1
777 }, /* unmapped */
778 {
779 "composite type column", -1
780 }, /* unmapped */
781 {
782 "foreign table column", OBJECT_COLUMN
783 },
784 {
785 "aggregate", OBJECT_AGGREGATE
786 },
787 {
788 "function", OBJECT_FUNCTION
789 },
790 {
791 "procedure", OBJECT_PROCEDURE
792 },
793 {
794 "type", OBJECT_TYPE
795 },
796 {
797 "cast", OBJECT_CAST
798 },
799 {
800 "collation", OBJECT_COLLATION
801 },
802 {
803 "table constraint", OBJECT_TABCONSTRAINT
804 },
805 {
806 "domain constraint", OBJECT_DOMCONSTRAINT
807 },
808 {
809 "conversion", OBJECT_CONVERSION
810 },
811 {
812 "default value", OBJECT_DEFAULT
813 },
814 {
815 "language", OBJECT_LANGUAGE
816 },
817 {
818 "large object", OBJECT_LARGEOBJECT
819 },
820 {
821 "operator", OBJECT_OPERATOR
822 },
823 {
824 "operator class", OBJECT_OPCLASS
825 },
826 {
827 "operator family", OBJECT_OPFAMILY
828 },
829 {
830 "access method", OBJECT_ACCESS_METHOD
831 },
832 {
833 "operator of access method", OBJECT_AMOP
834 },
835 {
836 "function of access method", OBJECT_AMPROC
837 },
838 {
839 "rule", OBJECT_RULE
840 },
841 {
842 "trigger", OBJECT_TRIGGER
843 },
844 {
845 "schema", OBJECT_SCHEMA
846 },
847 {
848 "text search parser", OBJECT_TSPARSER
849 },
850 {
851 "text search dictionary", OBJECT_TSDICTIONARY
852 },
853 {
854 "text search template", OBJECT_TSTEMPLATE
855 },
856 {
857 "text search configuration", OBJECT_TSCONFIGURATION
858 },
859 {
860 "role", OBJECT_ROLE
861 },
862 {
863 "role membership", -1 /* unmapped */
864 },
865 {
866 "database", OBJECT_DATABASE
867 },
868 {
869 "tablespace", OBJECT_TABLESPACE
870 },
871 {
872 "foreign-data wrapper", OBJECT_FDW
873 },
874 {
875 "server", OBJECT_FOREIGN_SERVER
876 },
877 {
878 "user mapping", OBJECT_USER_MAPPING
879 },
880 {
881 "default acl", OBJECT_DEFACL
882 },
883 {
884 "extension", OBJECT_EXTENSION
885 },
886 {
887 "event trigger", OBJECT_EVENT_TRIGGER
888 },
889 {
890 "parameter ACL", OBJECT_PARAMETER_ACL
891 },
892 {
893 "policy", OBJECT_POLICY
894 },
895 {
896 "property graph element", -1
897 },
898 {
899 "property graph label", -1
900 },
901 {
902 "property graph property", -1
903 },
904 {
905 "publication", OBJECT_PUBLICATION
906 },
907 {
908 "publication namespace", OBJECT_PUBLICATION_NAMESPACE
909 },
910 {
911 "publication relation", OBJECT_PUBLICATION_REL
912 },
913 {
914 "subscription", OBJECT_SUBSCRIPTION
915 },
916 {
917 "transform", OBJECT_TRANSFORM
918 },
919 {
920 "statistics object", OBJECT_STATISTIC_EXT
921 }
923
925{
928 0
929};
930
932 String *strval, bool missing_ok);
934 List *object, Relation *relp,
935 LOCKMODE lockmode, bool missing_ok);
937 List *object, Relation *relp, bool missing_ok);
939 List *object, Relation *relp,
940 LOCKMODE lockmode, bool missing_ok);
942 List *object, Relation *relp, LOCKMODE lockmode,
943 bool missing_ok);
945 TypeName *typename, bool missing_ok);
947 bool missing_ok);
949 List *object, bool missing_ok);
950
952 bool missing_ok);
954 Relation *relp,
955 bool missing_ok);
957 bool missing_ok);
959 bool missing_ok);
961
962static void getRelationDescription(StringInfo buffer, Oid relid,
963 bool missing_ok);
964static void getOpFamilyDescription(StringInfo buffer, Oid opfid,
965 bool missing_ok);
966static void getRelationTypeDescription(StringInfo buffer, Oid relid,
967 int32 objectSubId, bool missing_ok);
968static void getProcedureTypeDescription(StringInfo buffer, Oid procid,
969 bool missing_ok);
971 bool missing_ok);
972static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
973 bool missing_ok);
974static void getRelationIdentity(StringInfo buffer, Oid relid, List **object,
975 bool missing_ok);
976
977/*
978 * Translate an object name and arguments (as passed by the parser) to an
979 * ObjectAddress.
980 *
981 * The returned object will be locked using the specified lockmode. If a
982 * sub-object is looked up, the parent object will be locked instead.
983 *
984 * If the object is a relation or a child object of a relation (e.g. an
985 * attribute or constraint), the relation is also opened and *relp receives
986 * the open relcache entry pointer; otherwise, *relp is set to NULL.
987 * (relp can be NULL if the caller never passes a relation-related object.) This
988 * is a bit grotty but it makes life simpler, since the caller will
989 * typically need the relcache entry too. Caller must close the relcache
990 * entry when done with it. The relation is locked with the specified lockmode
991 * if the target object is the relation itself or an attribute, but for other
992 * child objects, only AccessShareLock is acquired on the relation.
993 *
994 * If the object is not found, an error is thrown, unless missing_ok is
995 * true. In this case, no lock is acquired, relp is set to NULL, and the
996 * returned address has objectId set to InvalidOid.
997 *
998 * We don't currently provide a function to release the locks acquired here;
999 * typically, the lock must be held until commit to guard against a concurrent
1000 * drop operation.
1001 *
1002 * Note: If the object is not found, we don't give any indication of the
1003 * reason. (It might have been a missing schema if the name was qualified, or
1004 * a nonexistent type name in case of a cast, function or operator; etc).
1005 * Currently there is only one caller that might be interested in such info, so
1006 * we don't spend much effort here. If more callers start to care, it might be
1007 * better to add some support for that in this function.
1008 */
1011 Relation *relp, LOCKMODE lockmode, bool missing_ok)
1012{
1013 ObjectAddress address = {InvalidOid, InvalidOid, 0};
1015 Relation relation = NULL;
1017
1018 /* Some kind of lock must be taken. */
1019 Assert(lockmode != NoLock);
1020
1021 for (;;)
1022 {
1023 /*
1024 * Remember this value, so that, after looking up the object name and
1025 * locking it, we can check whether any invalidation messages have
1026 * been processed that might require a do-over.
1027 */
1029
1030 /* Look up object address. */
1031 switch (objtype)
1032 {
1033 case OBJECT_INDEX:
1034 case OBJECT_SEQUENCE:
1035 case OBJECT_TABLE:
1036 case OBJECT_VIEW:
1037 case OBJECT_MATVIEW:
1039 case OBJECT_PROPGRAPH:
1040 address =
1042 &relation, lockmode,
1043 missing_ok);
1044 break;
1045 case OBJECT_ATTRIBUTE:
1046 case OBJECT_COLUMN:
1047 address =
1048 get_object_address_attribute(objtype, castNode(List, object),
1049 &relation, lockmode,
1050 missing_ok);
1051 break;
1052 case OBJECT_DEFAULT:
1053 address =
1054 get_object_address_attrdef(objtype, castNode(List, object),
1055 &relation, lockmode,
1056 missing_ok);
1057 break;
1058 case OBJECT_RULE:
1059 case OBJECT_TRIGGER:
1061 case OBJECT_POLICY:
1062 address = get_object_address_relobject(objtype, castNode(List, object),
1063 &relation, missing_ok);
1064 break;
1066 {
1067 List *objlist;
1069 char *constrname;
1070
1071 objlist = castNode(List, object);
1074 missing_ok);
1076
1077 address.classId = ConstraintRelationId;
1078 address.objectId = get_domain_constraint_oid(domaddr.objectId,
1079 constrname, missing_ok);
1080 address.objectSubId = 0;
1081 }
1082 break;
1083 case OBJECT_DATABASE:
1084 case OBJECT_EXTENSION:
1085 case OBJECT_TABLESPACE:
1086 case OBJECT_ROLE:
1087 case OBJECT_SCHEMA:
1088 case OBJECT_LANGUAGE:
1089 case OBJECT_FDW:
1094 case OBJECT_PUBLICATION:
1096 address = get_object_address_unqualified(objtype,
1097 castNode(String, object), missing_ok);
1098 break;
1099 case OBJECT_TYPE:
1100 case OBJECT_DOMAIN:
1101 address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
1102 break;
1103 case OBJECT_AGGREGATE:
1104 case OBJECT_FUNCTION:
1105 case OBJECT_PROCEDURE:
1106 case OBJECT_ROUTINE:
1107 address.classId = ProcedureRelationId;
1108 address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
1109 address.objectSubId = 0;
1110 break;
1111 case OBJECT_OPERATOR:
1112 address.classId = OperatorRelationId;
1113 address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
1114 address.objectSubId = 0;
1115 break;
1116 case OBJECT_COLLATION:
1117 address.classId = CollationRelationId;
1118 address.objectId = get_collation_oid(castNode(List, object), missing_ok);
1119 address.objectSubId = 0;
1120 break;
1121 case OBJECT_CONVERSION:
1122 address.classId = ConversionRelationId;
1123 address.objectId = get_conversion_oid(castNode(List, object), missing_ok);
1124 address.objectSubId = 0;
1125 break;
1126 case OBJECT_OPCLASS:
1127 case OBJECT_OPFAMILY:
1128 address = get_object_address_opcf(objtype, castNode(List, object), missing_ok);
1129 break;
1130 case OBJECT_AMOP:
1131 case OBJECT_AMPROC:
1132 address = get_object_address_opf_member(objtype, castNode(List, object), missing_ok);
1133 break;
1134 case OBJECT_LARGEOBJECT:
1136 address.objectId = oidparse(object);
1137 address.objectSubId = 0;
1138 if (!LargeObjectExists(address.objectId))
1139 {
1140 if (!missing_ok)
1141 ereport(ERROR,
1143 errmsg("large object %u does not exist",
1144 address.objectId)));
1145 }
1146 break;
1147 case OBJECT_CAST:
1148 {
1149 TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
1150 TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
1153
1154 sourcetypeid = LookupTypeNameOid(NULL, sourcetype, missing_ok);
1155 targettypeid = LookupTypeNameOid(NULL, targettype, missing_ok);
1156 address.classId = CastRelationId;
1157 address.objectId =
1159 address.objectSubId = 0;
1160 }
1161 break;
1162 case OBJECT_TRANSFORM:
1163 {
1164 TypeName *typename = linitial_node(TypeName, castNode(List, object));
1165 char *langname = strVal(lsecond(castNode(List, object)));
1166 Oid type_id = LookupTypeNameOid(NULL, typename, missing_ok);
1167 Oid lang_id = get_language_oid(langname, missing_ok);
1168
1169 address.classId = TransformRelationId;
1170 address.objectId =
1171 get_transform_oid(type_id, lang_id, missing_ok);
1172 address.objectSubId = 0;
1173 }
1174 break;
1175 case OBJECT_TSPARSER:
1176 address.classId = TSParserRelationId;
1177 address.objectId = get_ts_parser_oid(castNode(List, object), missing_ok);
1178 address.objectSubId = 0;
1179 break;
1182 address.objectId = get_ts_dict_oid(castNode(List, object), missing_ok);
1183 address.objectSubId = 0;
1184 break;
1185 case OBJECT_TSTEMPLATE:
1186 address.classId = TSTemplateRelationId;
1187 address.objectId = get_ts_template_oid(castNode(List, object), missing_ok);
1188 address.objectSubId = 0;
1189 break;
1191 address.classId = TSConfigRelationId;
1192 address.objectId = get_ts_config_oid(castNode(List, object), missing_ok);
1193 address.objectSubId = 0;
1194 break;
1196 address = get_object_address_usermapping(castNode(List, object),
1197 missing_ok);
1198 break;
1201 missing_ok);
1202 break;
1205 &relation,
1206 missing_ok);
1207 break;
1208 case OBJECT_DEFACL:
1209 address = get_object_address_defacl(castNode(List, object),
1210 missing_ok);
1211 break;
1215 missing_ok);
1216 address.objectSubId = 0;
1217 break;
1218 /* no default, to let compiler warn about missing case */
1219 }
1220
1221 if (!address.classId)
1222 elog(ERROR, "unrecognized object type: %d", (int) objtype);
1223
1224 /*
1225 * If we could not find the supplied object, return without locking.
1226 */
1227 if (!OidIsValid(address.objectId))
1228 {
1229 Assert(missing_ok);
1230 return address;
1231 }
1232
1233 /*
1234 * If we're retrying, see if we got the same answer as last time. If
1235 * so, we're done; if not, we locked the wrong thing, so give up our
1236 * lock.
1237 */
1238 if (OidIsValid(old_address.classId))
1239 {
1240 if (old_address.classId == address.classId
1241 && old_address.objectId == address.objectId
1242 && old_address.objectSubId == address.objectSubId)
1243 break;
1244 if (old_address.classId != RelationRelationId)
1245 {
1246 if (IsSharedRelation(old_address.classId))
1248 old_address.objectId,
1249 0, lockmode);
1250 else
1252 old_address.objectId,
1253 0, lockmode);
1254 }
1255 }
1256
1257 /*
1258 * If we're dealing with a relation or attribute, then the relation is
1259 * already locked. Otherwise, we lock it now.
1260 */
1261 if (address.classId != RelationRelationId)
1262 {
1263 if (IsSharedRelation(address.classId))
1264 LockSharedObject(address.classId, address.objectId, 0,
1265 lockmode);
1266 else
1267 LockDatabaseObject(address.classId, address.objectId, 0,
1268 lockmode);
1269 }
1270
1271 /*
1272 * At this point, we've resolved the name to an OID and locked the
1273 * corresponding database object. However, it's possible that by the
1274 * time we acquire the lock on the object, concurrent DDL has modified
1275 * the database in such a way that the name we originally looked up no
1276 * longer resolves to that OID.
1277 *
1278 * We can be certain that this isn't an issue if (a) no shared
1279 * invalidation messages have been processed or (b) we've locked a
1280 * relation somewhere along the line. All the relation name lookups
1281 * in this module ultimately use RangeVarGetRelid() to acquire a
1282 * relation lock, and that function protects against the same kinds of
1283 * races we're worried about here. Even when operating on a
1284 * constraint, rule, or trigger, we still acquire AccessShareLock on
1285 * the relation, which is enough to freeze out any concurrent DDL.
1286 *
1287 * In all other cases, however, it's possible that the name we looked
1288 * up no longer refers to the object we locked, so we retry the lookup
1289 * and see whether we get the same answer.
1290 */
1291 if (inval_count == SharedInvalidMessageCounter || relation != NULL)
1292 break;
1293 old_address = address;
1294 }
1295
1296 /* relp must be given if it's a relation */
1297 Assert(!relation || relp);
1298
1299 /* Return the object address and the relation. */
1300 if (relp)
1301 *relp = relation;
1302 return address;
1303}
1304
1305/*
1306 * Return an ObjectAddress based on a RangeVar and an object name. The
1307 * name of the relation identified by the RangeVar is prepended to the
1308 * (possibly empty) list passed in as object. This is useful to find
1309 * the ObjectAddress of objects that depend on a relation. All other
1310 * considerations are exactly as for get_object_address above.
1311 */
1314 Relation *relp, LOCKMODE lockmode,
1315 bool missing_ok)
1316{
1317 if (rel)
1318 {
1319 object = lcons(makeString(rel->relname), object);
1320 if (rel->schemaname)
1321 object = lcons(makeString(rel->schemaname), object);
1322 if (rel->catalogname)
1323 object = lcons(makeString(rel->catalogname), object);
1324 }
1325
1326 return get_object_address(objtype, (Node *) object,
1327 relp, lockmode, missing_ok);
1328}
1329
1330/*
1331 * Find an ObjectAddress for a type of object that is identified by an
1332 * unqualified name.
1333 */
1334static ObjectAddress
1336 String *strval, bool missing_ok)
1337{
1338 const char *name;
1339 ObjectAddress address;
1340
1341 name = strVal(strval);
1342
1343 /* Translate name to OID. */
1344 switch (objtype)
1345 {
1348 address.objectId = get_am_oid(name, missing_ok);
1349 address.objectSubId = 0;
1350 break;
1351 case OBJECT_DATABASE:
1352 address.classId = DatabaseRelationId;
1353 address.objectId = get_database_oid(name, missing_ok);
1354 address.objectSubId = 0;
1355 break;
1356 case OBJECT_EXTENSION:
1357 address.classId = ExtensionRelationId;
1358 address.objectId = get_extension_oid(name, missing_ok);
1359 address.objectSubId = 0;
1360 break;
1361 case OBJECT_TABLESPACE:
1362 address.classId = TableSpaceRelationId;
1363 address.objectId = get_tablespace_oid(name, missing_ok);
1364 address.objectSubId = 0;
1365 break;
1366 case OBJECT_ROLE:
1367 address.classId = AuthIdRelationId;
1368 address.objectId = get_role_oid(name, missing_ok);
1369 address.objectSubId = 0;
1370 break;
1371 case OBJECT_SCHEMA:
1372 address.classId = NamespaceRelationId;
1373 address.objectId = get_namespace_oid(name, missing_ok);
1374 address.objectSubId = 0;
1375 break;
1376 case OBJECT_LANGUAGE:
1377 address.classId = LanguageRelationId;
1378 address.objectId = get_language_oid(name, missing_ok);
1379 address.objectSubId = 0;
1380 break;
1381 case OBJECT_FDW:
1383 address.objectId = get_foreign_data_wrapper_oid(name, missing_ok);
1384 address.objectSubId = 0;
1385 break;
1388 address.objectId = get_foreign_server_oid(name, missing_ok);
1389 address.objectSubId = 0;
1390 break;
1393 address.objectId = get_event_trigger_oid(name, missing_ok);
1394 address.objectSubId = 0;
1395 break;
1398 address.objectId = ParameterAclLookup(name, missing_ok);
1399 address.objectSubId = 0;
1400 break;
1401 case OBJECT_PUBLICATION:
1403 address.objectId = get_publication_oid(name, missing_ok);
1404 address.objectSubId = 0;
1405 break;
1408 address.objectId = get_subscription_oid(name, missing_ok);
1409 address.objectSubId = 0;
1410 break;
1411 default:
1412 elog(ERROR, "unrecognized object type: %d", (int) objtype);
1413 /* placate compiler, which doesn't know elog won't return */
1414 address.classId = InvalidOid;
1415 address.objectId = InvalidOid;
1416 address.objectSubId = 0;
1417 }
1418
1419 return address;
1420}
1421
1422/*
1423 * Locate a relation by qualified name.
1424 */
1425static ObjectAddress
1427 Relation *relp, LOCKMODE lockmode,
1428 bool missing_ok)
1429{
1430 Relation relation;
1431 ObjectAddress address;
1432
1433 address.classId = RelationRelationId;
1434 address.objectId = InvalidOid;
1435 address.objectSubId = 0;
1436
1438 lockmode, missing_ok);
1439 if (!relation)
1440 return address;
1441
1442 switch (objtype)
1443 {
1444 case OBJECT_INDEX:
1445 if (relation->rd_rel->relkind != RELKIND_INDEX &&
1446 relation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
1447 ereport(ERROR,
1449 errmsg("\"%s\" is not an index",
1450 RelationGetRelationName(relation))));
1451 break;
1452 case OBJECT_PROPGRAPH:
1453 if (relation->rd_rel->relkind != RELKIND_PROPGRAPH)
1454 ereport(ERROR,
1456 errmsg("\"%s\" is not a property graph",
1457 RelationGetRelationName(relation))));
1458 break;
1459 case OBJECT_SEQUENCE:
1460 if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
1461 ereport(ERROR,
1463 errmsg("\"%s\" is not a sequence",
1464 RelationGetRelationName(relation))));
1465 break;
1466 case OBJECT_TABLE:
1467 if (relation->rd_rel->relkind != RELKIND_RELATION &&
1468 relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1469 ereport(ERROR,
1471 errmsg("\"%s\" is not a table",
1472 RelationGetRelationName(relation))));
1473 break;
1474 case OBJECT_VIEW:
1475 if (relation->rd_rel->relkind != RELKIND_VIEW)
1476 ereport(ERROR,
1478 errmsg("\"%s\" is not a view",
1479 RelationGetRelationName(relation))));
1480 break;
1481 case OBJECT_MATVIEW:
1482 if (relation->rd_rel->relkind != RELKIND_MATVIEW)
1483 ereport(ERROR,
1485 errmsg("\"%s\" is not a materialized view",
1486 RelationGetRelationName(relation))));
1487 break;
1489 if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
1490 ereport(ERROR,
1492 errmsg("\"%s\" is not a foreign table",
1493 RelationGetRelationName(relation))));
1494 break;
1495 default:
1496 elog(ERROR, "unrecognized object type: %d", (int) objtype);
1497 break;
1498 }
1499
1500 /* Done. */
1501 address.objectId = RelationGetRelid(relation);
1502 *relp = relation;
1503
1504 return address;
1505}
1506
1507/*
1508 * Find object address for an object that is attached to a relation.
1509 *
1510 * Note that we take only an AccessShareLock on the relation. We need not
1511 * pass down the LOCKMODE from get_object_address(), because that is the lock
1512 * mode for the object itself, not the relation to which it is attached.
1513 */
1514static ObjectAddress
1516 Relation *relp, bool missing_ok)
1517{
1518 ObjectAddress address;
1519 Relation relation = NULL;
1520 int nnames;
1521 const char *depname;
1522 List *relname;
1523 Oid reloid;
1524
1525 /* Extract name of dependent object. */
1526 depname = strVal(llast(object));
1527
1528 /* Separate relation name from dependent object name. */
1529 nnames = list_length(object);
1530 if (nnames < 2)
1531 ereport(ERROR,
1533 errmsg("must specify relation and object name")));
1534
1535 /* Extract relation name and open relation. */
1536 relname = list_copy_head(object, nnames - 1);
1539 missing_ok);
1540
1541 reloid = relation ? RelationGetRelid(relation) : InvalidOid;
1542
1543 switch (objtype)
1544 {
1545 case OBJECT_RULE:
1546 address.classId = RewriteRelationId;
1547 address.objectId = relation ?
1548 get_rewrite_oid(reloid, depname, missing_ok) : InvalidOid;
1549 address.objectSubId = 0;
1550 break;
1551 case OBJECT_TRIGGER:
1552 address.classId = TriggerRelationId;
1553 address.objectId = relation ?
1554 get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
1555 address.objectSubId = 0;
1556 break;
1558 address.classId = ConstraintRelationId;
1559 address.objectId = relation ?
1560 get_relation_constraint_oid(reloid, depname, missing_ok) :
1561 InvalidOid;
1562 address.objectSubId = 0;
1563 break;
1564 case OBJECT_POLICY:
1565 address.classId = PolicyRelationId;
1566 address.objectId = relation ?
1567 get_relation_policy_oid(reloid, depname, missing_ok) :
1568 InvalidOid;
1569 address.objectSubId = 0;
1570 break;
1571 default:
1572 elog(ERROR, "unrecognized object type: %d", (int) objtype);
1573 }
1574
1575 /* Avoid relcache leak when object not found. */
1576 if (!OidIsValid(address.objectId))
1577 {
1578 if (relation != NULL)
1579 table_close(relation, AccessShareLock);
1580
1581 relation = NULL; /* department of accident prevention */
1582 return address;
1583 }
1584
1585 /* Done. */
1586 *relp = relation;
1587 return address;
1588}
1589
1590/*
1591 * Find the ObjectAddress for an attribute.
1592 */
1593static ObjectAddress
1595 Relation *relp, LOCKMODE lockmode,
1596 bool missing_ok)
1597{
1598 ObjectAddress address;
1599 List *relname;
1600 Oid reloid;
1601 Relation relation;
1602 const char *attname;
1604
1605 /* Extract relation name and open relation. */
1606 if (list_length(object) < 2)
1607 ereport(ERROR,
1609 errmsg("column name must be qualified")));
1610 attname = strVal(llast(object));
1611 relname = list_copy_head(object, list_length(object) - 1);
1612 /* XXX no missing_ok support here */
1613 relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
1614 reloid = RelationGetRelid(relation);
1615
1616 /* Look up attribute and construct return value. */
1617 attnum = get_attnum(reloid, attname);
1619 {
1620 if (!missing_ok)
1621 ereport(ERROR,
1623 errmsg("column \"%s\" of relation \"%s\" does not exist",
1625
1626 address.classId = RelationRelationId;
1627 address.objectId = InvalidOid;
1629 relation_close(relation, lockmode);
1630 return address;
1631 }
1632
1633 address.classId = RelationRelationId;
1634 address.objectId = reloid;
1635 address.objectSubId = attnum;
1636
1637 *relp = relation;
1638 return address;
1639}
1640
1641/*
1642 * Find the ObjectAddress for an attribute's default value.
1643 */
1644static ObjectAddress
1646 Relation *relp, LOCKMODE lockmode,
1647 bool missing_ok)
1648{
1649 ObjectAddress address;
1650 List *relname;
1651 Oid reloid;
1652 Relation relation;
1653 const char *attname;
1655 TupleDesc tupdesc;
1656 Oid defoid;
1657
1658 /* Extract relation name and open relation. */
1659 if (list_length(object) < 2)
1660 ereport(ERROR,
1662 errmsg("column name must be qualified")));
1663 attname = strVal(llast(object));
1664 relname = list_copy_head(object, list_length(object) - 1);
1665 /* XXX no missing_ok support here */
1666 relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
1667 reloid = RelationGetRelid(relation);
1668
1669 tupdesc = RelationGetDescr(relation);
1670
1671 /* Look up attribute number and fetch the pg_attrdef OID */
1672 attnum = get_attnum(reloid, attname);
1674 if (attnum != InvalidAttrNumber && tupdesc->constr != NULL)
1675 defoid = GetAttrDefaultOid(reloid, attnum);
1676 if (!OidIsValid(defoid))
1677 {
1678 if (!missing_ok)
1679 ereport(ERROR,
1681 errmsg("default value for column \"%s\" of relation \"%s\" does not exist",
1683
1685 address.objectId = InvalidOid;
1687 relation_close(relation, lockmode);
1688 return address;
1689 }
1690
1692 address.objectId = defoid;
1693 address.objectSubId = 0;
1694
1695 *relp = relation;
1696 return address;
1697}
1698
1699/*
1700 * Find the ObjectAddress for a type or domain
1701 */
1702static ObjectAddress
1703get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
1704{
1705 ObjectAddress address;
1706 Type tup;
1707
1708 address.classId = TypeRelationId;
1709 address.objectId = InvalidOid;
1710 address.objectSubId = 0;
1711
1712 tup = LookupTypeName(NULL, typename, NULL, missing_ok);
1713 if (!HeapTupleIsValid(tup))
1714 {
1715 if (!missing_ok)
1716 ereport(ERROR,
1718 errmsg("type \"%s\" does not exist",
1719 TypeNameToString(typename))));
1720 return address;
1721 }
1722 address.objectId = typeTypeId(tup);
1723
1724 if (objtype == OBJECT_DOMAIN)
1725 {
1726 if (((Form_pg_type) GETSTRUCT(tup))->typtype != TYPTYPE_DOMAIN)
1727 ereport(ERROR,
1729 errmsg("\"%s\" is not a domain",
1730 TypeNameToString(typename))));
1731 }
1732
1734
1735 return address;
1736}
1737
1738/*
1739 * Find the ObjectAddress for an opclass or opfamily.
1740 */
1741static ObjectAddress
1742get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
1743{
1744 Oid amoid;
1745 ObjectAddress address;
1746
1747 /* XXX no missing_ok support here */
1748 amoid = get_index_am_oid(strVal(linitial(object)), false);
1749 object = list_copy_tail(object, 1);
1750
1751 switch (objtype)
1752 {
1753 case OBJECT_OPCLASS:
1755 address.objectId = get_opclass_oid(amoid, object, missing_ok);
1756 address.objectSubId = 0;
1757 break;
1758 case OBJECT_OPFAMILY:
1760 address.objectId = get_opfamily_oid(amoid, object, missing_ok);
1761 address.objectSubId = 0;
1762 break;
1763 default:
1764 elog(ERROR, "unrecognized object type: %d", (int) objtype);
1765 /* placate compiler, which doesn't know elog won't return */
1766 address.classId = InvalidOid;
1767 address.objectId = InvalidOid;
1768 address.objectSubId = 0;
1769 }
1770
1771 return address;
1772}
1773
1774/*
1775 * Find the ObjectAddress for an opclass/opfamily member.
1776 *
1777 * (The returned address corresponds to a pg_amop/pg_amproc object).
1778 */
1779static ObjectAddress
1781 List *object, bool missing_ok)
1782{
1784 ObjectAddress address;
1785 ListCell *cell;
1786 List *copy;
1787 TypeName *typenames[2];
1788 Oid typeoids[2];
1789 int membernum;
1790 int i;
1791
1792 /*
1793 * The last element of the object list contains the strategy or procedure
1794 * number. We need to strip that out before getting the opclass/family
1795 * address. The rest can be used directly by get_object_address_opcf().
1796 */
1797 membernum = atoi(strVal(llast(linitial(object))));
1798 copy = list_copy_head(linitial(object), list_length(linitial(object)) - 1);
1799
1800 /* no missing_ok support here */
1802
1803 /* find out left/right type names and OIDs */
1804 typenames[0] = typenames[1] = NULL;
1805 typeoids[0] = typeoids[1] = InvalidOid;
1806 i = 0;
1807 foreach(cell, lsecond(object))
1808 {
1810
1811 typenames[i] = lfirst_node(TypeName, cell);
1813 typeoids[i] = typaddr.objectId;
1814 if (++i >= 2)
1815 break;
1816 }
1817
1818 switch (objtype)
1819 {
1820 case OBJECT_AMOP:
1821 {
1822 HeapTuple tp;
1823
1825 InvalidOid);
1826
1828 ObjectIdGetDatum(famaddr.objectId),
1832 if (!HeapTupleIsValid(tp))
1833 {
1834 if (!missing_ok)
1835 ereport(ERROR,
1837 errmsg("operator %d (%s, %s) of %s does not exist",
1838 membernum,
1841 getObjectDescription(&famaddr, false))));
1842 }
1843 else
1844 {
1845 address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid;
1846 ReleaseSysCache(tp);
1847 }
1848 }
1849 break;
1850
1851 case OBJECT_AMPROC:
1852 {
1853 HeapTuple tp;
1854
1856 InvalidOid);
1857
1859 ObjectIdGetDatum(famaddr.objectId),
1863 if (!HeapTupleIsValid(tp))
1864 {
1865 if (!missing_ok)
1866 ereport(ERROR,
1868 errmsg("function %d (%s, %s) of %s does not exist",
1869 membernum,
1872 getObjectDescription(&famaddr, false))));
1873 }
1874 else
1875 {
1876 address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid;
1877 ReleaseSysCache(tp);
1878 }
1879 }
1880 break;
1881 default:
1882 elog(ERROR, "unrecognized object type: %d", (int) objtype);
1883 }
1884
1885 return address;
1886}
1887
1888/*
1889 * Find the ObjectAddress for a user mapping.
1890 */
1891static ObjectAddress
1892get_object_address_usermapping(List *object, bool missing_ok)
1893{
1894 ObjectAddress address;
1895 Oid userid;
1896 char *username;
1897 char *servername;
1898 ForeignServer *server;
1899 HeapTuple tp;
1900
1902
1903 /* fetch string names from input lists, for error messages */
1904 username = strVal(linitial(object));
1905 servername = strVal(lsecond(object));
1906
1907 /* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
1908 if (strcmp(username, "public") == 0)
1909 userid = InvalidOid;
1910 else
1911 {
1914 if (!HeapTupleIsValid(tp))
1915 {
1916 if (!missing_ok)
1917 ereport(ERROR,
1919 errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
1920 username, servername)));
1921 return address;
1922 }
1923 userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
1924 ReleaseSysCache(tp);
1925 }
1926
1927 /* Now look up the pg_user_mapping tuple */
1928 server = GetForeignServerByName(servername, true);
1929 if (!server)
1930 {
1931 if (!missing_ok)
1932 ereport(ERROR,
1934 errmsg("server \"%s\" does not exist", servername)));
1935 return address;
1936 }
1938 ObjectIdGetDatum(userid),
1939 ObjectIdGetDatum(server->serverid));
1940 if (!HeapTupleIsValid(tp))
1941 {
1942 if (!missing_ok)
1943 ereport(ERROR,
1945 errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
1946 username, servername)));
1947 return address;
1948 }
1949
1950 address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
1951
1952 ReleaseSysCache(tp);
1953
1954 return address;
1955}
1956
1957/*
1958 * Find the ObjectAddress for a publication relation. The first element of
1959 * the object parameter is the relation name, the second is the
1960 * publication name.
1961 */
1962static ObjectAddress
1964 Relation *relp, bool missing_ok)
1965{
1966 ObjectAddress address;
1967 Relation relation;
1968 List *relname;
1969 char *pubname;
1970 Publication *pub;
1971
1973
1974 relname = linitial(object);
1976 AccessShareLock, missing_ok);
1977 if (!relation)
1978 return address;
1979
1980 /* fetch publication name from input list */
1981 pubname = strVal(lsecond(object));
1982
1983 /* Now look up the pg_publication tuple */
1984 pub = GetPublicationByName(pubname, missing_ok);
1985 if (!pub)
1986 {
1988 return address;
1989 }
1990
1991 /* Find the publication relation mapping in syscache. */
1992 address.objectId =
1995 ObjectIdGetDatum(pub->oid));
1996 if (!OidIsValid(address.objectId))
1997 {
1998 if (!missing_ok)
1999 ereport(ERROR,
2001 errmsg("publication relation \"%s\" in publication \"%s\" does not exist",
2002 RelationGetRelationName(relation), pubname)));
2004 return address;
2005 }
2006
2007 *relp = relation;
2008 return address;
2009}
2010
2011/*
2012 * Find the ObjectAddress for a publication schema. The first element of the
2013 * object parameter is the schema name, the second is the publication name.
2014 */
2015static ObjectAddress
2017{
2018 ObjectAddress address;
2019 Publication *pub;
2020 char *pubname;
2021 char *schemaname;
2022 Oid schemaid;
2023
2025
2026 /* Fetch schema name and publication name from input list */
2027 schemaname = strVal(linitial(object));
2028 pubname = strVal(lsecond(object));
2029
2030 schemaid = get_namespace_oid(schemaname, missing_ok);
2031 if (!OidIsValid(schemaid))
2032 return address;
2033
2034 /* Now look up the pg_publication tuple */
2035 pub = GetPublicationByName(pubname, missing_ok);
2036 if (!pub)
2037 return address;
2038
2039 /* Find the publication schema mapping in syscache */
2040 address.objectId =
2044 ObjectIdGetDatum(pub->oid));
2045 if (!OidIsValid(address.objectId) && !missing_ok)
2046 ereport(ERROR,
2048 errmsg("publication schema \"%s\" in publication \"%s\" does not exist",
2049 schemaname, pubname)));
2050
2051 return address;
2052}
2053
2054/*
2055 * Find the ObjectAddress for a default ACL.
2056 */
2057static ObjectAddress
2058get_object_address_defacl(List *object, bool missing_ok)
2059{
2060 HeapTuple tp;
2061 Oid userid;
2062 Oid schemaid;
2063 char *username;
2064 char *schema;
2065 char objtype;
2066 char *objtype_str;
2067 ObjectAddress address;
2068
2070
2071 /*
2072 * First figure out the textual attributes so that they can be used for
2073 * error reporting.
2074 */
2075 username = strVal(lsecond(object));
2076 if (list_length(object) >= 3)
2077 schema = (char *) strVal(lthird(object));
2078 else
2079 schema = NULL;
2080
2081 /*
2082 * Decode defaclobjtype. Only first char is considered; the rest of the
2083 * string, if any, is blissfully ignored.
2084 */
2085 objtype = ((char *) strVal(linitial(object)))[0];
2086 switch (objtype)
2087 {
2088 case DEFACLOBJ_RELATION:
2089 objtype_str = "tables";
2090 break;
2091 case DEFACLOBJ_SEQUENCE:
2092 objtype_str = "sequences";
2093 break;
2094 case DEFACLOBJ_FUNCTION:
2095 objtype_str = "functions";
2096 break;
2097 case DEFACLOBJ_TYPE:
2098 objtype_str = "types";
2099 break;
2101 objtype_str = "schemas";
2102 break;
2104 objtype_str = "large objects";
2105 break;
2106 default:
2107 ereport(ERROR,
2109 errmsg("unrecognized default ACL object type \"%c\"", objtype),
2110 errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".",
2117 }
2118
2119 /*
2120 * Look up user ID. Behave as "default ACL not found" if the user doesn't
2121 * exist.
2122 */
2125 if (!HeapTupleIsValid(tp))
2126 goto not_found;
2127 userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
2128 ReleaseSysCache(tp);
2129
2130 /*
2131 * If a schema name was given, look up its OID. If it doesn't exist,
2132 * behave as "default ACL not found".
2133 */
2134 if (schema)
2135 {
2136 schemaid = get_namespace_oid(schema, true);
2137 if (schemaid == InvalidOid)
2138 goto not_found;
2139 }
2140 else
2142
2143 /* Finally, look up the pg_default_acl object */
2145 ObjectIdGetDatum(userid),
2147 CharGetDatum(objtype));
2148 if (!HeapTupleIsValid(tp))
2149 goto not_found;
2150
2151 address.objectId = ((Form_pg_default_acl) GETSTRUCT(tp))->oid;
2152 ReleaseSysCache(tp);
2153
2154 return address;
2155
2156not_found:
2157 if (!missing_ok)
2158 {
2159 if (schema)
2160 ereport(ERROR,
2162 errmsg("default ACL for user \"%s\" in schema \"%s\" on %s does not exist",
2163 username, schema, objtype_str)));
2164 else
2165 ereport(ERROR,
2167 errmsg("default ACL for user \"%s\" on %s does not exist",
2169 }
2170 return address;
2171}
2172
2173/*
2174 * Convert an array of TEXT into a List of string Values, as emitted by the
2175 * parser, which is what get_object_address uses as input.
2176 */
2177static List *
2179{
2180 Datum *elems;
2181 bool *nulls;
2182 int nelems;
2183 List *list = NIL;
2184 int i;
2185
2186 deconstruct_array_builtin(arr, TEXTOID, &elems, &nulls, &nelems);
2187
2188 for (i = 0; i < nelems; i++)
2189 {
2190 if (nulls[i])
2191 ereport(ERROR,
2193 errmsg("name or argument lists may not contain nulls")));
2194 list = lappend(list, makeString(TextDatumGetCString(elems[i])));
2195 }
2196
2197 return list;
2198}
2199
2200/*
2201 * SQL-callable version of get_object_address
2202 */
2203Datum
2205{
2206 char *ttype = TextDatumGetCString(PG_GETARG_DATUM(0));
2209 int itype;
2211 List *name = NIL;
2212 TypeName *typename = NULL;
2213 List *args = NIL;
2214 Node *objnode = NULL;
2215 ObjectAddress addr;
2216 TupleDesc tupdesc;
2217 Datum values[3];
2218 bool nulls[3];
2219 HeapTuple htup;
2220 Relation relation;
2221
2222 /* Decode object type, raise error if unknown */
2224 if (itype < 0)
2225 ereport(ERROR,
2227 errmsg("unsupported object type \"%s\"", ttype)));
2228 type = (ObjectType) itype;
2229
2230 /*
2231 * Convert the text array to the representation appropriate for the given
2232 * object type. Most use a simple string Values list, but there are some
2233 * exceptions.
2234 */
2235 if (type == OBJECT_TYPE || type == OBJECT_DOMAIN || type == OBJECT_CAST ||
2237 {
2238 Datum *elems;
2239 bool *nulls;
2240 int nelems;
2241
2242 deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, &nelems);
2243 if (nelems != 1)
2244 ereport(ERROR,
2246 errmsg("name list length must be exactly %d", 1)));
2247 if (nulls[0])
2248 ereport(ERROR,
2250 errmsg("name or argument lists may not contain nulls")));
2251 typename = typeStringToTypeName(TextDatumGetCString(elems[0]), NULL);
2252 }
2253 else if (type == OBJECT_LARGEOBJECT)
2254 {
2255 Datum *elems;
2256 bool *nulls;
2257 int nelems;
2258
2259 deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, &nelems);
2260 if (nelems != 1)
2261 ereport(ERROR,
2263 errmsg("name list length must be exactly %d", 1)));
2264 if (nulls[0])
2265 ereport(ERROR,
2267 errmsg("large object OID may not be null")));
2268 objnode = (Node *) makeFloat(TextDatumGetCString(elems[0]));
2269 }
2270 else
2271 {
2273 if (name == NIL)
2274 ereport(ERROR,
2276 errmsg("name list length must be at least %d", 1)));
2277 }
2278
2279 /*
2280 * If args are given, decode them according to the object type.
2281 */
2282 if (type == OBJECT_AGGREGATE ||
2283 type == OBJECT_FUNCTION ||
2285 type == OBJECT_ROUTINE ||
2286 type == OBJECT_OPERATOR ||
2287 type == OBJECT_CAST ||
2288 type == OBJECT_AMOP ||
2290 {
2291 /* in these cases, the args list must be of TypeName */
2292 Datum *elems;
2293 bool *nulls;
2294 int nelems;
2295 int i;
2296
2297 deconstruct_array_builtin(argsarr, TEXTOID, &elems, &nulls, &nelems);
2298
2299 args = NIL;
2300 for (i = 0; i < nelems; i++)
2301 {
2302 if (nulls[i])
2303 ereport(ERROR,
2305 errmsg("name or argument lists may not contain nulls")));
2306 args = lappend(args,
2308 NULL));
2309 }
2310 }
2311 else
2312 {
2313 /* For all other object types, use string Values */
2315 }
2316
2317 /*
2318 * get_object_address is pretty sensitive to the length of its input
2319 * lists; check that they're what it wants.
2320 */
2321 switch (type)
2322 {
2325 if (list_length(name) != 1)
2326 ereport(ERROR,
2328 errmsg("name list length must be exactly %d", 1)));
2329 /* fall through to check args length */
2332 case OBJECT_CAST:
2334 case OBJECT_DEFACL:
2335 case OBJECT_TRANSFORM:
2336 if (list_length(args) != 1)
2337 ereport(ERROR,
2339 errmsg("argument list length must be exactly %d", 1)));
2340 break;
2341 case OBJECT_OPFAMILY:
2342 case OBJECT_OPCLASS:
2343 if (list_length(name) < 2)
2344 ereport(ERROR,
2346 errmsg("name list length must be at least %d", 2)));
2347 break;
2348 case OBJECT_AMOP:
2349 case OBJECT_AMPROC:
2350 if (list_length(name) < 3)
2351 ereport(ERROR,
2353 errmsg("name list length must be at least %d", 3)));
2354 /* fall through to check args length */
2356 case OBJECT_OPERATOR:
2357 if (list_length(args) != 2)
2358 ereport(ERROR,
2360 errmsg("argument list length must be exactly %d", 2)));
2361 break;
2362 default:
2363 break;
2364 }
2365
2366 /*
2367 * Now build the Node type that get_object_address() expects for the given
2368 * type.
2369 */
2370 switch (type)
2371 {
2372 case OBJECT_TABLE:
2373 case OBJECT_SEQUENCE:
2374 case OBJECT_VIEW:
2375 case OBJECT_MATVIEW:
2376 case OBJECT_INDEX:
2378 case OBJECT_PROPGRAPH:
2379 case OBJECT_COLUMN:
2380 case OBJECT_ATTRIBUTE:
2381 case OBJECT_COLLATION:
2382 case OBJECT_CONVERSION:
2384 case OBJECT_TSPARSER:
2386 case OBJECT_TSTEMPLATE:
2388 case OBJECT_DEFAULT:
2389 case OBJECT_POLICY:
2390 case OBJECT_RULE:
2391 case OBJECT_TRIGGER:
2393 case OBJECT_OPCLASS:
2394 case OBJECT_OPFAMILY:
2395 objnode = (Node *) name;
2396 break;
2398 case OBJECT_DATABASE:
2400 case OBJECT_EXTENSION:
2401 case OBJECT_FDW:
2403 case OBJECT_LANGUAGE:
2405 case OBJECT_PUBLICATION:
2406 case OBJECT_ROLE:
2407 case OBJECT_SCHEMA:
2409 case OBJECT_TABLESPACE:
2410 if (list_length(name) != 1)
2411 ereport(ERROR,
2413 errmsg("name list length must be exactly %d", 1)));
2415 break;
2416 case OBJECT_TYPE:
2417 case OBJECT_DOMAIN:
2418 objnode = (Node *) typename;
2419 break;
2420 case OBJECT_CAST:
2422 case OBJECT_TRANSFORM:
2423 objnode = (Node *) list_make2(typename, linitial(args));
2424 break;
2426 objnode = (Node *) list_make2(name, linitial(args));
2427 break;
2431 break;
2432 case OBJECT_DEFACL:
2433 objnode = (Node *) lcons(linitial(args), name);
2434 break;
2435 case OBJECT_AMOP:
2436 case OBJECT_AMPROC:
2437 objnode = (Node *) list_make2(name, args);
2438 break;
2439 case OBJECT_FUNCTION:
2440 case OBJECT_PROCEDURE:
2441 case OBJECT_ROUTINE:
2442 case OBJECT_AGGREGATE:
2443 case OBJECT_OPERATOR:
2444 {
2446
2447 owa->objname = name;
2448 owa->objargs = args;
2449 objnode = (Node *) owa;
2450 break;
2451 }
2452 case OBJECT_LARGEOBJECT:
2453 /* already handled above */
2454 break;
2455 /* no default, to let compiler warn about missing case */
2456 }
2457
2458 if (objnode == NULL)
2459 elog(ERROR, "unrecognized object type: %d", type);
2460
2462 &relation, AccessShareLock, false);
2463
2464 /* We don't need the relcache entry, thank you very much */
2465 if (relation)
2467
2468 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
2469 elog(ERROR, "return type must be a row type");
2470
2471 values[0] = ObjectIdGetDatum(addr.classId);
2472 values[1] = ObjectIdGetDatum(addr.objectId);
2473 values[2] = Int32GetDatum(addr.objectSubId);
2474 nulls[0] = false;
2475 nulls[1] = false;
2476 nulls[2] = false;
2477
2478 htup = heap_form_tuple(tupdesc, values, nulls);
2479
2481}
2482
2483/*
2484 * Check ownership of an object previously identified by get_object_address.
2485 */
2486void
2488 Node *object, Relation relation)
2489{
2490 switch (objtype)
2491 {
2492 case OBJECT_INDEX:
2493 case OBJECT_SEQUENCE:
2494 case OBJECT_TABLE:
2495 case OBJECT_VIEW:
2496 case OBJECT_MATVIEW:
2498 case OBJECT_PROPGRAPH:
2499 case OBJECT_COLUMN:
2500 case OBJECT_RULE:
2501 case OBJECT_TRIGGER:
2502 case OBJECT_POLICY:
2504 if (!object_ownercheck(RelationRelationId, RelationGetRelid(relation), roleid))
2506 RelationGetRelationName(relation));
2507 break;
2508 case OBJECT_TYPE:
2509 case OBJECT_DOMAIN:
2510 case OBJECT_ATTRIBUTE:
2511 if (!object_ownercheck(address.classId, address.objectId, roleid))
2513 break;
2515 {
2516 HeapTuple tuple;
2517 Oid contypid;
2518
2519 tuple = SearchSysCache1(CONSTROID,
2520 ObjectIdGetDatum(address.objectId));
2521 if (!HeapTupleIsValid(tuple))
2522 elog(ERROR, "constraint with OID %u does not exist",
2523 address.objectId);
2524
2526
2527 ReleaseSysCache(tuple);
2528
2529 /*
2530 * Fallback to type ownership check in this case as this is
2531 * what domain constraints rely on.
2532 */
2535 }
2536 break;
2537 case OBJECT_AGGREGATE:
2538 case OBJECT_FUNCTION:
2539 case OBJECT_PROCEDURE:
2540 case OBJECT_ROUTINE:
2541 case OBJECT_OPERATOR:
2542 if (!object_ownercheck(address.classId, address.objectId, roleid))
2544 NameListToString((castNode(ObjectWithArgs, object))->objname));
2545 break;
2546 case OBJECT_DATABASE:
2548 case OBJECT_EXTENSION:
2549 case OBJECT_FDW:
2551 case OBJECT_LANGUAGE:
2552 case OBJECT_PUBLICATION:
2553 case OBJECT_SCHEMA:
2555 case OBJECT_TABLESPACE:
2556 if (!object_ownercheck(address.classId, address.objectId, roleid))
2558 strVal(object));
2559 break;
2560 case OBJECT_COLLATION:
2561 case OBJECT_CONVERSION:
2562 case OBJECT_OPCLASS:
2563 case OBJECT_OPFAMILY:
2567 if (!object_ownercheck(address.classId, address.objectId, roleid))
2569 NameListToString(castNode(List, object)));
2570 break;
2571 case OBJECT_LARGEOBJECT:
2572 if (!lo_compat_privileges &&
2573 !object_ownercheck(address.classId, address.objectId, roleid))
2574 ereport(ERROR,
2576 errmsg("must be owner of large object %u",
2577 address.objectId)));
2578 break;
2579 case OBJECT_CAST:
2580 {
2581 /* We can only check permissions on the source/target types */
2582 TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
2583 TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
2584 Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
2585 Oid targettypeid = typenameTypeId(NULL, targettype);
2586
2589 ereport(ERROR,
2591 errmsg("must be owner of type %s or type %s",
2594 }
2595 break;
2596 case OBJECT_TRANSFORM:
2597 {
2598 TypeName *typename = linitial_node(TypeName, castNode(List, object));
2599 Oid typeid = typenameTypeId(NULL, typename);
2600
2601 if (!object_ownercheck(TypeRelationId, typeid, roleid))
2603 }
2604 break;
2605 case OBJECT_ROLE:
2606
2607 /*
2608 * We treat roles as being "owned" by those with CREATEROLE priv,
2609 * provided that they also have admin option on the role.
2610 *
2611 * However, superusers are only owned by superusers.
2612 */
2613 if (superuser_arg(address.objectId))
2614 {
2615 if (!superuser_arg(roleid))
2616 ereport(ERROR,
2618 errmsg("permission denied"),
2619 errdetail("The current user must have the %s attribute.",
2620 "SUPERUSER")));
2621 }
2622 else
2623 {
2624 if (!has_createrole_privilege(roleid))
2625 ereport(ERROR,
2627 errmsg("permission denied"),
2628 errdetail("The current user must have the %s attribute.",
2629 "CREATEROLE")));
2630 if (!is_admin_of_role(roleid, address.objectId))
2631 ereport(ERROR,
2633 errmsg("permission denied"),
2634 errdetail("The current user must have the %s option on role \"%s\".",
2635 "ADMIN",
2637 true))));
2638 }
2639 break;
2640 case OBJECT_TSPARSER:
2641 case OBJECT_TSTEMPLATE:
2644 /* We treat these object types as being owned by superusers */
2645 if (!superuser_arg(roleid))
2646 ereport(ERROR,
2648 errmsg("must be superuser")));
2649 break;
2650 case OBJECT_AMOP:
2651 case OBJECT_AMPROC:
2652 case OBJECT_DEFAULT:
2653 case OBJECT_DEFACL:
2657 /* These are currently not supported or don't make sense here. */
2658 elog(ERROR, "unsupported object type: %d", (int) objtype);
2659 break;
2660 }
2661}
2662
2663/*
2664 * get_object_namespace
2665 *
2666 * Find the schema containing the specified object. For non-schema objects,
2667 * this function returns InvalidOid.
2668 */
2669Oid
2671{
2672 SysCacheIdentifier cache;
2673 HeapTuple tuple;
2674 Oid oid;
2676
2677 /* If not owned by a namespace, just return InvalidOid. */
2678 property = get_object_property_data(address->classId);
2679 if (property->attnum_namespace == InvalidAttrNumber)
2680 return InvalidOid;
2681
2682 /* Currently, we can only handle object types with system caches. */
2683 cache = property->oid_catcache_id;
2684 Assert(cache != SYSCACHEID_INVALID);
2685
2686 /* Fetch tuple from syscache and extract namespace attribute. */
2687 tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId));
2688 if (!HeapTupleIsValid(tuple))
2689 elog(ERROR, "cache lookup failed for cache %d oid %u",
2690 cache, address->objectId);
2692 tuple,
2693 property->attnum_namespace));
2694 ReleaseSysCache(tuple);
2695
2696 return oid;
2697}
2698
2699/*
2700 * Return ObjectType for the given object type as given by
2701 * getObjectTypeDescription; if no valid ObjectType code exists, but it's a
2702 * possible output type from getObjectTypeDescription, return -1.
2703 * Otherwise, an error is thrown.
2704 */
2705int
2706read_objtype_from_string(const char *objtype)
2707{
2708 int i;
2709
2710 for (i = 0; i < lengthof(ObjectTypeMap); i++)
2711 {
2712 if (strcmp(ObjectTypeMap[i].tm_name, objtype) == 0)
2713 return ObjectTypeMap[i].tm_type;
2714 }
2715 ereport(ERROR,
2717 errmsg("unrecognized object type \"%s\"", objtype)));
2718
2719 return -1; /* keep compiler quiet */
2720}
2721
2722/*
2723 * Interfaces to reference fields of ObjectPropertyType
2724 */
2725const char *
2732
2733Oid
2740
2748
2756
2759{
2761
2762 return prop->attnum_oid;
2763}
2764
2772
2780
2788
2791{
2793
2794 return prop->attnum_acl;
2795}
2796
2797/*
2798 * get_object_type
2799 *
2800 * Return the object type associated with a given object. This routine
2801 * is primarily used to determine the object type to mention in ACL check
2802 * error messages, so it's desirable for it to avoid failing.
2803 */
2806{
2808
2809 if (prop->objtype == OBJECT_TABLE)
2810 {
2811 /*
2812 * If the property data says it's a table, dig a little deeper to get
2813 * the real relation kind, so that callers can produce more precise
2814 * error messages.
2815 */
2816 return get_relkind_objtype(get_rel_relkind(object_id));
2817 }
2818 else
2819 return prop->objtype;
2820}
2821
2822bool
2829
2830/*
2831 * Return whether we have useful data for the given object class in the
2832 * ObjectProperty table.
2833 */
2834bool
2836{
2837 int index;
2838
2839 for (index = 0; index < lengthof(ObjectProperty); index++)
2840 {
2841 if (ObjectProperty[index].class_oid == class_id)
2842 return true;
2843 }
2844
2845 return false;
2846}
2847
2848/*
2849 * Find ObjectProperty structure by class_id.
2850 */
2851static const ObjectPropertyType *
2853{
2854 static const ObjectPropertyType *prop_last = NULL;
2855 int index;
2856
2857 /*
2858 * A shortcut to speed up multiple consecutive lookups of a particular
2859 * object class.
2860 */
2861 if (prop_last && prop_last->class_oid == class_id)
2862 return prop_last;
2863
2864 for (index = 0; index < lengthof(ObjectProperty); index++)
2865 {
2866 if (ObjectProperty[index].class_oid == class_id)
2867 {
2869 return &ObjectProperty[index];
2870 }
2871 }
2872
2873 ereport(ERROR,
2874 (errmsg_internal("unrecognized class ID: %u", class_id)));
2875
2876 return NULL; /* keep MSC compiler happy */
2877}
2878
2879/*
2880 * Return a copy of the tuple for the object with the given object OID, from
2881 * the given catalog (which must have been opened by the caller and suitably
2882 * locked). NULL is returned if the OID is not found.
2883 *
2884 * We try a syscache first, if available.
2885 */
2892
2893/*
2894 * Same as get_catalog_object_by_oid(), but with an additional "locktup"
2895 * argument controlling whether to acquire a LOCKTAG_TUPLE at mode
2896 * InplaceUpdateTupleLock. See README.tuplock section "Locking to write
2897 * inplace-updated tables".
2898 */
2902 Oid objectId,
2903 bool locktup)
2904{
2905 HeapTuple tuple;
2906 Oid classId = RelationGetRelid(catalog);
2908
2909 if (oidCacheId >= 0)
2910 {
2911 if (locktup)
2913 ObjectIdGetDatum(objectId));
2914 else
2916 ObjectIdGetDatum(objectId));
2917 if (!HeapTupleIsValid(tuple)) /* should not happen */
2918 return NULL;
2919 }
2920 else
2921 {
2923 SysScanDesc scan;
2925
2927
2929 oidcol,
2931 ObjectIdGetDatum(objectId));
2932
2934 NULL, 1, &skey);
2935 tuple = systable_getnext(scan);
2936 if (!HeapTupleIsValid(tuple))
2937 {
2938 systable_endscan(scan);
2939 return NULL;
2940 }
2941
2942 if (locktup)
2944
2945 tuple = heap_copytuple(tuple);
2946
2947 systable_endscan(scan);
2948 }
2949
2950 return tuple;
2951}
2952
2953/*
2954 * getPublicationSchemaInfo
2955 *
2956 * Get publication name and schema name from the object address into pubname and
2957 * nspname. Both pubname and nspname are palloc'd strings which will be freed by
2958 * the caller.
2959 */
2960static bool
2961getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok,
2962 char **pubname, char **nspname)
2963{
2964 HeapTuple tup;
2966
2968 ObjectIdGetDatum(object->objectId));
2969 if (!HeapTupleIsValid(tup))
2970 {
2971 if (!missing_ok)
2972 elog(ERROR, "cache lookup failed for publication schema %u",
2973 object->objectId);
2974 return false;
2975 }
2976
2978 *pubname = get_publication_name(pnform->pnpubid, missing_ok);
2979 if (!(*pubname))
2980 {
2982 return false;
2983 }
2984
2985 *nspname = get_namespace_name(pnform->pnnspid);
2986 if (!(*nspname))
2987 {
2988 Oid schemaid = pnform->pnnspid;
2989
2990 pfree(*pubname);
2992 if (!missing_ok)
2993 elog(ERROR, "cache lookup failed for schema %u",
2994 schemaid);
2995 return false;
2996 }
2997
2999 return true;
3000}
3001
3002/*
3003 * getObjectDescription: build an object description for messages
3004 *
3005 * The result is a palloc'd string. NULL is returned for an undefined
3006 * object if missing_ok is true, else an error is generated.
3007 */
3008char *
3009getObjectDescription(const ObjectAddress *object, bool missing_ok)
3010{
3011 StringInfoData buffer;
3012
3013 initStringInfo(&buffer);
3014
3015 switch (object->classId)
3016 {
3017 case RelationRelationId:
3018 if (object->objectSubId == 0)
3019 getRelationDescription(&buffer, object->objectId, missing_ok);
3020 else
3021 {
3022 /* column, not whole relation */
3023 StringInfoData rel;
3024 char *attname = get_attname(object->objectId,
3025 object->objectSubId,
3026 missing_ok);
3027
3028 if (!attname)
3029 break;
3030
3031 initStringInfo(&rel);
3032 getRelationDescription(&rel, object->objectId, missing_ok);
3033 /* translator: second %s is, e.g., "table %s" */
3034 appendStringInfo(&buffer, _("column %s of %s"),
3035 attname, rel.data);
3036 pfree(rel.data);
3037 }
3038 break;
3039
3041 {
3044 flags);
3045
3046 if (proname == NULL)
3047 break;
3048
3049 appendStringInfo(&buffer, _("function %s"), proname);
3050 break;
3051 }
3052
3053 case TypeRelationId:
3054 {
3056 char *typname = format_type_extended(object->objectId, -1,
3057 flags);
3058
3059 if (typname == NULL)
3060 break;
3061
3062 appendStringInfo(&buffer, _("type %s"), typname);
3063 break;
3064 }
3065
3066 case CastRelationId:
3067 {
3069 ScanKeyData skey[1];
3071 HeapTuple tup;
3073
3075
3076 ScanKeyInit(&skey[0],
3079 ObjectIdGetDatum(object->objectId));
3080
3082 NULL, 1, skey);
3083
3085
3086 if (!HeapTupleIsValid(tup))
3087 {
3088 if (!missing_ok)
3089 elog(ERROR, "could not find tuple for cast %u",
3090 object->objectId);
3091
3094 break;
3095 }
3096
3098
3099 appendStringInfo(&buffer, _("cast from %s to %s"),
3100 format_type_be(castForm->castsource),
3101 format_type_be(castForm->casttarget));
3102
3105 break;
3106 }
3107
3109 {
3111 Form_pg_collation coll;
3112 char *nspname;
3113
3115 ObjectIdGetDatum(object->objectId));
3117 {
3118 if (!missing_ok)
3119 elog(ERROR, "cache lookup failed for collation %u",
3120 object->objectId);
3121 break;
3122 }
3123
3125
3126 /* Qualify the name if not visible in search path */
3127 if (CollationIsVisible(object->objectId))
3128 nspname = NULL;
3129 else
3130 nspname = get_namespace_name(coll->collnamespace);
3131
3132 appendStringInfo(&buffer, _("collation %s"),
3134 NameStr(coll->collname)));
3136 break;
3137 }
3138
3140 {
3143
3145 ObjectIdGetDatum(object->objectId));
3147 {
3148 if (!missing_ok)
3149 elog(ERROR, "cache lookup failed for constraint %u",
3150 object->objectId);
3151 break;
3152 }
3153
3155
3156 if (OidIsValid(con->conrelid))
3157 {
3158 StringInfoData rel;
3159
3160 initStringInfo(&rel);
3161 getRelationDescription(&rel, con->conrelid, false);
3162 /* translator: second %s is, e.g., "table %s" */
3163 appendStringInfo(&buffer, _("constraint %s on %s"),
3164 NameStr(con->conname), rel.data);
3165 pfree(rel.data);
3166 }
3167 else
3168 {
3169 appendStringInfo(&buffer, _("constraint %s"),
3170 NameStr(con->conname));
3171 }
3172
3174 break;
3175 }
3176
3178 {
3181 char *nspname;
3182
3184 ObjectIdGetDatum(object->objectId));
3186 {
3187 if (!missing_ok)
3188 elog(ERROR, "cache lookup failed for conversion %u",
3189 object->objectId);
3190 break;
3191 }
3192
3194
3195 /* Qualify the name if not visible in search path */
3196 if (ConversionIsVisible(object->objectId))
3197 nspname = NULL;
3198 else
3199 nspname = get_namespace_name(conv->connamespace);
3200
3201 appendStringInfo(&buffer, _("conversion %s"),
3203 NameStr(conv->conname)));
3205 break;
3206 }
3207
3209 {
3211
3213
3214 if (!OidIsValid(colobject.objectId))
3215 {
3216 if (!missing_ok)
3217 elog(ERROR, "could not find tuple for attrdef %u",
3218 object->objectId);
3219 break;
3220 }
3221
3222 /* translator: %s is typically "column %s of table %s" */
3223 appendStringInfo(&buffer, _("default value for %s"),
3225 break;
3226 }
3227
3228 case LanguageRelationId:
3229 {
3230 char *langname = get_language_name(object->objectId,
3231 missing_ok);
3232
3233 if (langname)
3234 appendStringInfo(&buffer, _("language %s"),
3235 get_language_name(object->objectId, false));
3236 break;
3237 }
3238
3240 if (!LargeObjectExists(object->objectId))
3241 break;
3242 appendStringInfo(&buffer, _("large object %u"),
3243 object->objectId);
3244 break;
3245
3246 case OperatorRelationId:
3247 {
3249 char *oprname = format_operator_extended(object->objectId,
3250 flags);
3251
3252 if (oprname == NULL)
3253 break;
3254
3255 appendStringInfo(&buffer, _("operator %s"), oprname);
3256 break;
3257 }
3258
3260 {
3265 char *nspname;
3266
3268 ObjectIdGetDatum(object->objectId));
3270 {
3271 if (!missing_ok)
3272 elog(ERROR, "cache lookup failed for opclass %u",
3273 object->objectId);
3274 break;
3275 }
3276
3278
3280 ObjectIdGetDatum(opcForm->opcmethod));
3281 if (!HeapTupleIsValid(amTup))
3282 elog(ERROR, "cache lookup failed for access method %u",
3283 opcForm->opcmethod);
3285
3286 /* Qualify the name if not visible in search path */
3287 if (OpclassIsVisible(object->objectId))
3288 nspname = NULL;
3289 else
3290 nspname = get_namespace_name(opcForm->opcnamespace);
3291
3292 appendStringInfo(&buffer, _("operator class %s for access method %s"),
3294 NameStr(opcForm->opcname)),
3295 NameStr(amForm->amname));
3296
3299 break;
3300 }
3301
3303 getOpFamilyDescription(&buffer, object->objectId, missing_ok);
3304 break;
3305
3307 {
3308 HeapTuple tup;
3309
3311 ObjectIdGetDatum(object->objectId));
3312 if (!HeapTupleIsValid(tup))
3313 {
3314 if (!missing_ok)
3315 elog(ERROR, "cache lookup failed for access method %u",
3316 object->objectId);
3317 break;
3318 }
3319
3320 appendStringInfo(&buffer, _("access method %s"),
3321 NameStr(((Form_pg_am) GETSTRUCT(tup))->amname));
3323 break;
3324 }
3325
3327 {
3329 HeapTuple tup;
3330 ScanKeyData skey[1];
3333 StringInfoData opfam;
3334
3337
3338 ScanKeyInit(&skey[0],
3341 ObjectIdGetDatum(object->objectId));
3342
3344 NULL, 1, skey);
3345
3347
3348 if (!HeapTupleIsValid(tup))
3349 {
3350 if (!missing_ok)
3351 elog(ERROR, "could not find tuple for amop entry %u",
3352 object->objectId);
3353
3356 break;
3357 }
3358
3360
3361 initStringInfo(&opfam);
3362 getOpFamilyDescription(&opfam, amopForm->amopfamily, false);
3363
3364 /*
3365 * We use FORMAT_TYPE_ALLOW_INVALID here so as not to fail
3366 * completely if the type links are dangling, which is a form
3367 * of catalog corruption that could occur due to old bugs.
3368 */
3369
3370 /*------
3371 translator: %d is the operator strategy (a number), the
3372 first two %s's are data type names, the third %s is the
3373 description of the operator family, and the last %s is the
3374 textual form of the operator with arguments. */
3375 appendStringInfo(&buffer, _("operator %d (%s, %s) of %s: %s"),
3376 amopForm->amopstrategy,
3377 format_type_extended(amopForm->amoplefttype,
3379 format_type_extended(amopForm->amoprighttype,
3381 opfam.data,
3382 format_operator(amopForm->amopopr));
3383
3384 pfree(opfam.data);
3385
3388 break;
3389 }
3390
3392 {
3394 ScanKeyData skey[1];
3396 HeapTuple tup;
3398 StringInfoData opfam;
3399
3402
3403 ScanKeyInit(&skey[0],
3406 ObjectIdGetDatum(object->objectId));
3407
3409 NULL, 1, skey);
3410
3412
3413 if (!HeapTupleIsValid(tup))
3414 {
3415 if (!missing_ok)
3416 elog(ERROR, "could not find tuple for amproc entry %u",
3417 object->objectId);
3418
3421 break;
3422 }
3423
3425
3426 initStringInfo(&opfam);
3427 getOpFamilyDescription(&opfam, amprocForm->amprocfamily, false);
3428
3429 /*
3430 * We use FORMAT_TYPE_ALLOW_INVALID here so as not to fail
3431 * completely if the type links are dangling, which is a form
3432 * of catalog corruption that could occur due to old bugs.
3433 */
3434
3435 /*------
3436 translator: %d is the function number, the first two %s's
3437 are data type names, the third %s is the description of the
3438 operator family, and the last %s is the textual form of the
3439 function with arguments. */
3440 appendStringInfo(&buffer, _("function %d (%s, %s) of %s: %s"),
3441 amprocForm->amprocnum,
3442 format_type_extended(amprocForm->amproclefttype,
3444 format_type_extended(amprocForm->amprocrighttype,
3446 opfam.data,
3447 format_procedure(amprocForm->amproc));
3448
3449 pfree(opfam.data);
3450
3453 break;
3454 }
3455
3456 case RewriteRelationId:
3457 {
3459 ScanKeyData skey[1];
3461 HeapTuple tup;
3463 StringInfoData rel;
3464
3466
3467 ScanKeyInit(&skey[0],
3470 ObjectIdGetDatum(object->objectId));
3471
3473 NULL, 1, skey);
3474
3476
3477 if (!HeapTupleIsValid(tup))
3478 {
3479 if (!missing_ok)
3480 elog(ERROR, "could not find tuple for rule %u",
3481 object->objectId);
3482
3485 break;
3486 }
3487
3489
3490 initStringInfo(&rel);
3491 getRelationDescription(&rel, rule->ev_class, false);
3492
3493 /* translator: second %s is, e.g., "table %s" */
3494 appendStringInfo(&buffer, _("rule %s on %s"),
3495 NameStr(rule->rulename), rel.data);
3496 pfree(rel.data);
3499 break;
3500 }
3501
3502 case TriggerRelationId:
3503 {
3505 ScanKeyData skey[1];
3507 HeapTuple tup;
3509 StringInfoData rel;
3510
3512
3513 ScanKeyInit(&skey[0],
3516 ObjectIdGetDatum(object->objectId));
3517
3519 NULL, 1, skey);
3520
3522
3523 if (!HeapTupleIsValid(tup))
3524 {
3525 if (!missing_ok)
3526 elog(ERROR, "could not find tuple for trigger %u",
3527 object->objectId);
3528
3531 break;
3532 }
3533
3535
3536 initStringInfo(&rel);
3537 getRelationDescription(&rel, trig->tgrelid, false);
3538
3539 /* translator: second %s is, e.g., "table %s" */
3540 appendStringInfo(&buffer, _("trigger %s on %s"),
3541 NameStr(trig->tgname), rel.data);
3542 pfree(rel.data);
3545 break;
3546 }
3547
3549 {
3550 char *nspname;
3551
3552 nspname = get_namespace_name(object->objectId);
3553 if (!nspname)
3554 {
3555 if (!missing_ok)
3556 elog(ERROR, "cache lookup failed for namespace %u",
3557 object->objectId);
3558 break;
3559 }
3560 appendStringInfo(&buffer, _("schema %s"), nspname);
3561 break;
3562 }
3563
3565 {
3568 char *nspname;
3569
3571 ObjectIdGetDatum(object->objectId));
3573 {
3574 if (!missing_ok)
3575 elog(ERROR, "could not find tuple for statistics object %u",
3576 object->objectId);
3577 break;
3578 }
3579
3581
3582 /* Qualify the name if not visible in search path */
3583 if (StatisticsObjIsVisible(object->objectId))
3584 nspname = NULL;
3585 else
3586 nspname = get_namespace_name(stxForm->stxnamespace);
3587
3588 appendStringInfo(&buffer, _("statistics object %s"),
3590 NameStr(stxForm->stxname)));
3591
3593 break;
3594 }
3595
3596 case TSParserRelationId:
3597 {
3598 HeapTuple tup;
3600 char *nspname;
3601
3603 ObjectIdGetDatum(object->objectId));
3604 if (!HeapTupleIsValid(tup))
3605 {
3606 if (!missing_ok)
3607 elog(ERROR, "cache lookup failed for text search parser %u",
3608 object->objectId);
3609 break;
3610 }
3612
3613 /* Qualify the name if not visible in search path */
3614 if (TSParserIsVisible(object->objectId))
3615 nspname = NULL;
3616 else
3617 nspname = get_namespace_name(prsForm->prsnamespace);
3618
3619 appendStringInfo(&buffer, _("text search parser %s"),
3621 NameStr(prsForm->prsname)));
3623 break;
3624 }
3625
3627 {
3628 HeapTuple tup;
3630 char *nspname;
3631
3633 ObjectIdGetDatum(object->objectId));
3634 if (!HeapTupleIsValid(tup))
3635 {
3636 if (!missing_ok)
3637 elog(ERROR, "cache lookup failed for text search dictionary %u",
3638 object->objectId);
3639 break;
3640 }
3641
3643
3644 /* Qualify the name if not visible in search path */
3645 if (TSDictionaryIsVisible(object->objectId))
3646 nspname = NULL;
3647 else
3648 nspname = get_namespace_name(dictForm->dictnamespace);
3649
3650 appendStringInfo(&buffer, _("text search dictionary %s"),
3652 NameStr(dictForm->dictname)));
3654 break;
3655 }
3656
3658 {
3659 HeapTuple tup;
3661 char *nspname;
3662
3664 ObjectIdGetDatum(object->objectId));
3665 if (!HeapTupleIsValid(tup))
3666 {
3667 if (!missing_ok)
3668 elog(ERROR, "cache lookup failed for text search template %u",
3669 object->objectId);
3670 break;
3671 }
3672
3674
3675 /* Qualify the name if not visible in search path */
3676 if (TSTemplateIsVisible(object->objectId))
3677 nspname = NULL;
3678 else
3679 nspname = get_namespace_name(tmplForm->tmplnamespace);
3680
3681 appendStringInfo(&buffer, _("text search template %s"),
3683 NameStr(tmplForm->tmplname)));
3685 break;
3686 }
3687
3688 case TSConfigRelationId:
3689 {
3690 HeapTuple tup;
3692 char *nspname;
3693
3695 ObjectIdGetDatum(object->objectId));
3696 if (!HeapTupleIsValid(tup))
3697 {
3698 if (!missing_ok)
3699 elog(ERROR, "cache lookup failed for text search configuration %u",
3700 object->objectId);
3701 break;
3702 }
3703
3705
3706 /* Qualify the name if not visible in search path */
3707 if (TSConfigIsVisible(object->objectId))
3708 nspname = NULL;
3709 else
3710 nspname = get_namespace_name(cfgForm->cfgnamespace);
3711
3712 appendStringInfo(&buffer, _("text search configuration %s"),
3714 NameStr(cfgForm->cfgname)));
3716 break;
3717 }
3718
3719 case AuthIdRelationId:
3720 {
3721 char *username = GetUserNameFromId(object->objectId,
3722 missing_ok);
3723
3724 if (username)
3725 appendStringInfo(&buffer, _("role %s"), username);
3726 break;
3727 }
3728
3729 case AuthMemRelationId:
3730 {
3732 ScanKeyData skey[1];
3734 HeapTuple tup;
3736
3738
3739 ScanKeyInit(&skey[0],
3742 ObjectIdGetDatum(object->objectId));
3743
3745 NULL, 1, skey);
3746
3748
3749 if (!HeapTupleIsValid(tup))
3750 {
3751 if (!missing_ok)
3752 elog(ERROR, "could not find tuple for role membership %u",
3753 object->objectId);
3754
3757 break;
3758 }
3759
3761
3762 appendStringInfo(&buffer, _("membership of role %s in role %s"),
3763 GetUserNameFromId(amForm->member, false),
3764 GetUserNameFromId(amForm->roleid, false));
3765
3768 break;
3769 }
3770
3771 case DatabaseRelationId:
3772 {
3773 char *datname;
3774
3776 if (!datname)
3777 {
3778 if (!missing_ok)
3779 elog(ERROR, "cache lookup failed for database %u",
3780 object->objectId);
3781 break;
3782 }
3783 appendStringInfo(&buffer, _("database %s"), datname);
3784 break;
3785 }
3786
3788 {
3789 char *tblspace;
3790
3792 if (!tblspace)
3793 {
3794 if (!missing_ok)
3795 elog(ERROR, "cache lookup failed for tablespace %u",
3796 object->objectId);
3797 break;
3798 }
3799 appendStringInfo(&buffer, _("tablespace %s"), tblspace);
3800 break;
3801 }
3802
3804 {
3806
3808 missing_ok);
3809 if (fdw)
3810 appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
3811 break;
3812 }
3813
3815 {
3817
3818 srv = GetForeignServerExtended(object->objectId, missing_ok);
3819 if (srv)
3820 appendStringInfo(&buffer, _("server %s"), srv->servername);
3821 break;
3822 }
3823
3825 {
3826 HeapTuple tup;
3827 Oid useid;
3828 char *usename;
3831
3833 ObjectIdGetDatum(object->objectId));
3834 if (!HeapTupleIsValid(tup))
3835 {
3836 if (!missing_ok)
3837 elog(ERROR, "cache lookup failed for user mapping %u",
3838 object->objectId);
3839 break;
3840 }
3841
3843 useid = umform->umuser;
3844 srv = GetForeignServer(umform->umserver);
3845
3847
3848 if (OidIsValid(useid))
3850 else
3851 usename = "public";
3852
3853 appendStringInfo(&buffer, _("user mapping for %s on server %s"), usename,
3854 srv->servername);
3855 break;
3856 }
3857
3859 {
3861 ScanKeyData skey[1];
3863 HeapTuple tup;
3865 char *rolename;
3866 char *nspname;
3867
3869
3870 ScanKeyInit(&skey[0],
3873 ObjectIdGetDatum(object->objectId));
3874
3876 true, NULL, 1, skey);
3877
3879
3880 if (!HeapTupleIsValid(tup))
3881 {
3882 if (!missing_ok)
3883 elog(ERROR, "could not find tuple for default ACL %u",
3884 object->objectId);
3885
3888 break;
3889 }
3890
3892
3893 rolename = GetUserNameFromId(defacl->defaclrole, false);
3894
3895 if (OidIsValid(defacl->defaclnamespace))
3896 nspname = get_namespace_name(defacl->defaclnamespace);
3897 else
3898 nspname = NULL;
3899
3900 switch (defacl->defaclobjtype)
3901 {
3902 case DEFACLOBJ_RELATION:
3903 if (nspname)
3904 appendStringInfo(&buffer,
3905 _("default privileges on new relations belonging to role %s in schema %s"),
3906 rolename, nspname);
3907 else
3908 appendStringInfo(&buffer,
3909 _("default privileges on new relations belonging to role %s"),
3910 rolename);
3911 break;
3912 case DEFACLOBJ_SEQUENCE:
3913 if (nspname)
3914 appendStringInfo(&buffer,
3915 _("default privileges on new sequences belonging to role %s in schema %s"),
3916 rolename, nspname);
3917 else
3918 appendStringInfo(&buffer,
3919 _("default privileges on new sequences belonging to role %s"),
3920 rolename);
3921 break;
3922 case DEFACLOBJ_FUNCTION:
3923 if (nspname)
3924 appendStringInfo(&buffer,
3925 _("default privileges on new functions belonging to role %s in schema %s"),
3926 rolename, nspname);
3927 else
3928 appendStringInfo(&buffer,
3929 _("default privileges on new functions belonging to role %s"),
3930 rolename);
3931 break;
3932 case DEFACLOBJ_TYPE:
3933 if (nspname)
3934 appendStringInfo(&buffer,
3935 _("default privileges on new types belonging to role %s in schema %s"),
3936 rolename, nspname);
3937 else
3938 appendStringInfo(&buffer,
3939 _("default privileges on new types belonging to role %s"),
3940 rolename);
3941 break;
3943 Assert(!nspname);
3944 appendStringInfo(&buffer,
3945 _("default privileges on new schemas belonging to role %s"),
3946 rolename);
3947 break;
3949 Assert(!nspname);
3950 appendStringInfo(&buffer,
3951 _("default privileges on new large objects belonging to role %s"),
3952 rolename);
3953 break;
3954 default:
3955 /* shouldn't get here */
3956 if (nspname)
3957 appendStringInfo(&buffer,
3958 _("default privileges belonging to role %s in schema %s"),
3959 rolename, nspname);
3960 else
3961 appendStringInfo(&buffer,
3962 _("default privileges belonging to role %s"),
3963 rolename);
3964 break;
3965 }
3966
3969 break;
3970 }
3971
3973 {
3974 char *extname;
3975
3976 extname = get_extension_name(object->objectId);
3977 if (!extname)
3978 {
3979 if (!missing_ok)
3980 elog(ERROR, "cache lookup failed for extension %u",
3981 object->objectId);
3982 break;
3983 }
3984 appendStringInfo(&buffer, _("extension %s"), extname);
3985 break;
3986 }
3987
3989 {
3990 HeapTuple tup;
3991
3993 ObjectIdGetDatum(object->objectId));
3994 if (!HeapTupleIsValid(tup))
3995 {
3996 if (!missing_ok)
3997 elog(ERROR, "cache lookup failed for event trigger %u",
3998 object->objectId);
3999 break;
4000 }
4001 appendStringInfo(&buffer, _("event trigger %s"),
4004 break;
4005 }
4006
4008 {
4009 HeapTuple tup;
4011 char *parname;
4012
4014 ObjectIdGetDatum(object->objectId));
4015 if (!HeapTupleIsValid(tup))
4016 {
4017 if (!missing_ok)
4018 elog(ERROR, "cache lookup failed for parameter ACL %u",
4019 object->objectId);
4020 break;
4021 }
4025 appendStringInfo(&buffer, _("parameter %s"), parname);
4027 break;
4028 }
4029
4030 case PolicyRelationId:
4031 {
4033 ScanKeyData skey[1];
4035 HeapTuple tuple;
4037 StringInfoData rel;
4038
4040
4041 ScanKeyInit(&skey[0],
4044 ObjectIdGetDatum(object->objectId));
4045
4047 true, NULL, 1, skey);
4048
4049 tuple = systable_getnext(sscan);
4050
4051 if (!HeapTupleIsValid(tuple))
4052 {
4053 if (!missing_ok)
4054 elog(ERROR, "could not find tuple for policy %u",
4055 object->objectId);
4056
4059 break;
4060 }
4061
4063
4064 initStringInfo(&rel);
4065 getRelationDescription(&rel, form_policy->polrelid, false);
4066
4067 /* translator: second %s is, e.g., "table %s" */
4068 appendStringInfo(&buffer, _("policy %s on %s"),
4069 NameStr(form_policy->polname), rel.data);
4070 pfree(rel.data);
4073 break;
4074 }
4075
4077 {
4078 HeapTuple tup;
4080
4082 if (!HeapTupleIsValid(tup))
4083 {
4084 if (!missing_ok)
4085 elog(ERROR, "cache lookup failed for property graph element %u",
4086 object->objectId);
4087 break;
4088 }
4089
4091
4092 if (pgeform->pgekind == PGEKIND_VERTEX)
4093 /* translator: followed by, e.g., "property graph %s" */
4094 appendStringInfo(&buffer, _("vertex %s of "), NameStr(pgeform->pgealias));
4095 else if (pgeform->pgekind == PGEKIND_EDGE)
4096 /* translator: followed by, e.g., "property graph %s" */
4097 appendStringInfo(&buffer, _("edge %s of "), NameStr(pgeform->pgealias));
4098 else
4099 appendStringInfo(&buffer, "??? element %s of ", NameStr(pgeform->pgealias));
4100 getRelationDescription(&buffer, pgeform->pgepgid, false);
4101
4103 break;
4104 }
4105
4107 {
4108 Relation rel;
4109 HeapTuple tuple;
4112
4114 tuple = get_catalog_object_by_oid(rel,
4116 object->objectId);
4117 if (!HeapTupleIsValid(tuple))
4118 {
4119 if (!missing_ok)
4120 elog(ERROR, "could not find tuple for element label %u", object->objectId);
4121
4123 break;
4124 }
4125
4127
4128 appendStringInfo(&buffer, _("label %s of "), get_propgraph_label_name(pgelform->pgellabelid));
4131
4133 break;
4134 }
4135
4137 {
4138 HeapTuple tuple;
4140
4142 if (!HeapTupleIsValid(tuple))
4143 {
4144 if (!missing_ok)
4145 elog(ERROR, "could not find tuple for label %u", object->objectId);
4146 break;
4147 }
4148
4150
4151 /* translator: followed by, e.g., "property graph %s" */
4152 appendStringInfo(&buffer, _("label %s of "), NameStr(pglform->pgllabel));
4153 getRelationDescription(&buffer, pglform->pglpgid, false);
4154 ReleaseSysCache(tuple);
4155 break;
4156 }
4157
4159 {
4160 Relation rel;
4161 HeapTuple tuple;
4164
4166 tuple = get_catalog_object_by_oid(rel,
4168 object->objectId);
4169 if (!HeapTupleIsValid(tuple))
4170 {
4171 if (!missing_ok)
4172 elog(ERROR, "could not find tuple for label property %u", object->objectId);
4173
4175 break;
4176 }
4177
4179
4180 appendStringInfo(&buffer, _("property %s of "), get_propgraph_property_name(plpform->plppropid));
4183
4185 break;
4186 }
4187
4189 {
4190 HeapTuple tuple;
4192
4194 if (!HeapTupleIsValid(tuple))
4195 {
4196 if (!missing_ok)
4197 elog(ERROR, "could not find tuple for property %u", object->objectId);
4198 break;
4199 }
4200
4202
4203 /* translator: followed by, e.g., "property graph %s" */
4204 appendStringInfo(&buffer, _("property %s of "), NameStr(pgpform->pgpname));
4205 getRelationDescription(&buffer, pgpform->pgppgid, false);
4206 ReleaseSysCache(tuple);
4207 break;
4208 }
4209
4211 {
4212 char *pubname = get_publication_name(object->objectId,
4213 missing_ok);
4214
4215 if (pubname)
4216 appendStringInfo(&buffer, _("publication %s"), pubname);
4217 break;
4218 }
4219
4221 {
4222 char *pubname;
4223 char *nspname;
4224
4225 if (!getPublicationSchemaInfo(object, missing_ok,
4226 &pubname, &nspname))
4227 break;
4228
4229 appendStringInfo(&buffer, _("publication of schema %s in publication %s"),
4230 nspname, pubname);
4231 pfree(pubname);
4232 pfree(nspname);
4233 break;
4234 }
4235
4237 {
4238 HeapTuple tup;
4239 char *pubname;
4241 StringInfoData rel;
4242
4244 ObjectIdGetDatum(object->objectId));
4245 if (!HeapTupleIsValid(tup))
4246 {
4247 if (!missing_ok)
4248 elog(ERROR, "cache lookup failed for publication table %u",
4249 object->objectId);
4250 break;
4251 }
4252
4254 pubname = get_publication_name(prform->prpubid, false);
4255
4256 initStringInfo(&rel);
4257 getRelationDescription(&rel, prform->prrelid, false);
4258
4259 /* translator: first %s is, e.g., "table %s" */
4260 appendStringInfo(&buffer, _("publication of %s in publication %s"),
4261 rel.data, pubname);
4262 pfree(rel.data);
4264 break;
4265 }
4266
4268 {
4269 char *subname = get_subscription_name(object->objectId,
4270 missing_ok);
4271
4272 if (subname)
4273 appendStringInfo(&buffer, _("subscription %s"), subname);
4274 break;
4275 }
4276
4278 {
4281
4283 ObjectIdGetDatum(object->objectId));
4285 {
4286 if (!missing_ok)
4287 elog(ERROR, "could not find tuple for transform %u",
4288 object->objectId);
4289 break;
4290 }
4291
4293
4294 appendStringInfo(&buffer, _("transform for %s language %s"),
4295 format_type_be(trfForm->trftype),
4296 get_language_name(trfForm->trflang, false));
4297
4299 break;
4300 }
4301
4302 default:
4303 elog(ERROR, "unsupported object class: %u", object->classId);
4304 }
4305
4306 /* an empty buffer is equivalent to no object found */
4307 if (buffer.len == 0)
4308 return NULL;
4309
4310 return buffer.data;
4311}
4312
4313/*
4314 * getObjectDescriptionOids: as above, except the object is specified by Oids
4315 */
4316char *
4318{
4319 ObjectAddress address;
4320
4321 address.classId = classid;
4322 address.objectId = objid;
4323 address.objectSubId = 0;
4324
4325 return getObjectDescription(&address, false);
4326}
4327
4328/*
4329 * subroutine for getObjectDescription: describe a relation
4330 *
4331 * The result is appended to "buffer".
4332 */
4333static void
4334getRelationDescription(StringInfo buffer, Oid relid, bool missing_ok)
4335{
4338 char *nspname;
4339 char *relname;
4340
4342 ObjectIdGetDatum(relid));
4344 {
4345 if (!missing_ok)
4346 elog(ERROR, "cache lookup failed for relation %u", relid);
4347 return;
4348 }
4350
4351 /* Qualify the name if not visible in search path */
4352 if (RelationIsVisible(relid))
4353 nspname = NULL;
4354 else
4355 nspname = get_namespace_name(relForm->relnamespace);
4356
4357 relname = quote_qualified_identifier(nspname, NameStr(relForm->relname));
4358
4359 switch (relForm->relkind)
4360 {
4361 case RELKIND_RELATION:
4363 appendStringInfo(buffer, _("table %s"),
4364 relname);
4365 break;
4366 case RELKIND_INDEX:
4368 appendStringInfo(buffer, _("index %s"),
4369 relname);
4370 break;
4371 case RELKIND_SEQUENCE:
4372 appendStringInfo(buffer, _("sequence %s"),
4373 relname);
4374 break;
4375 case RELKIND_TOASTVALUE:
4376 appendStringInfo(buffer, _("toast table %s"),
4377 relname);
4378 break;
4379 case RELKIND_VIEW:
4380 appendStringInfo(buffer, _("view %s"),
4381 relname);
4382 break;
4383 case RELKIND_MATVIEW:
4384 appendStringInfo(buffer, _("materialized view %s"),
4385 relname);
4386 break;
4388 appendStringInfo(buffer, _("composite type %s"),
4389 relname);
4390 break;
4392 appendStringInfo(buffer, _("foreign table %s"),
4393 relname);
4394 break;
4395 case RELKIND_PROPGRAPH:
4396 appendStringInfo(buffer, _("property graph %s"),
4397 relname);
4398 break;
4399 default:
4400 /* shouldn't get here */
4401 appendStringInfo(buffer, _("relation %s"),
4402 relname);
4403 break;
4404 }
4405
4407}
4408
4409/*
4410 * subroutine for getObjectDescription: describe an operator family
4411 */
4412static void
4414{
4419 char *nspname;
4420
4423 {
4424 if (!missing_ok)
4425 elog(ERROR, "cache lookup failed for opfamily %u", opfid);
4426 return;
4427 }
4429
4431 if (!HeapTupleIsValid(amTup))
4432 elog(ERROR, "cache lookup failed for access method %u",
4433 opfForm->opfmethod);
4435
4436 /* Qualify the name if not visible in search path */
4438 nspname = NULL;
4439 else
4440 nspname = get_namespace_name(opfForm->opfnamespace);
4441
4442 appendStringInfo(buffer, _("operator family %s for access method %s"),
4444 NameStr(opfForm->opfname)),
4445 NameStr(amForm->amname));
4446
4449}
4450
4451/*
4452 * SQL-level callable version of getObjectDescription
4453 */
4454Datum
4456{
4457 Oid classid = PG_GETARG_OID(0);
4458 Oid objid = PG_GETARG_OID(1);
4459 int32 objsubid = PG_GETARG_INT32(2);
4460 char *description;
4461 ObjectAddress address;
4462
4463 /* for "pinned" items in pg_depend, return null */
4464 if (!OidIsValid(classid) && !OidIsValid(objid))
4466
4467 address.classId = classid;
4468 address.objectId = objid;
4469 address.objectSubId = objsubid;
4470
4471 description = getObjectDescription(&address, true);
4472
4473 if (description == NULL)
4475
4477}
4478
4479/*
4480 * SQL-level callable function to obtain object type + identity
4481 */
4482Datum
4484{
4485 Oid classid = PG_GETARG_OID(0);
4486 Oid objid = PG_GETARG_OID(1);
4487 int32 objsubid = PG_GETARG_INT32(2);
4489 const char *objname = NULL;
4490 char *objidentity;
4491 ObjectAddress address;
4492 Datum values[4];
4493 bool nulls[4];
4494 TupleDesc tupdesc;
4495 HeapTuple htup;
4496
4497 address.classId = classid;
4498 address.objectId = objid;
4499 address.objectSubId = objsubid;
4500
4501 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
4502 elog(ERROR, "return type must be a row type");
4503
4504 if (is_objectclass_supported(address.classId))
4505 {
4508
4511 address.objectId);
4512 if (objtup != NULL)
4513 {
4514 bool isnull;
4517
4520 {
4522 RelationGetDescr(catalog), &isnull));
4523 if (isnull)
4524 elog(ERROR, "invalid null namespace in object %u/%u/%d",
4525 address.classId, address.objectId, address.objectSubId);
4526 }
4527
4528 /*
4529 * We only return the object name if it can be used (together with
4530 * the schema name, if any) as a unique identifier.
4531 */
4533 {
4536 {
4538
4540 RelationGetDescr(catalog), &isnull);
4541 if (isnull)
4542 elog(ERROR, "invalid null name in object %u/%u/%d",
4543 address.classId, address.objectId, address.objectSubId);
4545 }
4546 }
4547 }
4548
4550 }
4551
4552 /* object type, which can never be NULL */
4554 nulls[0] = false;
4555
4556 /*
4557 * Before doing anything, extract the object identity. If the identity
4558 * could not be found, set all the fields except the object type to NULL.
4559 */
4560 objidentity = getObjectIdentity(&address, true);
4561
4562 /* schema name */
4563 if (OidIsValid(schema_oid) && objidentity)
4564 {
4565 const char *schema = quote_identifier(get_namespace_name(schema_oid));
4566
4567 values[1] = CStringGetTextDatum(schema);
4568 nulls[1] = false;
4569 }
4570 else
4571 nulls[1] = true;
4572
4573 /* object name */
4574 if (objname && objidentity)
4575 {
4576 values[2] = CStringGetTextDatum(objname);
4577 nulls[2] = false;
4578 }
4579 else
4580 nulls[2] = true;
4581
4582 /* object identity */
4583 if (objidentity)
4584 {
4585 values[3] = CStringGetTextDatum(objidentity);
4586 nulls[3] = false;
4587 }
4588 else
4589 nulls[3] = true;
4590
4591 htup = heap_form_tuple(tupdesc, values, nulls);
4592
4594}
4595
4596/*
4597 * SQL-level callable function to obtain object type + identity
4598 */
4599Datum
4601{
4602 Oid classid = PG_GETARG_OID(0);
4603 Oid objid = PG_GETARG_OID(1);
4604 int32 objsubid = PG_GETARG_INT32(2);
4605 ObjectAddress address;
4606 char *identity;
4607 List *names;
4608 List *args;
4609 Datum values[3];
4610 bool nulls[3];
4611 TupleDesc tupdesc;
4612 HeapTuple htup;
4613
4614 address.classId = classid;
4615 address.objectId = objid;
4616 address.objectSubId = objsubid;
4617
4618 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
4619 elog(ERROR, "return type must be a row type");
4620
4621 /* object type, which can never be NULL */
4623 nulls[0] = false;
4624
4625 /* object identity */
4626 identity = getObjectIdentityParts(&address, &names, &args, true);
4627 if (identity == NULL)
4628 {
4629 nulls[1] = true;
4630 nulls[2] = true;
4631 }
4632 else
4633 {
4634 pfree(identity);
4635
4636 /* object_names */
4637 if (names != NIL)
4639 else
4641 nulls[1] = false;
4642
4643 /* object_args */
4644 if (args)
4646 else
4648 nulls[2] = false;
4649 }
4650
4651 htup = heap_form_tuple(tupdesc, values, nulls);
4652
4654}
4655
4656/*
4657 * SQL-level callable function to obtain the ACL of a specified object, given
4658 * its catalog OID, object OID and sub-object ID.
4659 */
4660Datum
4662{
4663 Oid classId = PG_GETARG_OID(0);
4664 Oid objectId = PG_GETARG_OID(1);
4665 int32 objsubid = PG_GETARG_INT32(2);
4666 Oid catalogId;
4668 Datum datum;
4669 bool isnull;
4670 HeapTuple tup;
4671
4672 /* for "pinned" items in pg_depend, return null */
4673 if (!OidIsValid(classId) && !OidIsValid(objectId))
4675
4676 /* for large objects, the catalog to look at is pg_largeobject_metadata */
4677 catalogId = (classId == LargeObjectRelationId) ?
4679 Anum_acl = get_object_attnum_acl(catalogId);
4680
4681 /* return NULL if no ACL field for this catalog */
4684
4685 /*
4686 * If dealing with a relation's attribute (objsubid is set), the ACL is
4687 * retrieved from pg_attribute.
4688 */
4689 if (classId == RelationRelationId && objsubid != 0)
4690 {
4691 AttrNumber attnum = (AttrNumber) objsubid;
4692
4693 tup = SearchSysCacheCopyAttNum(objectId, attnum);
4694
4695 if (!HeapTupleIsValid(tup))
4697
4699 &isnull);
4700 }
4701 else
4702 {
4703 Relation rel;
4704
4705 rel = table_open(catalogId, AccessShareLock);
4706
4708 objectId);
4709 if (!HeapTupleIsValid(tup))
4710 {
4713 }
4714
4715 datum = heap_getattr(tup, Anum_acl, RelationGetDescr(rel), &isnull);
4717 }
4718
4719 if (isnull)
4721
4722 PG_RETURN_DATUM(datum);
4723}
4724
4725/*
4726 * Return a palloc'ed string that describes the type of object that the
4727 * passed address is for.
4728 *
4729 * Keep ObjectTypeMap in sync with this.
4730 */
4731char *
4732getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
4733{
4734 StringInfoData buffer;
4735
4736 initStringInfo(&buffer);
4737
4738 switch (object->classId)
4739 {
4740 case RelationRelationId:
4741 getRelationTypeDescription(&buffer, object->objectId,
4742 object->objectSubId,
4743 missing_ok);
4744 break;
4745
4747 getProcedureTypeDescription(&buffer, object->objectId,
4748 missing_ok);
4749 break;
4750
4751 case TypeRelationId:
4752 appendStringInfoString(&buffer, "type");
4753 break;
4754
4755 case CastRelationId:
4756 appendStringInfoString(&buffer, "cast");
4757 break;
4758
4760 appendStringInfoString(&buffer, "collation");
4761 break;
4762
4764 getConstraintTypeDescription(&buffer, object->objectId,
4765 missing_ok);
4766 break;
4767
4769 appendStringInfoString(&buffer, "conversion");
4770 break;
4771
4773 appendStringInfoString(&buffer, "default value");
4774 break;
4775
4776 case LanguageRelationId:
4777 appendStringInfoString(&buffer, "language");
4778 break;
4779
4781 appendStringInfoString(&buffer, "large object");
4782 break;
4783
4784 case OperatorRelationId:
4785 appendStringInfoString(&buffer, "operator");
4786 break;
4787
4789 appendStringInfoString(&buffer, "operator class");
4790 break;
4791
4793 appendStringInfoString(&buffer, "operator family");
4794 break;
4795
4797 appendStringInfoString(&buffer, "access method");
4798 break;
4799
4801 appendStringInfoString(&buffer, "operator of access method");
4802 break;
4803
4805 appendStringInfoString(&buffer, "function of access method");
4806 break;
4807
4808 case RewriteRelationId:
4809 appendStringInfoString(&buffer, "rule");
4810 break;
4811
4812 case TriggerRelationId:
4813 appendStringInfoString(&buffer, "trigger");
4814 break;
4815
4817 appendStringInfoString(&buffer, "schema");
4818 break;
4819
4821 appendStringInfoString(&buffer, "statistics object");
4822 break;
4823
4824 case TSParserRelationId:
4825 appendStringInfoString(&buffer, "text search parser");
4826 break;
4827
4829 appendStringInfoString(&buffer, "text search dictionary");
4830 break;
4831
4833 appendStringInfoString(&buffer, "text search template");
4834 break;
4835
4836 case TSConfigRelationId:
4837 appendStringInfoString(&buffer, "text search configuration");
4838 break;
4839
4840 case AuthIdRelationId:
4841 appendStringInfoString(&buffer, "role");
4842 break;
4843
4844 case AuthMemRelationId:
4845 appendStringInfoString(&buffer, "role membership");
4846 break;
4847
4848 case DatabaseRelationId:
4849 appendStringInfoString(&buffer, "database");
4850 break;
4851
4853 appendStringInfoString(&buffer, "tablespace");
4854 break;
4855
4857 appendStringInfoString(&buffer, "foreign-data wrapper");
4858 break;
4859
4861 appendStringInfoString(&buffer, "server");
4862 break;
4863
4865 appendStringInfoString(&buffer, "user mapping");
4866 break;
4867
4869 appendStringInfoString(&buffer, "default acl");
4870 break;
4871
4873 appendStringInfoString(&buffer, "extension");
4874 break;
4875
4877 appendStringInfoString(&buffer, "event trigger");
4878 break;
4879
4881 appendStringInfoString(&buffer, "parameter ACL");
4882 break;
4883
4884 case PolicyRelationId:
4885 appendStringInfoString(&buffer, "policy");
4886 break;
4887
4889 appendStringInfoString(&buffer, "property graph element");
4890 break;
4891
4893 appendStringInfoString(&buffer, "property graph label");
4894 break;
4895
4897 appendStringInfoString(&buffer, "property graph property");
4898 break;
4899
4901 appendStringInfoString(&buffer, "publication");
4902 break;
4903
4905 appendStringInfoString(&buffer, "publication namespace");
4906 break;
4907
4909 appendStringInfoString(&buffer, "publication relation");
4910 break;
4911
4913 appendStringInfoString(&buffer, "subscription");
4914 break;
4915
4917 appendStringInfoString(&buffer, "transform");
4918 break;
4919
4920 default:
4921 elog(ERROR, "unsupported object class: %u", object->classId);
4922 }
4923
4924 /* the result can never be empty */
4925 Assert(buffer.len > 0);
4926
4927 return buffer.data;
4928}
4929
4930/*
4931 * subroutine for getObjectTypeDescription: describe a relation type
4932 */
4933static void
4935 bool missing_ok)
4936{
4939
4941 ObjectIdGetDatum(relid));
4943 {
4944 if (!missing_ok)
4945 elog(ERROR, "cache lookup failed for relation %u", relid);
4946
4947 /* fallback to "relation" for an undefined object */
4948 appendStringInfoString(buffer, "relation");
4949 return;
4950 }
4952
4953 switch (relForm->relkind)
4954 {
4955 case RELKIND_RELATION:
4957 appendStringInfoString(buffer, "table");
4958 break;
4959 case RELKIND_INDEX:
4961 appendStringInfoString(buffer, "index");
4962 break;
4963 case RELKIND_SEQUENCE:
4964 appendStringInfoString(buffer, "sequence");
4965 break;
4966 case RELKIND_TOASTVALUE:
4967 appendStringInfoString(buffer, "toast table");
4968 break;
4969 case RELKIND_VIEW:
4970 appendStringInfoString(buffer, "view");
4971 break;
4972 case RELKIND_MATVIEW:
4973 appendStringInfoString(buffer, "materialized view");
4974 break;
4976 appendStringInfoString(buffer, "composite type");
4977 break;
4979 appendStringInfoString(buffer, "foreign table");
4980 break;
4981 case RELKIND_PROPGRAPH:
4982 appendStringInfoString(buffer, "property graph");
4983 break;
4984 default:
4985 /* shouldn't get here */
4986 appendStringInfoString(buffer, "relation");
4987 break;
4988 }
4989
4990 if (objectSubId != 0)
4991 appendStringInfoString(buffer, " column");
4992
4994}
4995
4996/*
4997 * subroutine for getObjectTypeDescription: describe a constraint type
4998 */
4999static void
5001{
5005
5008 constroid);
5010 {
5011 if (!missing_ok)
5012 elog(ERROR, "cache lookup failed for constraint %u", constroid);
5013
5015
5016 /* fallback to "constraint" for an undefined object */
5017 appendStringInfoString(buffer, "constraint");
5018 return;
5019 }
5020
5022
5023 if (OidIsValid(constrForm->conrelid))
5024 appendStringInfoString(buffer, "table constraint");
5025 else if (OidIsValid(constrForm->contypid))
5026 appendStringInfoString(buffer, "domain constraint");
5027 else
5028 elog(ERROR, "invalid constraint %u", constrForm->oid);
5029
5031}
5032
5033/*
5034 * subroutine for getObjectTypeDescription: describe a procedure type
5035 */
5036static void
5038 bool missing_ok)
5039{
5042
5044 ObjectIdGetDatum(procid));
5046 {
5047 if (!missing_ok)
5048 elog(ERROR, "cache lookup failed for procedure %u", procid);
5049
5050 /* fallback to "procedure" for an undefined object */
5051 appendStringInfoString(buffer, "routine");
5052 return;
5053 }
5055
5056 if (procForm->prokind == PROKIND_AGGREGATE)
5057 appendStringInfoString(buffer, "aggregate");
5058 else if (procForm->prokind == PROKIND_PROCEDURE)
5059 appendStringInfoString(buffer, "procedure");
5060 else /* function or window function */
5061 appendStringInfoString(buffer, "function");
5062
5064}
5065
5066/*
5067 * Obtain a given object's identity, as a palloc'ed string.
5068 *
5069 * This is for machine consumption, so it's not translated. All elements are
5070 * schema-qualified when appropriate. Returns NULL if the object could not
5071 * be found.
5072 */
5073char *
5074getObjectIdentity(const ObjectAddress *object, bool missing_ok)
5075{
5076 return getObjectIdentityParts(object, NULL, NULL, missing_ok);
5077}
5078
5079/*
5080 * As above, but more detailed.
5081 *
5082 * There are two sets of return values: the identity itself as a palloc'd
5083 * string is returned. objname and objargs, if not NULL, are output parameters
5084 * that receive lists of C-strings that are useful to give back to
5085 * get_object_address() to reconstruct the ObjectAddress. Returns NULL if
5086 * the object could not be found.
5087 */
5088char *
5090 List **objname, List **objargs,
5091 bool missing_ok)
5092{
5093 StringInfoData buffer;
5094
5095 initStringInfo(&buffer);
5096
5097 /*
5098 * Make sure that both objname and objargs were passed, or none was; and
5099 * initialize them to empty lists. For objname this is useless because it
5100 * will be initialized in all cases inside the switch; but we do it anyway
5101 * so that we can test below that no branch leaves it unset.
5102 */
5103 Assert((objname != NULL) == (objargs != NULL));
5104 if (objname)
5105 {
5106 *objname = NIL;
5107 *objargs = NIL;
5108 }
5109
5110 switch (object->classId)
5111 {
5112 case RelationRelationId:
5113 {
5114 char *attr = NULL;
5115
5116 /*
5117 * Check for the attribute first, so as if it is missing we
5118 * can skip the entire relation description.
5119 */
5120 if (object->objectSubId != 0)
5121 {
5122 attr = get_attname(object->objectId,
5123 object->objectSubId,
5124 missing_ok);
5125
5126 if (missing_ok && attr == NULL)
5127 break;
5128 }
5129
5130 getRelationIdentity(&buffer, object->objectId, objname,
5131 missing_ok);
5132 if (objname && *objname == NIL)
5133 break;
5134
5135 if (attr)
5136 {
5137 appendStringInfo(&buffer, ".%s",
5138 quote_identifier(attr));
5139 if (objname)
5140 *objname = lappend(*objname, attr);
5141 }
5142 }
5143 break;
5144
5146 {
5149 flags);
5150
5151 if (proname == NULL)
5152 break;
5153
5155 if (objname)
5156 format_procedure_parts(object->objectId, objname, objargs,
5157 missing_ok);
5158 break;
5159 }
5160
5161 case TypeRelationId:
5162 {
5164 char *typeout;
5165
5166 typeout = format_type_extended(object->objectId, -1, flags);
5167
5168 if (typeout == NULL)
5169 break;
5170
5172 if (objname)
5173 *objname = list_make1(typeout);
5174 }
5175 break;
5176
5177 case CastRelationId:
5178 {
5180 HeapTuple tup;
5182
5184
5186 object->objectId);
5187
5188 if (!HeapTupleIsValid(tup))
5189 {
5190 if (!missing_ok)
5191 elog(ERROR, "could not find tuple for cast %u",
5192 object->objectId);
5193
5195 break;
5196 }
5197
5199
5200 appendStringInfo(&buffer, "(%s AS %s)",
5202 format_type_be_qualified(castForm->casttarget));
5203
5204 if (objname)
5205 {
5206 *objname = list_make1(format_type_be_qualified(castForm->castsource));
5207 *objargs = list_make1(format_type_be_qualified(castForm->casttarget));
5208 }
5209
5211 break;
5212 }
5213
5215 {
5217 Form_pg_collation coll;
5218 char *schema;
5219
5221 ObjectIdGetDatum(object->objectId));
5223 {
5224 if (!missing_ok)
5225 elog(ERROR, "cache lookup failed for collation %u",
5226 object->objectId);
5227 break;
5228 }
5230 schema = get_namespace_name_or_temp(coll->collnamespace);
5231 appendStringInfoString(&buffer,
5233 NameStr(coll->collname)));
5234 if (objname)
5235 *objname = list_make2(schema,
5236 pstrdup(NameStr(coll->collname)));
5238 break;
5239 }
5240
5242 {
5245
5247 ObjectIdGetDatum(object->objectId));
5249 {
5250 if (!missing_ok)
5251 elog(ERROR, "cache lookup failed for constraint %u",
5252 object->objectId);
5253 break;
5254 }
5256
5257 if (OidIsValid(con->conrelid))
5258 {
5259 appendStringInfo(&buffer, "%s on ",
5260 quote_identifier(NameStr(con->conname)));
5261 getRelationIdentity(&buffer, con->conrelid, objname,
5262 false);
5263 if (objname)
5264 *objname = lappend(*objname, pstrdup(NameStr(con->conname)));
5265 }
5266 else
5267 {
5268 ObjectAddress domain;
5269
5270 Assert(OidIsValid(con->contypid));
5271 domain.classId = TypeRelationId;
5272 domain.objectId = con->contypid;
5273 domain.objectSubId = 0;
5274
5275 appendStringInfo(&buffer, "%s on %s",
5276 quote_identifier(NameStr(con->conname)),
5277 getObjectIdentityParts(&domain, objname,
5278 objargs, false));
5279
5280 if (objname)
5281 *objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
5282 }
5283
5285 break;
5286 }
5287
5289 {
5292 char *schema;
5293
5295 ObjectIdGetDatum(object->objectId));
5297 {
5298 if (!missing_ok)
5299 elog(ERROR, "cache lookup failed for conversion %u",
5300 object->objectId);
5301 break;
5302 }
5304 schema = get_namespace_name_or_temp(conForm->connamespace);
5305 appendStringInfoString(&buffer,
5307 NameStr(conForm->conname)));
5308 if (objname)
5309 *objname = list_make2(schema,
5310 pstrdup(NameStr(conForm->conname)));
5312 break;
5313 }
5314
5316 {
5318
5320
5321 if (!OidIsValid(colobject.objectId))
5322 {
5323 if (!missing_ok)
5324 elog(ERROR, "could not find tuple for attrdef %u",
5325 object->objectId);
5326 break;
5327 }
5328
5329 appendStringInfo(&buffer, "for %s",
5331 objname, objargs,
5332 false));
5333 break;
5334 }
5335
5336 case LanguageRelationId:
5337 {
5340
5342 ObjectIdGetDatum(object->objectId));
5344 {
5345 if (!missing_ok)
5346 elog(ERROR, "cache lookup failed for language %u",
5347 object->objectId);
5348 break;
5349 }
5351 appendStringInfoString(&buffer,
5352 quote_identifier(NameStr(langForm->lanname)));
5353 if (objname)
5354 *objname = list_make1(pstrdup(NameStr(langForm->lanname)));
5356 break;
5357 }
5358
5360 if (!LargeObjectExists(object->objectId))
5361 break;
5362 appendStringInfo(&buffer, "%u",
5363 object->objectId);
5364 if (objname)
5365 *objname = list_make1(psprintf("%u", object->objectId));
5366 break;
5367
5368 case OperatorRelationId:
5369 {
5371 char *oprname = format_operator_extended(object->objectId,
5372 flags);
5373
5374 if (oprname == NULL)
5375 break;
5376
5377 appendStringInfoString(&buffer, oprname);
5378 if (objname)
5379 format_operator_parts(object->objectId, objname, objargs, missing_ok);
5380 break;
5381 }
5382
5384 {
5389 char *schema;
5390
5392 ObjectIdGetDatum(object->objectId));
5394 {
5395 if (!missing_ok)
5396 elog(ERROR, "cache lookup failed for opclass %u",
5397 object->objectId);
5398 break;
5399 }
5401 schema = get_namespace_name_or_temp(opcForm->opcnamespace);
5402
5404 ObjectIdGetDatum(opcForm->opcmethod));
5405 if (!HeapTupleIsValid(amTup))
5406 elog(ERROR, "cache lookup failed for access method %u",
5407 opcForm->opcmethod);
5409
5410 appendStringInfo(&buffer, "%s USING %s",
5412 NameStr(opcForm->opcname)),
5413 quote_identifier(NameStr(amForm->amname)));
5414 if (objname)
5415 *objname = list_make3(pstrdup(NameStr(amForm->amname)),
5416 schema,
5417 pstrdup(NameStr(opcForm->opcname)));
5418
5421 break;
5422 }
5423
5425 getOpFamilyIdentity(&buffer, object->objectId, objname,
5426 missing_ok);
5427 break;
5428
5430 {
5431 char *amname;
5432
5433 amname = get_am_name(object->objectId);
5434 if (!amname)
5435 {
5436 if (!missing_ok)
5437 elog(ERROR, "cache lookup failed for access method %u",
5438 object->objectId);
5439 break;
5440 }
5441 appendStringInfoString(&buffer, quote_identifier(amname));
5442 if (objname)
5443 *objname = list_make1(amname);
5444 }
5445 break;
5446
5448 {
5450 HeapTuple tup;
5451 ScanKeyData skey[1];
5454 StringInfoData opfam;
5455 char *ltype;
5456 char *rtype;
5457
5460
5461 ScanKeyInit(&skey[0],
5464 ObjectIdGetDatum(object->objectId));
5465
5467 NULL, 1, skey);
5468
5470
5471 if (!HeapTupleIsValid(tup))
5472 {
5473 if (!missing_ok)
5474 elog(ERROR, "could not find tuple for amop entry %u",
5475 object->objectId);
5476
5479 break;
5480 }
5481
5483
5484 initStringInfo(&opfam);
5485 getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname,
5486 false);
5487
5488 ltype = format_type_be_qualified(amopForm->amoplefttype);
5489 rtype = format_type_be_qualified(amopForm->amoprighttype);
5490
5491 if (objname)
5492 {
5493 *objname = lappend(*objname,
5494 psprintf("%d", amopForm->amopstrategy));
5495 *objargs = list_make2(ltype, rtype);
5496 }
5497
5498 appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
5499 amopForm->amopstrategy,
5500 ltype, rtype, opfam.data);
5501
5502 pfree(opfam.data);
5503
5506 break;
5507 }
5508
5510 {
5512 ScanKeyData skey[1];
5514 HeapTuple tup;
5516 StringInfoData opfam;
5517 char *ltype;
5518 char *rtype;
5519
5522
5523 ScanKeyInit(&skey[0],
5526 ObjectIdGetDatum(object->objectId));
5527
5529 NULL, 1, skey);
5530
5532
5533 if (!HeapTupleIsValid(tup))
5534 {
5535 if (!missing_ok)
5536 elog(ERROR, "could not find tuple for amproc entry %u",
5537 object->objectId);
5538
5541 break;
5542 }
5543
5545
5546 initStringInfo(&opfam);
5547 getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname,
5548 false);
5549
5550 ltype = format_type_be_qualified(amprocForm->amproclefttype);
5551 rtype = format_type_be_qualified(amprocForm->amprocrighttype);
5552
5553 if (objname)
5554 {
5555 *objname = lappend(*objname,
5556 psprintf("%d", amprocForm->amprocnum));
5557 *objargs = list_make2(ltype, rtype);
5558 }
5559
5560 appendStringInfo(&buffer, "function %d (%s, %s) of %s",
5561 amprocForm->amprocnum,
5562 ltype, rtype, opfam.data);
5563
5564 pfree(opfam.data);
5565
5568 break;
5569 }
5570
5571 case RewriteRelationId:
5572 {
5574 HeapTuple tup;
5576
5578
5580 object->objectId);
5581
5582 if (!HeapTupleIsValid(tup))
5583 {
5584 if (!missing_ok)
5585 elog(ERROR, "could not find tuple for rule %u",
5586 object->objectId);
5587
5589 break;
5590 }
5591
5593
5594 appendStringInfo(&buffer, "%s on ",
5595 quote_identifier(NameStr(rule->rulename)));
5596 getRelationIdentity(&buffer, rule->ev_class, objname, false);
5597 if (objname)
5598 *objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
5599
5601 break;
5602 }
5603
5604 case TriggerRelationId:
5605 {
5607 HeapTuple tup;
5609
5611
5613 object->objectId);
5614
5615 if (!HeapTupleIsValid(tup))
5616 {
5617 if (!missing_ok)
5618 elog(ERROR, "could not find tuple for trigger %u",
5619 object->objectId);
5620
5622 break;
5623 }
5624
5626
5627 appendStringInfo(&buffer, "%s on ",
5628 quote_identifier(NameStr(trig->tgname)));
5629 getRelationIdentity(&buffer, trig->tgrelid, objname, false);
5630 if (objname)
5631 *objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
5632
5634 break;
5635 }
5636
5638 {
5639 char *nspname;
5640
5641 nspname = get_namespace_name_or_temp(object->objectId);
5642 if (!nspname)
5643 {
5644 if (!missing_ok)
5645 elog(ERROR, "cache lookup failed for namespace %u",
5646 object->objectId);
5647 break;
5648 }
5649 appendStringInfoString(&buffer,
5650 quote_identifier(nspname));
5651 if (objname)
5652 *objname = list_make1(nspname);
5653 break;
5654 }
5655
5657 {
5658 HeapTuple tup;
5660 char *schema;
5661
5663 ObjectIdGetDatum(object->objectId));
5664 if (!HeapTupleIsValid(tup))
5665 {
5666 if (!missing_ok)
5667 elog(ERROR, "cache lookup failed for statistics object %u",
5668 object->objectId);
5669 break;
5670 }
5672 schema = get_namespace_name_or_temp(formStatistic->stxnamespace);
5673 appendStringInfoString(&buffer,
5675 NameStr(formStatistic->stxname)));
5676 if (objname)
5677 *objname = list_make2(schema,
5678 pstrdup(NameStr(formStatistic->stxname)));
5680 }
5681 break;
5682
5683 case TSParserRelationId:
5684 {
5685 HeapTuple tup;
5687 char *schema;
5688
5690 ObjectIdGetDatum(object->objectId));
5691 if (!HeapTupleIsValid(tup))
5692 {
5693 if (!missing_ok)
5694 elog(ERROR, "cache lookup failed for text search parser %u",
5695 object->objectId);
5696 break;
5697 }
5699 schema = get_namespace_name_or_temp(formParser->prsnamespace);
5700 appendStringInfoString(&buffer,
5702 NameStr(formParser->prsname)));
5703 if (objname)
5704 *objname = list_make2(schema,
5705 pstrdup(NameStr(formParser->prsname)));
5707 break;
5708 }
5709
5711 {
5712 HeapTuple tup;
5714 char *schema;
5715
5717 ObjectIdGetDatum(object->objectId));
5718 if (!HeapTupleIsValid(tup))
5719 {
5720 if (!missing_ok)
5721 elog(ERROR, "cache lookup failed for text search dictionary %u",
5722 object->objectId);
5723 break;
5724 }
5726 schema = get_namespace_name_or_temp(formDict->dictnamespace);
5727 appendStringInfoString(&buffer,
5729 NameStr(formDict->dictname)));
5730 if (objname)
5731 *objname = list_make2(schema,
5732 pstrdup(NameStr(formDict->dictname)));
5734 break;
5735 }
5736
5738 {
5739 HeapTuple tup;
5741 char *schema;
5742
5744 ObjectIdGetDatum(object->objectId));
5745 if (!HeapTupleIsValid(tup))
5746 {
5747 if (!missing_ok)
5748 elog(ERROR, "cache lookup failed for text search template %u",
5749 object->objectId);
5750 break;
5751 }
5753 schema = get_namespace_name_or_temp(formTmpl->tmplnamespace);
5754 appendStringInfoString(&buffer,
5756 NameStr(formTmpl->tmplname)));
5757 if (objname)
5758 *objname = list_make2(schema,
5759 pstrdup(NameStr(formTmpl->tmplname)));
5761 break;
5762 }
5763
5764 case TSConfigRelationId:
5765 {
5766 HeapTuple tup;
5768 char *schema;
5769
5771 ObjectIdGetDatum(object->objectId));
5772 if (!HeapTupleIsValid(tup))
5773 {
5774 if (!missing_ok)
5775 elog(ERROR, "cache lookup failed for text search configuration %u",
5776 object->objectId);
5777 break;
5778 }
5780 schema = get_namespace_name_or_temp(formCfg->cfgnamespace);
5781 appendStringInfoString(&buffer,
5783 NameStr(formCfg->cfgname)));
5784 if (objname)
5785 *objname = list_make2(schema,
5786 pstrdup(NameStr(formCfg->cfgname)));
5788 break;
5789 }
5790
5791 case AuthIdRelationId:
5792 {
5793 char *username;
5794
5795 username = GetUserNameFromId(object->objectId, missing_ok);
5796 if (!username)
5797 break;
5798 if (objname)
5799 *objname = list_make1(username);
5800 appendStringInfoString(&buffer,
5802 break;
5803 }
5804
5805 case AuthMemRelationId:
5806 {
5808 ScanKeyData skey[1];
5810 HeapTuple tup;
5812
5815
5816 ScanKeyInit(&skey[0],
5819 ObjectIdGetDatum(object->objectId));
5820
5822 NULL, 1, skey);
5823
5825
5826 if (!HeapTupleIsValid(tup))
5827 {
5828 if (!missing_ok)
5829 elog(ERROR, "could not find tuple for pg_auth_members entry %u",
5830 object->objectId);
5831
5834 break;
5835 }
5836
5838
5839 appendStringInfo(&buffer, _("membership of role %s in role %s"),
5840 GetUserNameFromId(amForm->member, false),
5841 GetUserNameFromId(amForm->roleid, false));
5842
5845 break;
5846 }
5847
5848 case DatabaseRelationId:
5849 {
5850 char *datname;
5851
5853 if (!datname)
5854 {
5855 if (!missing_ok)
5856 elog(ERROR, "cache lookup failed for database %u",
5857 object->objectId);
5858 break;
5859 }
5860 if (objname)
5861 *objname = list_make1(datname);
5862 appendStringInfoString(&buffer,
5864 break;
5865 }
5866
5868 {
5869 char *tblspace;
5870
5872 if (!tblspace)
5873 {
5874 if (!missing_ok)
5875 elog(ERROR, "cache lookup failed for tablespace %u",
5876 object->objectId);
5877 break;
5878 }
5879 if (objname)
5880 *objname = list_make1(tblspace);
5881 appendStringInfoString(&buffer,
5883 break;
5884 }
5885
5887 {
5889
5891 missing_ok);
5892 if (fdw)
5893 {
5894 appendStringInfoString(&buffer, quote_identifier(fdw->fdwname));
5895 if (objname)
5896 *objname = list_make1(pstrdup(fdw->fdwname));
5897 }
5898 break;
5899 }
5900
5902 {
5904
5906 missing_ok);
5907 if (srv)
5908 {
5909 appendStringInfoString(&buffer,
5910 quote_identifier(srv->servername));
5911 if (objname)
5912 *objname = list_make1(pstrdup(srv->servername));
5913 }
5914 break;
5915 }
5916
5918 {
5919 HeapTuple tup;
5920 Oid useid;
5923 const char *usename;
5924
5926 ObjectIdGetDatum(object->objectId));
5927 if (!HeapTupleIsValid(tup))
5928 {
5929 if (!missing_ok)
5930 elog(ERROR, "cache lookup failed for user mapping %u",
5931 object->objectId);
5932 break;
5933 }
5935 useid = umform->umuser;
5936 srv = GetForeignServer(umform->umserver);
5937
5939
5940 if (OidIsValid(useid))
5942 else
5943 usename = "public";
5944
5945 if (objname)
5946 {
5947 *objname = list_make1(pstrdup(usename));
5948 *objargs = list_make1(pstrdup(srv->servername));
5949 }
5950
5951 appendStringInfo(&buffer, "%s on server %s",
5953 srv->servername);
5954 break;
5955 }
5956
5958 {
5960 ScanKeyData skey[1];
5962 HeapTuple tup;
5964 char *schema;
5965 char *username;
5966
5968
5969 ScanKeyInit(&skey[0],
5972 ObjectIdGetDatum(object->objectId));
5973
5975 true, NULL, 1, skey);
5976
5978
5979 if (!HeapTupleIsValid(tup))
5980 {
5981 if (!missing_ok)
5982 elog(ERROR, "could not find tuple for default ACL %u",
5983 object->objectId);
5984
5987 break;
5988 }
5989
5991
5992 username = GetUserNameFromId(defacl->defaclrole, false);
5993 appendStringInfo(&buffer,
5994 "for role %s",
5996
5997 if (OidIsValid(defacl->defaclnamespace))
5998 {
5999 schema = get_namespace_name_or_temp(defacl->defaclnamespace);
6000 appendStringInfo(&buffer,
6001 " in schema %s",
6002 quote_identifier(schema));
6003 }
6004 else
6005 schema = NULL;
6006
6007 switch (defacl->defaclobjtype)
6008 {
6009 case DEFACLOBJ_RELATION:
6010 appendStringInfoString(&buffer,
6011 " on tables");
6012 break;
6013 case DEFACLOBJ_SEQUENCE:
6014 appendStringInfoString(&buffer,
6015 " on sequences");
6016 break;
6017 case DEFACLOBJ_FUNCTION:
6018 appendStringInfoString(&buffer,
6019 " on functions");
6020 break;
6021 case DEFACLOBJ_TYPE:
6022 appendStringInfoString(&buffer,
6023 " on types");
6024 break;
6026 appendStringInfoString(&buffer,
6027 " on schemas");
6028 break;
6030 appendStringInfoString(&buffer,
6031 " on large objects");
6032 break;
6033 }
6034
6035 if (objname)
6036 {
6037 *objname = list_make1(username);
6038 if (schema)
6039 *objname = lappend(*objname, schema);
6040 *objargs = list_make1(psprintf("%c", defacl->defaclobjtype));
6041 }
6042
6045 break;
6046 }
6047
6049 {
6050 char *extname;
6051
6052 extname = get_extension_name(object->objectId);
6053 if (!extname)
6054 {
6055 if (!missing_ok)
6056 elog(ERROR, "cache lookup failed for extension %u",
6057 object->objectId);
6058 break;
6059 }
6060 appendStringInfoString(&buffer, quote_identifier(extname));
6061 if (objname)
6062 *objname = list_make1(extname);
6063 break;
6064 }
6065
6067 {
6068 HeapTuple tup;
6070 char *evtname;
6071
6073 ObjectIdGetDatum(object->objectId));
6074 if (!HeapTupleIsValid(tup))
6075 {
6076 if (!missing_ok)
6077 elog(ERROR, "cache lookup failed for event trigger %u",
6078 object->objectId);
6079 break;
6080 }
6082 evtname = pstrdup(NameStr(trigForm->evtname));
6083 appendStringInfoString(&buffer, quote_identifier(evtname));
6084 if (objname)
6085 *objname = list_make1(evtname);
6087 break;
6088 }
6089
6091 {
6092 HeapTuple tup;
6094 char *parname;
6095
6097 ObjectIdGetDatum(object->objectId));
6098 if (!HeapTupleIsValid(tup))
6099 {
6100 if (!missing_ok)
6101 elog(ERROR, "cache lookup failed for parameter ACL %u",
6102 object->objectId);
6103 break;
6104 }
6109 if (objname)
6110 *objname = list_make1(parname);
6112 break;
6113 }
6114
6115 case PolicyRelationId:
6116 {
6118 HeapTuple tup;
6120
6122
6124 object->objectId);
6125
6126 if (!HeapTupleIsValid(tup))
6127 {
6128 if (!missing_ok)
6129 elog(ERROR, "could not find tuple for policy %u",
6130 object->objectId);
6131
6133 break;
6134 }
6135
6137
6138 appendStringInfo(&buffer, "%s on ",
6139 quote_identifier(NameStr(policy->polname)));
6140 getRelationIdentity(&buffer, policy->polrelid, objname, false);
6141 if (objname)
6142 *objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
6143
6145 break;
6146 }
6147
6149 {
6150 HeapTuple tup;
6152
6154 if (!HeapTupleIsValid(tup))
6155 {
6156 if (!missing_ok)
6157 elog(ERROR, "cache lookup failed for property graph element %u", object->objectId);
6158 break;
6159 }
6161 appendStringInfo(&buffer, "%s of ", quote_identifier(NameStr(pge->pgealias)));
6162
6163 getRelationIdentity(&buffer, pge->pgepgid, objname, false);
6164 if (objname)
6165 *objname = lappend(*objname, pstrdup(NameStr(pge->pgealias)));
6166
6168 break;
6169 }
6170
6172 {
6173 HeapTuple tup;
6175
6177 if (!HeapTupleIsValid(tup))
6178 {
6179 if (!missing_ok)
6180 elog(ERROR, "cache lookup failed for property graph label %u", object->objectId);
6181 break;
6182 }
6183
6185 appendStringInfo(&buffer, "%s of ", quote_identifier(NameStr(pgl->pgllabel)));
6186 getRelationIdentity(&buffer, pgl->pglpgid, objname, false);
6187 if (objname)
6188 *objname = lappend(*objname, pstrdup(NameStr(pgl->pgllabel)));
6190 break;
6191 }
6192
6194 {
6195 HeapTuple tup;
6197
6199 if (!HeapTupleIsValid(tup))
6200 {
6201 if (!missing_ok)
6202 elog(ERROR, "cache lookup failed for property graph property %u", object->objectId);
6203 break;
6204 }
6205
6207 appendStringInfo(&buffer, "%s of ", quote_identifier(NameStr(pgp->pgpname)));
6208 getRelationIdentity(&buffer, pgp->pgppgid, objname, false);
6209 if (objname)
6210 *objname = lappend(*objname, pstrdup(NameStr(pgp->pgpname)));
6212 break;
6213 }
6214
6216 {
6217 char *pubname;
6218
6219 pubname = get_publication_name(object->objectId, missing_ok);
6220 if (pubname)
6221 {
6222 appendStringInfoString(&buffer,
6223 quote_identifier(pubname));
6224 if (objname)
6225 *objname = list_make1(pubname);
6226 }
6227 break;
6228 }
6229
6231 {
6232 char *pubname;
6233 char *nspname;
6234
6235 if (!getPublicationSchemaInfo(object, missing_ok, &pubname,
6236 &nspname))
6237 break;
6238 appendStringInfo(&buffer, "%s in publication %s",
6239 nspname, pubname);
6240
6241 if (objargs)
6242 *objargs = list_make1(pubname);
6243 else
6244 pfree(pubname);
6245
6246 if (objname)
6247 *objname = list_make1(nspname);
6248 else
6249 pfree(nspname);
6250
6251 break;
6252 }
6253
6255 {
6256 HeapTuple tup;
6257 char *pubname;
6259
6261 ObjectIdGetDatum(object->objectId));
6262 if (!HeapTupleIsValid(tup))
6263 {
6264 if (!missing_ok)
6265 elog(ERROR, "cache lookup failed for publication table %u",
6266 object->objectId);
6267 break;
6268 }
6269
6271 pubname = get_publication_name(prform->prpubid, false);
6272
6273 getRelationIdentity(&buffer, prform->prrelid, objname, false);
6274 appendStringInfo(&buffer, " in publication %s", pubname);
6275
6276 if (objargs)
6277 *objargs = list_make1(pubname);
6278
6280 break;
6281 }
6282
6284 {
6285 char *subname;
6286
6287 subname = get_subscription_name(object->objectId, missing_ok);
6288 if (subname)
6289 {
6290 appendStringInfoString(&buffer,
6292 if (objname)
6293 *objname = list_make1(subname);
6294 }
6295 break;
6296 }
6297
6299 {
6301 HeapTuple tup;
6302 Form_pg_transform transform;
6303 char *transformLang;
6304 char *transformType;
6305
6307
6310 object->objectId);
6311
6312 if (!HeapTupleIsValid(tup))
6313 {
6314 if (!missing_ok)
6315 elog(ERROR, "could not find tuple for transform %u",
6316 object->objectId);
6317
6319 break;
6320 }
6321
6322 transform = (Form_pg_transform) GETSTRUCT(tup);
6323
6324 transformType = format_type_be_qualified(transform->trftype);
6325 transformLang = get_language_name(transform->trflang, false);
6326
6327 appendStringInfo(&buffer, "for %s language %s",
6330 if (objname)
6331 {
6332 *objname = list_make1(transformType);
6333 *objargs = list_make1(pstrdup(transformLang));
6334 }
6335
6337 }
6338 break;
6339
6340 default:
6341 elog(ERROR, "unsupported object class: %u", object->classId);
6342 }
6343
6344 if (!missing_ok)
6345 {
6346 /*
6347 * If a get_object_address() representation was requested, make sure
6348 * we are providing one. We don't check objargs, because many of the
6349 * cases above leave it as NIL.
6350 */
6351 if (objname && *objname == NIL)
6352 elog(ERROR, "requested object address for unsupported object class %u: text result \"%s\"",
6353 object->classId, buffer.data);
6354 }
6355 else
6356 {
6357 /* an empty buffer is equivalent to no object found */
6358 if (buffer.len == 0)
6359 {
6360 Assert((objname == NULL || *objname == NIL) &&
6361 (objargs == NULL || *objargs == NIL));
6362 return NULL;
6363 }
6364 }
6365
6366 return buffer.data;
6367}
6368
6369static void
6371 bool missing_ok)
6372{
6377 char *schema;
6378
6381 {
6382 if (!missing_ok)
6383 elog(ERROR, "cache lookup failed for opfamily %u", opfid);
6384 return;
6385 }
6387
6389 if (!HeapTupleIsValid(amTup))
6390 elog(ERROR, "cache lookup failed for access method %u",
6391 opfForm->opfmethod);
6393
6394 schema = get_namespace_name_or_temp(opfForm->opfnamespace);
6395 appendStringInfo(buffer, "%s USING %s",
6397 NameStr(opfForm->opfname)),
6398 NameStr(amForm->amname));
6399
6400 if (object)
6401 *object = list_make3(pstrdup(NameStr(amForm->amname)),
6402 pstrdup(schema),
6403 pstrdup(NameStr(opfForm->opfname)));
6404
6407}
6408
6409/*
6410 * Append the relation identity (quoted qualified name) to the given
6411 * StringInfo.
6412 */
6413static void
6414getRelationIdentity(StringInfo buffer, Oid relid, List **object,
6415 bool missing_ok)
6416{
6419 char *schema;
6420
6422 ObjectIdGetDatum(relid));
6424 {
6425 if (!missing_ok)
6426 elog(ERROR, "cache lookup failed for relation %u", relid);
6427
6428 if (object)
6429 *object = NIL;
6430 return;
6431 }
6433
6434 schema = get_namespace_name_or_temp(relForm->relnamespace);
6437 NameStr(relForm->relname)));
6438 if (object)
6439 *object = list_make2(schema, pstrdup(NameStr(relForm->relname)));
6440
6442}
6443
6444/*
6445 * Auxiliary function to build a TEXT array out of a list of C-strings.
6446 */
6447ArrayType *
6449{
6450 ArrayType *arr;
6451 Datum *datums;
6452 bool *nulls;
6453 int j = 0;
6454 ListCell *cell;
6455 MemoryContext memcxt;
6457 int lb[1];
6458
6459 /* Work in a temp context; easier than individually pfree'ing the Datums */
6461 "strlist to array",
6463 oldcxt = MemoryContextSwitchTo(memcxt);
6464
6465 datums = palloc_array(Datum, list_length(list));
6466 nulls = palloc_array(bool, list_length(list));
6467
6468 foreach(cell, list)
6469 {
6470 char *name = lfirst(cell);
6471
6472 if (name)
6473 {
6474 nulls[j] = false;
6475 datums[j++] = CStringGetTextDatum(name);
6476 }
6477 else
6478 nulls[j] = true;
6479 }
6480
6482
6483 lb[0] = 1;
6484 arr = construct_md_array(datums, nulls, 1, &j,
6485 lb, TEXTOID, -1, false, TYPALIGN_INT);
6486
6487 MemoryContextDelete(memcxt);
6488
6489 return arr;
6490}
6491
6492/*
6493 * get_relkind_objtype
6494 *
6495 * Return the object type for the relkind given by the caller.
6496 *
6497 * If an unexpected relkind is passed, we say OBJECT_TABLE rather than
6498 * failing. That's because this is mostly used for generating error messages
6499 * for failed ACL checks on relations, and we'd rather produce a generic
6500 * message saying "table" than fail entirely.
6501 */
6504{
6505 switch (relkind)
6506 {
6507 case RELKIND_RELATION:
6509 return OBJECT_TABLE;
6510 case RELKIND_INDEX:
6512 return OBJECT_INDEX;
6513 case RELKIND_SEQUENCE:
6514 return OBJECT_SEQUENCE;
6515 case RELKIND_VIEW:
6516 return OBJECT_VIEW;
6517 case RELKIND_MATVIEW:
6518 return OBJECT_MATVIEW;
6520 return OBJECT_FOREIGN_TABLE;
6521 case RELKIND_PROPGRAPH:
6522 return OBJECT_PROPGRAPH;
6523 case RELKIND_TOASTVALUE:
6524 return OBJECT_TABLE;
6525 default:
6526 /* Per above, don't raise an error */
6527 return OBJECT_TABLE;
6528 }
6529}
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5444
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5605
@ ACLCHECK_NOT_OWNER
Definition acl.h:186
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4134
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition aclchk.c:2997
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4213
Oid get_index_am_oid(const char *amname, bool missing_ok)
Definition amcmds.c:163
char * get_am_name(Oid amOid)
Definition amcmds.c:192
Oid get_am_oid(const char *amname, bool missing_ok)
Definition amcmds.c:183
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
ArrayType * construct_empty_array(Oid elmtype)
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
int16 AttrNumber
Definition attnum.h:21
#define InvalidAttrNumber
Definition attnum.h:23
char * get_tablespace_name(Oid spc_oid)
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define FORMAT_TYPE_ALLOW_INVALID
Definition builtins.h:126
#define TextDatumGetCString(d)
Definition builtins.h:99
#define FORMAT_TYPE_INVALID_AS_NULL
Definition builtins.h:128
#define FORMAT_TYPE_FORCE_QUALIFY
Definition builtins.h:127
#define NameStr(name)
Definition c.h:835
#define Assert(condition)
Definition c.h:943
int32_t int32
Definition c.h:620
uint64_t uint64
Definition c.h:625
uint16_t uint16
Definition c.h:623
#define lengthof(array)
Definition c.h:873
#define pg_fallthrough
Definition c.h:161
#define OidIsValid(objectId)
Definition c.h:858
bool IsSharedRelation(Oid relationId)
Definition catalog.c:304
Oid get_database_oid(const char *dbname, bool missing_ok)
int errcode(int sqlerrcode)
Definition elog.c:875
#define _(x)
Definition elog.c:96
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
Oid get_event_trigger_oid(const char *trigname, bool missing_ok)
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition extension.c:229
char * get_extension_name(Oid ext_oid)
Definition extension.c:251
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition foreign.c:185
ForeignDataWrapper * GetForeignDataWrapperExtended(Oid fdwid, uint16 flags)
Definition foreign.c:51
Oid get_foreign_server_oid(const char *servername, bool missing_ok)
Definition foreign.c:736
ForeignServer * GetForeignServer(Oid serverid)
Definition foreign.c:114
ForeignServer * GetForeignServerExtended(Oid serverid, uint16 flags)
Definition foreign.c:126
Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
Definition foreign.c:713
char * format_type_be_qualified(Oid type_oid)
char * format_type_be(Oid type_oid)
char * format_type_extended(Oid type_oid, int32 typemod, uint16 flags)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok)
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:612
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:523
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:686
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1025
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
static char * username
Definition initdb.c:153
bool lo_compat_privileges
Definition inv_api.c:56
int j
Definition isn.c:78
int i
Definition isn.c:77
const char ** typenames
Definition lexi.c:115
List * lappend(List *list, void *datum)
Definition list.c:339
List * list_copy_tail(const List *oldlist, int nskip)
Definition list.c:1613
List * lcons(void *datum, List *list)
Definition list.c:495
List * list_copy_head(const List *oldlist, int len)
Definition list.c:1593
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1088
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1008
void LockTuple(Relation relation, const ItemPointerData *tid, LOCKMODE lockmode)
Definition lmgr.c:562
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1148
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1068
int LOCKMODE
Definition lockdefs.h:26
#define NoLock
Definition lockdefs.h:34
#define AccessShareLock
Definition lockdefs.h:36
#define InplaceUpdateTupleLock
Definition lockdefs.h:48
char * get_propgraph_property_name(Oid propoid)
Definition lsyscache.c:4015
Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
Definition lsyscache.c:1164
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:1015
char * get_database_name(Oid dbid)
Definition lsyscache.c:1323
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2234
Oid get_publication_oid(const char *pubname, bool missing_ok)
Definition lsyscache.c:3903
char * get_language_name(Oid langoid, bool missing_ok)
Definition lsyscache.c:1344
char * get_namespace_name_or_temp(Oid nspid)
Definition lsyscache.c:3623
char * get_propgraph_label_name(Oid labeloid)
Definition lsyscache.c:3997
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:984
Oid get_subscription_oid(const char *subname, bool missing_ok)
Definition lsyscache.c:3953
char * get_subscription_name(Oid subid, bool missing_ok)
Definition lsyscache.c:3973
char * get_publication_name(Oid pubid, bool missing_ok)
Definition lsyscache.c:3923
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3599
char * pstrdup(const char *in)
Definition mcxt.c:1910
void pfree(void *pointer)
Definition mcxt.c:1619
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c:990
char * NameListToString(const List *names)
Definition namespace.c:3666
bool TSTemplateIsVisible(Oid tmplId)
Definition namespace.c:3137
bool OpfamilyIsVisible(Oid opfid)
Definition namespace.c:2325
bool CollationIsVisible(Oid collid)
Definition namespace.c:2476
bool ConversionIsVisible(Oid conid)
Definition namespace.c:2578
Oid get_statistics_object_oid(List *names, bool missing_ok)
Definition namespace.c:2644
Oid get_collation_oid(List *collname, bool missing_ok)
Definition namespace.c:4043
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition namespace.c:3607
bool RelationIsVisible(Oid relid)
Definition namespace.c:914
bool OpclassIsVisible(Oid opcid)
Definition namespace.c:2223
bool TSParserIsVisible(Oid prsId)
Definition namespace.c:2846
Oid get_conversion_oid(List *conname, bool missing_ok)
Definition namespace.c:4097
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition namespace.c:2933
Oid get_ts_parser_oid(List *names, bool missing_ok)
Definition namespace.c:2788
RangeVar * makeRangeVarFromNameList(const List *names)
Definition namespace.c:3626
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition namespace.c:3224
bool TSConfigIsVisible(Oid cfgid)
Definition namespace.c:3282
bool StatisticsObjIsVisible(Oid stxid)
Definition namespace.c:2701
bool TSDictionaryIsVisible(Oid dictId)
Definition namespace.c:2991
Oid get_ts_template_oid(List *names, bool missing_ok)
Definition namespace.c:3079
#define makeNode(_type_)
Definition nodes.h:161
#define castNode(_type_, nodeptr)
Definition nodes.h:182
static char * errmsg
static void getRelationDescription(StringInfo buffer, Oid relid, bool missing_ok)
char * getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
ArrayType * strlist_to_textarray(List *list)
bool get_object_namensp_unique(Oid class_id)
ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
AttrNumber get_object_attnum_owner(Oid class_id)
Datum pg_identify_object(PG_FUNCTION_ARGS)
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
AttrNumber get_object_attnum_oid(Oid class_id)
static const ObjectPropertyType ObjectProperty[]
ObjectType get_relkind_objtype(char relkind)
AttrNumber get_object_attnum_namespace(Oid class_id)
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
SysCacheIdentifier get_object_catcache_name(Oid class_id)
char * getObjectDescriptionOids(Oid classid, Oid objid)
char * getObjectIdentityParts(const ObjectAddress *object, List **objname, List **objargs, bool missing_ok)
static ObjectAddress get_object_address_publication_schema(List *object, bool missing_ok)
AttrNumber get_object_attnum_name(Oid class_id)
static ObjectAddress get_object_address_relobject(ObjectType objtype, List *object, Relation *relp, bool missing_ok)
static void getConstraintTypeDescription(StringInfo buffer, Oid constroid, bool missing_ok)
const char * get_object_class_descr(Oid class_id)
static void getProcedureTypeDescription(StringInfo buffer, Oid procid, bool missing_ok)
static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object, bool missing_ok)
static ObjectAddress get_object_address_defacl(List *object, bool missing_ok)
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
Datum pg_get_acl(PG_FUNCTION_ARGS)
static bool getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok, char **pubname, char **nspname)
AttrNumber get_object_attnum_acl(Oid class_id)
static void getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId, bool missing_ok)
static void getOpFamilyDescription(StringInfo buffer, Oid opfid, bool missing_ok)
Oid get_object_oid_index(Oid class_id)
static ObjectAddress get_object_address_unqualified(ObjectType objtype, String *strval, bool missing_ok)
int read_objtype_from_string(const char *objtype)
SysCacheIdentifier get_object_catcache_oid(Oid class_id)
const ObjectAddress InvalidObjectAddress
ObjectType get_object_type(Oid class_id, Oid object_id)
static ObjectAddress get_object_address_publication_rel(List *object, Relation *relp, bool missing_ok)
static ObjectAddress get_object_address_opf_member(ObjectType objtype, List *object, bool missing_ok)
static const ObjectPropertyType * get_object_property_data(Oid class_id)
static ObjectAddress get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
static ObjectAddress get_object_address_usermapping(List *object, bool missing_ok)
static const struct object_type_map ObjectTypeMap[]
static void getRelationIdentity(StringInfo buffer, Oid relid, List **object, bool missing_ok)
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
Datum pg_identify_object_as_address(PG_FUNCTION_ARGS)
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
Datum pg_describe_object(PG_FUNCTION_ARGS)
Datum pg_get_object_address(PG_FUNCTION_ARGS)
static ObjectAddress get_object_address_attribute(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
static ObjectAddress get_relation_by_qualified_name(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
Oid get_object_namespace(const ObjectAddress *address)
HeapTuple get_catalog_object_by_oid_extended(Relation catalog, AttrNumber oidcol, Oid objectId, bool locktup)
static ObjectAddress get_object_address_attrdef(ObjectType objtype, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
bool is_objectclass_supported(Oid class_id)
static List * textarray_to_strvaluelist(ArrayType *arr)
#define ObjectAddressSet(addr, class_id, object_id)
Oid oidparse(Node *node)
Definition oid.c:264
Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError)
Definition parse_oper.c:136
char * TypeNameToString(const TypeName *typeName)
Definition parse_type.c:478
Type LookupTypeName(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool missing_ok)
Definition parse_type.c:38
TypeName * typeStringToTypeName(const char *str, Node *escontext)
Definition parse_type.c:738
Oid typeTypeId(Type tp)
Definition parse_type.c:590
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition parse_type.c:291
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
Definition parse_type.c:232
ObjectType
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_USER_MAPPING
@ OBJECT_PROPGRAPH
@ OBJECT_ACCESS_METHOD
@ OBJECT_OPCLASS
@ OBJECT_DEFACL
@ OBJECT_AGGREGATE
@ OBJECT_MATVIEW
@ OBJECT_SCHEMA
@ OBJECT_POLICY
@ OBJECT_OPERATOR
@ OBJECT_FOREIGN_TABLE
@ OBJECT_TSCONFIGURATION
@ OBJECT_OPFAMILY
@ OBJECT_DOMAIN
@ OBJECT_COLUMN
@ OBJECT_TABLESPACE
@ OBJECT_ROLE
@ OBJECT_ROUTINE
@ OBJECT_LARGEOBJECT
@ OBJECT_PUBLICATION_NAMESPACE
@ OBJECT_PROCEDURE
@ OBJECT_EXTENSION
@ OBJECT_INDEX
@ OBJECT_DEFAULT
@ OBJECT_DATABASE
@ OBJECT_SEQUENCE
@ OBJECT_TSTEMPLATE
@ OBJECT_LANGUAGE
@ OBJECT_AMOP
@ OBJECT_PUBLICATION_REL
@ OBJECT_FOREIGN_SERVER
@ OBJECT_TSDICTIONARY
@ OBJECT_ATTRIBUTE
@ OBJECT_PUBLICATION
@ OBJECT_RULE
@ OBJECT_CONVERSION
@ OBJECT_AMPROC
@ OBJECT_TABLE
@ OBJECT_VIEW
@ OBJECT_PARAMETER_ACL
@ OBJECT_TYPE
@ OBJECT_FUNCTION
@ OBJECT_TABCONSTRAINT
@ OBJECT_DOMCONSTRAINT
@ OBJECT_SUBSCRIPTION
@ OBJECT_STATISTIC_EXT
@ OBJECT_CAST
@ OBJECT_TRIGGER
@ OBJECT_TRANSFORM
END_CATALOG_STRUCT typedef FormData_pg_am * Form_pg_am
Definition pg_am.h:52
END_CATALOG_STRUCT typedef FormData_pg_amop * Form_pg_amop
Definition pg_amop.h:92
END_CATALOG_STRUCT typedef FormData_pg_amproc * Form_pg_amproc
Definition pg_amproc.h:72
Oid GetAttrDefaultOid(Oid relid, AttrNumber attnum)
Definition pg_attrdef.c:280
ObjectAddress GetAttrDefaultColumnAddress(Oid attrdefoid)
Definition pg_attrdef.c:322
NameData attname
int16 attnum
END_CATALOG_STRUCT typedef FormData_pg_auth_members * Form_pg_auth_members
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
END_CATALOG_STRUCT typedef FormData_pg_cast * Form_pg_cast
Definition pg_cast.h:61
NameData relname
Definition pg_class.h:40
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
END_CATALOG_STRUCT typedef FormData_pg_collation * Form_pg_collation
Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok)
Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)
END_CATALOG_STRUCT typedef FormData_pg_constraint * Form_pg_constraint
END_CATALOG_STRUCT typedef FormData_pg_conversion * Form_pg_conversion
NameData datname
Definition pg_database.h:37
END_CATALOG_STRUCT typedef FormData_pg_default_acl * Form_pg_default_acl
END_CATALOG_STRUCT typedef FormData_pg_event_trigger * Form_pg_event_trigger
END_CATALOG_STRUCT typedef FormData_pg_language * Form_pg_language
Definition pg_language.h:69
bool LargeObjectExists(Oid loid)
#define lfirst(lc)
Definition pg_list.h:172
#define llast(l)
Definition pg_list.h:198
#define lfirst_node(type, lc)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial_node(type, l)
Definition pg_list.h:181
#define NIL
Definition pg_list.h:68
#define lsecond_node(type, l)
Definition pg_list.h:186
#define lthird(l)
Definition pg_list.h:188
#define list_make1(x1)
Definition pg_list.h:244
#define linitial(l)
Definition pg_list.h:178
#define list_make3(x1, x2, x3)
Definition pg_list.h:248
#define lsecond(l)
Definition pg_list.h:183
#define list_make2(x1, x2)
Definition pg_list.h:246
END_CATALOG_STRUCT typedef FormData_pg_opclass * Form_pg_opclass
Definition pg_opclass.h:87
END_CATALOG_STRUCT typedef FormData_pg_opfamily * Form_pg_opfamily
Definition pg_opfamily.h:55
Oid ParameterAclLookup(const char *parameter, bool missing_ok)
END_CATALOG_STRUCT typedef FormData_pg_policy * Form_pg_policy
Definition pg_policy.h:55
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
NameData proname
Definition pg_proc.h:37
END_CATALOG_STRUCT typedef FormData_pg_propgraph_element * Form_pg_propgraph_element
END_CATALOG_STRUCT typedef FormData_pg_propgraph_element_label * Form_pg_propgraph_element_label
END_CATALOG_STRUCT typedef FormData_pg_propgraph_label * Form_pg_propgraph_label
END_CATALOG_STRUCT typedef FormData_pg_propgraph_label_property * Form_pg_propgraph_label_property
END_CATALOG_STRUCT typedef FormData_pg_propgraph_property * Form_pg_propgraph_property
Publication * GetPublicationByName(const char *pubname, bool missing_ok)
END_CATALOG_STRUCT typedef FormData_pg_publication_namespace * Form_pg_publication_namespace
END_CATALOG_STRUCT typedef FormData_pg_publication_rel * Form_pg_publication_rel
END_CATALOG_STRUCT typedef FormData_pg_rewrite * Form_pg_rewrite
Definition pg_rewrite.h:56
END_CATALOG_STRUCT typedef FormData_pg_statistic_ext * Form_pg_statistic_ext
NameData subname
END_CATALOG_STRUCT typedef FormData_pg_transform * Form_pg_transform
END_CATALOG_STRUCT typedef FormData_pg_trigger * Form_pg_trigger
Definition pg_trigger.h:84
END_CATALOG_STRUCT typedef FormData_pg_ts_config * Form_pg_ts_config
END_CATALOG_STRUCT typedef FormData_pg_ts_dict * Form_pg_ts_dict
Definition pg_ts_dict.h:56
END_CATALOG_STRUCT typedef FormData_pg_ts_parser * Form_pg_ts_parser
END_CATALOG_STRUCT typedef FormData_pg_ts_template * Form_pg_ts_template
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265
NameData typname
Definition pg_type.h:43
END_CATALOG_STRUCT typedef FormData_pg_user_mapping * Form_pg_user_mapping
Oid get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok)
Definition policy.c:1204
static Name DatumGetName(Datum X)
Definition postgres.h:393
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define PointerGetDatum(X)
Definition postgres.h:354
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define InvalidOid
unsigned int Oid
static int fb(int x)
Oid get_language_oid(const char *langname, bool missing_ok)
Definition proclang.c:227
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
char * format_procedure(Oid procedure_oid)
Definition regproc.c:305
char * format_procedure_extended(Oid procedure_oid, uint16 flags)
Definition regproc.c:332
void format_operator_parts(Oid operator_oid, List **objnames, List **objargs, bool missing_ok)
Definition regproc.c:814
char * format_operator_extended(Oid operator_oid, uint16 flags)
Definition regproc.c:730
void format_procedure_parts(Oid procedure_oid, List **objnames, List **objargs, bool missing_ok)
Definition regproc.c:404
char * format_operator(Oid operator_oid)
Definition regproc.c:801
#define FORMAT_OPERATOR_INVALID_AS_NULL
Definition regproc.h:24
#define FORMAT_OPERATOR_FORCE_QUALIFY
Definition regproc.h:25
#define FORMAT_PROC_FORCE_QUALIFY
Definition regproc.h:20
#define FORMAT_PROC_INVALID_AS_NULL
Definition regproc.h:19
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationGetDescr(relation)
Definition rel.h:542
#define RelationGetRelationName(relation)
Definition rel.h:550
Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
char * quote_qualified_identifier(const char *qualifier, const char *ident)
const char * quote_identifier(const char *ident)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
uint64 SharedInvalidMessageCounter
Definition sinval.c:24
Relation relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok)
Definition relation.c:173
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:206
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition relation.c:138
#define BTEqualStrategyNumber
Definition stratnum.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
ItemPointerData t_self
Definition htup.h:65
Definition pg_list.h:54
Definition nodes.h:135
const char * class_descr
AttrNumber attnum_owner
AttrNumber attnum_namespace
SysCacheIdentifier oid_catcache_id
SysCacheIdentifier name_catcache_id
char * relname
Definition primnodes.h:84
char * catalogname
Definition primnodes.h:78
char * schemaname
Definition primnodes.h:81
Form_pg_class rd_rel
Definition rel.h:111
Definition value.h:64
TupleConstr * constr
Definition tupdesc.h:159
Definition type.h:97
ObjectType tm_type
const char * tm_name
bool superuser_arg(Oid roleid)
Definition superuser.c:57
HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
Definition syscache.c:562
HeapTuple SearchSysCacheLockedCopy1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:400
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
HeapTuple SearchSysCache3(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:241
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
HeapTuple SearchSysCache4(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:251
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition syscache.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
Relation table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok)
Definition table.c:103
Oid get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
Definition trigger.c:1372
String * makeString(char *str)
Definition value.c:63
Float * makeFloat(char *numericStr)
Definition value.c:37
#define strVal(v)
Definition value.h:82
text * cstring_to_text(const char *s)
Definition varlena.c:184
const char * description
const char * type
const char * name