Age Owner Branch data TLA Line data Source code
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"
23 : : #include "catalog/objectaddress.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"
29 : : #include "catalog/pg_auth_members.h"
30 : : #include "catalog/pg_cast.h"
31 : : #include "catalog/pg_collation.h"
32 : : #include "catalog/pg_constraint.h"
33 : : #include "catalog/pg_conversion.h"
34 : : #include "catalog/pg_database.h"
35 : : #include "catalog/pg_default_acl.h"
36 : : #include "catalog/pg_event_trigger.h"
37 : : #include "catalog/pg_extension.h"
38 : : #include "catalog/pg_foreign_data_wrapper.h"
39 : : #include "catalog/pg_foreign_server.h"
40 : : #include "catalog/pg_language.h"
41 : : #include "catalog/pg_largeobject.h"
42 : : #include "catalog/pg_largeobject_metadata.h"
43 : : #include "catalog/pg_namespace.h"
44 : : #include "catalog/pg_opclass.h"
45 : : #include "catalog/pg_operator.h"
46 : : #include "catalog/pg_opfamily.h"
47 : : #include "catalog/pg_parameter_acl.h"
48 : : #include "catalog/pg_policy.h"
49 : : #include "catalog/pg_proc.h"
50 : : #include "catalog/pg_publication.h"
51 : : #include "catalog/pg_publication_namespace.h"
52 : : #include "catalog/pg_publication_rel.h"
53 : : #include "catalog/pg_rewrite.h"
54 : : #include "catalog/pg_statistic_ext.h"
55 : : #include "catalog/pg_subscription.h"
56 : : #include "catalog/pg_tablespace.h"
57 : : #include "catalog/pg_transform.h"
58 : : #include "catalog/pg_trigger.h"
59 : : #include "catalog/pg_ts_config.h"
60 : : #include "catalog/pg_ts_dict.h"
61 : : #include "catalog/pg_ts_parser.h"
62 : : #include "catalog/pg_ts_template.h"
63 : : #include "catalog/pg_type.h"
64 : : #include "catalog/pg_user_mapping.h"
65 : : #include "commands/defrem.h"
66 : : #include "commands/event_trigger.h"
67 : : #include "commands/extension.h"
68 : : #include "commands/policy.h"
69 : : #include "commands/proclang.h"
70 : : #include "commands/tablespace.h"
71 : : #include "commands/trigger.h"
72 : : #include "foreign/foreign.h"
73 : : #include "funcapi.h"
74 : : #include "miscadmin.h"
75 : : #include "parser/parse_func.h"
76 : : #include "parser/parse_oper.h"
77 : : #include "parser/parse_type.h"
78 : : #include "rewrite/rewriteSupport.h"
79 : : #include "storage/large_object.h"
80 : : #include "storage/lmgr.h"
81 : : #include "storage/sinval.h"
82 : : #include "utils/acl.h"
83 : : #include "utils/builtins.h"
84 : : #include "utils/fmgroids.h"
85 : : #include "utils/lsyscache.h"
86 : : #include "utils/memutils.h"
87 : : #include "utils/regproc.h"
88 : : #include "utils/syscache.h"
89 : :
90 : : /*
91 : : * ObjectProperty
92 : : *
93 : : * This array provides a common part of system object structure; to help
94 : : * consolidate routines to handle various kind of object classes.
95 : : */
96 : : typedef struct
97 : : {
98 : : const char *class_descr; /* string describing the catalog, for internal
99 : : * error messages */
100 : : Oid class_oid; /* oid of catalog */
101 : : Oid oid_index_oid; /* oid of index on system oid column */
102 : : SysCacheIdentifier oid_catcache_id; /* id of catcache on system oid column */
103 : : SysCacheIdentifier name_catcache_id; /* id of catcache on
104 : : * (name,namespace), or (name) if
105 : : * the object does not live in a
106 : : * namespace */
107 : : AttrNumber attnum_oid; /* attribute number of oid column */
108 : : AttrNumber attnum_name; /* attnum of name field */
109 : : AttrNumber attnum_namespace; /* attnum of namespace field */
110 : : AttrNumber attnum_owner; /* attnum of owner field */
111 : : AttrNumber attnum_acl; /* attnum of acl field */
112 : : ObjectType objtype; /* OBJECT_* of this object type */
113 : : bool is_nsp_name_unique; /* can the nsp/name combination (or name
114 : : * alone, if there's no namespace) be
115 : : * considered a unique identifier for an
116 : : * object of this class? */
117 : : } ObjectPropertyType;
118 : :
119 : : static const ObjectPropertyType ObjectProperty[] =
120 : : {
121 : : {
122 : : "access method",
123 : : AccessMethodRelationId,
124 : : AmOidIndexId,
125 : : AMOID,
126 : : AMNAME,
127 : : Anum_pg_am_oid,
128 : : Anum_pg_am_amname,
129 : : InvalidAttrNumber,
130 : : InvalidAttrNumber,
131 : : InvalidAttrNumber,
132 : : OBJECT_ACCESS_METHOD,
133 : : true
134 : : },
135 : : {
136 : : "access method operator",
137 : : AccessMethodOperatorRelationId,
138 : : AccessMethodOperatorOidIndexId,
139 : : SYSCACHEID_INVALID,
140 : : SYSCACHEID_INVALID,
141 : : Anum_pg_amop_oid,
142 : : InvalidAttrNumber,
143 : : InvalidAttrNumber,
144 : : InvalidAttrNumber,
145 : : InvalidAttrNumber,
146 : : OBJECT_AMOP,
147 : : false
148 : : },
149 : : {
150 : : "access method procedure",
151 : : AccessMethodProcedureRelationId,
152 : : AccessMethodProcedureOidIndexId,
153 : : SYSCACHEID_INVALID,
154 : : SYSCACHEID_INVALID,
155 : : Anum_pg_amproc_oid,
156 : : InvalidAttrNumber,
157 : : InvalidAttrNumber,
158 : : InvalidAttrNumber,
159 : : InvalidAttrNumber,
160 : : OBJECT_AMPROC,
161 : : false
162 : : },
163 : : {
164 : : "cast",
165 : : CastRelationId,
166 : : CastOidIndexId,
167 : : SYSCACHEID_INVALID,
168 : : SYSCACHEID_INVALID,
169 : : Anum_pg_cast_oid,
170 : : InvalidAttrNumber,
171 : : InvalidAttrNumber,
172 : : InvalidAttrNumber,
173 : : InvalidAttrNumber,
174 : : OBJECT_CAST,
175 : : false
176 : : },
177 : : {
178 : : "collation",
179 : : CollationRelationId,
180 : : CollationOidIndexId,
181 : : COLLOID,
182 : : SYSCACHEID_INVALID, /* COLLNAMEENCNSP also takes encoding */
183 : : Anum_pg_collation_oid,
184 : : Anum_pg_collation_collname,
185 : : Anum_pg_collation_collnamespace,
186 : : Anum_pg_collation_collowner,
187 : : InvalidAttrNumber,
188 : : OBJECT_COLLATION,
189 : : true
190 : : },
191 : : {
192 : : "constraint",
193 : : ConstraintRelationId,
194 : : ConstraintOidIndexId,
195 : : CONSTROID,
196 : : SYSCACHEID_INVALID,
197 : : Anum_pg_constraint_oid,
198 : : Anum_pg_constraint_conname,
199 : : Anum_pg_constraint_connamespace,
200 : : InvalidAttrNumber,
201 : : InvalidAttrNumber,
202 : : -1,
203 : : false
204 : : },
205 : : {
206 : : "conversion",
207 : : ConversionRelationId,
208 : : ConversionOidIndexId,
209 : : CONVOID,
210 : : CONNAMENSP,
211 : : Anum_pg_conversion_oid,
212 : : Anum_pg_conversion_conname,
213 : : Anum_pg_conversion_connamespace,
214 : : Anum_pg_conversion_conowner,
215 : : InvalidAttrNumber,
216 : : OBJECT_CONVERSION,
217 : : true
218 : : },
219 : : {
220 : : "database",
221 : : DatabaseRelationId,
222 : : DatabaseOidIndexId,
223 : : DATABASEOID,
224 : : SYSCACHEID_INVALID,
225 : : Anum_pg_database_oid,
226 : : Anum_pg_database_datname,
227 : : InvalidAttrNumber,
228 : : Anum_pg_database_datdba,
229 : : Anum_pg_database_datacl,
230 : : OBJECT_DATABASE,
231 : : true
232 : : },
233 : : {
234 : : "default ACL",
235 : : DefaultAclRelationId,
236 : : DefaultAclOidIndexId,
237 : : SYSCACHEID_INVALID,
238 : : SYSCACHEID_INVALID,
239 : : Anum_pg_default_acl_oid,
240 : : InvalidAttrNumber,
241 : : InvalidAttrNumber,
242 : : InvalidAttrNumber,
243 : : InvalidAttrNumber,
244 : : OBJECT_DEFACL,
245 : : false
246 : : },
247 : : {
248 : : "extension",
249 : : ExtensionRelationId,
250 : : ExtensionOidIndexId,
251 : : SYSCACHEID_INVALID,
252 : : SYSCACHEID_INVALID,
253 : : Anum_pg_extension_oid,
254 : : Anum_pg_extension_extname,
255 : : InvalidAttrNumber, /* extension doesn't belong to extnamespace */
256 : : Anum_pg_extension_extowner,
257 : : InvalidAttrNumber,
258 : : OBJECT_EXTENSION,
259 : : true
260 : : },
261 : : {
262 : : "foreign-data wrapper",
263 : : ForeignDataWrapperRelationId,
264 : : ForeignDataWrapperOidIndexId,
265 : : FOREIGNDATAWRAPPEROID,
266 : : FOREIGNDATAWRAPPERNAME,
267 : : Anum_pg_foreign_data_wrapper_oid,
268 : : Anum_pg_foreign_data_wrapper_fdwname,
269 : : InvalidAttrNumber,
270 : : Anum_pg_foreign_data_wrapper_fdwowner,
271 : : Anum_pg_foreign_data_wrapper_fdwacl,
272 : : OBJECT_FDW,
273 : : true
274 : : },
275 : : {
276 : : "foreign server",
277 : : ForeignServerRelationId,
278 : : ForeignServerOidIndexId,
279 : : FOREIGNSERVEROID,
280 : : FOREIGNSERVERNAME,
281 : : Anum_pg_foreign_server_oid,
282 : : Anum_pg_foreign_server_srvname,
283 : : InvalidAttrNumber,
284 : : Anum_pg_foreign_server_srvowner,
285 : : Anum_pg_foreign_server_srvacl,
286 : : OBJECT_FOREIGN_SERVER,
287 : : true
288 : : },
289 : : {
290 : : "function",
291 : : ProcedureRelationId,
292 : : ProcedureOidIndexId,
293 : : PROCOID,
294 : : SYSCACHEID_INVALID, /* PROCNAMEARGSNSP also takes argument types */
295 : : Anum_pg_proc_oid,
296 : : Anum_pg_proc_proname,
297 : : Anum_pg_proc_pronamespace,
298 : : Anum_pg_proc_proowner,
299 : : Anum_pg_proc_proacl,
300 : : OBJECT_FUNCTION,
301 : : false
302 : : },
303 : : {
304 : : "language",
305 : : LanguageRelationId,
306 : : LanguageOidIndexId,
307 : : LANGOID,
308 : : LANGNAME,
309 : : Anum_pg_language_oid,
310 : : Anum_pg_language_lanname,
311 : : InvalidAttrNumber,
312 : : Anum_pg_language_lanowner,
313 : : Anum_pg_language_lanacl,
314 : : OBJECT_LANGUAGE,
315 : : true
316 : : },
317 : : {
318 : : "large object metadata",
319 : : LargeObjectMetadataRelationId,
320 : : LargeObjectMetadataOidIndexId,
321 : : SYSCACHEID_INVALID,
322 : : SYSCACHEID_INVALID,
323 : : Anum_pg_largeobject_metadata_oid,
324 : : InvalidAttrNumber,
325 : : InvalidAttrNumber,
326 : : Anum_pg_largeobject_metadata_lomowner,
327 : : Anum_pg_largeobject_metadata_lomacl,
328 : : OBJECT_LARGEOBJECT,
329 : : false
330 : : },
331 : : {
332 : : "operator class",
333 : : OperatorClassRelationId,
334 : : OpclassOidIndexId,
335 : : CLAOID,
336 : : SYSCACHEID_INVALID, /* CLAAMNAMENSP also takes opcmethod */
337 : : Anum_pg_opclass_oid,
338 : : Anum_pg_opclass_opcname,
339 : : Anum_pg_opclass_opcnamespace,
340 : : Anum_pg_opclass_opcowner,
341 : : InvalidAttrNumber,
342 : : OBJECT_OPCLASS,
343 : : true
344 : : },
345 : : {
346 : : "operator",
347 : : OperatorRelationId,
348 : : OperatorOidIndexId,
349 : : OPEROID,
350 : : SYSCACHEID_INVALID, /* OPERNAMENSP also takes left and right type */
351 : : Anum_pg_operator_oid,
352 : : Anum_pg_operator_oprname,
353 : : Anum_pg_operator_oprnamespace,
354 : : Anum_pg_operator_oprowner,
355 : : InvalidAttrNumber,
356 : : OBJECT_OPERATOR,
357 : : false
358 : : },
359 : : {
360 : : "operator family",
361 : : OperatorFamilyRelationId,
362 : : OpfamilyOidIndexId,
363 : : OPFAMILYOID,
364 : : SYSCACHEID_INVALID, /* OPFAMILYAMNAMENSP also takes opfmethod */
365 : : Anum_pg_opfamily_oid,
366 : : Anum_pg_opfamily_opfname,
367 : : Anum_pg_opfamily_opfnamespace,
368 : : Anum_pg_opfamily_opfowner,
369 : : InvalidAttrNumber,
370 : : OBJECT_OPFAMILY,
371 : : true
372 : : },
373 : : {
374 : : "role",
375 : : AuthIdRelationId,
376 : : AuthIdOidIndexId,
377 : : AUTHOID,
378 : : AUTHNAME,
379 : : Anum_pg_authid_oid,
380 : : Anum_pg_authid_rolname,
381 : : InvalidAttrNumber,
382 : : InvalidAttrNumber,
383 : : InvalidAttrNumber,
384 : : OBJECT_ROLE,
385 : : true
386 : : },
387 : : {
388 : : "role membership",
389 : : AuthMemRelationId,
390 : : AuthMemOidIndexId,
391 : : SYSCACHEID_INVALID,
392 : : SYSCACHEID_INVALID,
393 : : Anum_pg_auth_members_oid,
394 : : InvalidAttrNumber,
395 : : InvalidAttrNumber,
396 : : Anum_pg_auth_members_grantor,
397 : : InvalidAttrNumber,
398 : : -1,
399 : : true
400 : : },
401 : : {
402 : : "rule",
403 : : RewriteRelationId,
404 : : RewriteOidIndexId,
405 : : SYSCACHEID_INVALID,
406 : : SYSCACHEID_INVALID,
407 : : Anum_pg_rewrite_oid,
408 : : Anum_pg_rewrite_rulename,
409 : : InvalidAttrNumber,
410 : : InvalidAttrNumber,
411 : : InvalidAttrNumber,
412 : : OBJECT_RULE,
413 : : false
414 : : },
415 : : {
416 : : "schema",
417 : : NamespaceRelationId,
418 : : NamespaceOidIndexId,
419 : : NAMESPACEOID,
420 : : NAMESPACENAME,
421 : : Anum_pg_namespace_oid,
422 : : Anum_pg_namespace_nspname,
423 : : InvalidAttrNumber,
424 : : Anum_pg_namespace_nspowner,
425 : : Anum_pg_namespace_nspacl,
426 : : OBJECT_SCHEMA,
427 : : true
428 : : },
429 : : {
430 : : "relation",
431 : : RelationRelationId,
432 : : ClassOidIndexId,
433 : : RELOID,
434 : : RELNAMENSP,
435 : : Anum_pg_class_oid,
436 : : Anum_pg_class_relname,
437 : : Anum_pg_class_relnamespace,
438 : : Anum_pg_class_relowner,
439 : : Anum_pg_class_relacl,
440 : : OBJECT_TABLE,
441 : : true
442 : : },
443 : : {
444 : : "tablespace",
445 : : TableSpaceRelationId,
446 : : TablespaceOidIndexId,
447 : : TABLESPACEOID,
448 : : SYSCACHEID_INVALID,
449 : : Anum_pg_tablespace_oid,
450 : : Anum_pg_tablespace_spcname,
451 : : InvalidAttrNumber,
452 : : Anum_pg_tablespace_spcowner,
453 : : Anum_pg_tablespace_spcacl,
454 : : OBJECT_TABLESPACE,
455 : : true
456 : : },
457 : : {
458 : : "transform",
459 : : TransformRelationId,
460 : : TransformOidIndexId,
461 : : TRFOID,
462 : : SYSCACHEID_INVALID,
463 : : Anum_pg_transform_oid,
464 : : InvalidAttrNumber,
465 : : InvalidAttrNumber,
466 : : InvalidAttrNumber,
467 : : InvalidAttrNumber,
468 : : OBJECT_TRANSFORM,
469 : : false
470 : : },
471 : : {
472 : : "trigger",
473 : : TriggerRelationId,
474 : : TriggerOidIndexId,
475 : : SYSCACHEID_INVALID,
476 : : SYSCACHEID_INVALID,
477 : : Anum_pg_trigger_oid,
478 : : Anum_pg_trigger_tgname,
479 : : InvalidAttrNumber,
480 : : InvalidAttrNumber,
481 : : InvalidAttrNumber,
482 : : OBJECT_TRIGGER,
483 : : false
484 : : },
485 : : {
486 : : "policy",
487 : : PolicyRelationId,
488 : : PolicyOidIndexId,
489 : : SYSCACHEID_INVALID,
490 : : SYSCACHEID_INVALID,
491 : : Anum_pg_policy_oid,
492 : : Anum_pg_policy_polname,
493 : : InvalidAttrNumber,
494 : : InvalidAttrNumber,
495 : : InvalidAttrNumber,
496 : : OBJECT_POLICY,
497 : : false
498 : : },
499 : : {
500 : : "event trigger",
501 : : EventTriggerRelationId,
502 : : EventTriggerOidIndexId,
503 : : EVENTTRIGGEROID,
504 : : EVENTTRIGGERNAME,
505 : : Anum_pg_event_trigger_oid,
506 : : Anum_pg_event_trigger_evtname,
507 : : InvalidAttrNumber,
508 : : Anum_pg_event_trigger_evtowner,
509 : : InvalidAttrNumber,
510 : : OBJECT_EVENT_TRIGGER,
511 : : true
512 : : },
513 : : {
514 : : "text search configuration",
515 : : TSConfigRelationId,
516 : : TSConfigOidIndexId,
517 : : TSCONFIGOID,
518 : : TSCONFIGNAMENSP,
519 : : Anum_pg_ts_config_oid,
520 : : Anum_pg_ts_config_cfgname,
521 : : Anum_pg_ts_config_cfgnamespace,
522 : : Anum_pg_ts_config_cfgowner,
523 : : InvalidAttrNumber,
524 : : OBJECT_TSCONFIGURATION,
525 : : true
526 : : },
527 : : {
528 : : "text search dictionary",
529 : : TSDictionaryRelationId,
530 : : TSDictionaryOidIndexId,
531 : : TSDICTOID,
532 : : TSDICTNAMENSP,
533 : : Anum_pg_ts_dict_oid,
534 : : Anum_pg_ts_dict_dictname,
535 : : Anum_pg_ts_dict_dictnamespace,
536 : : Anum_pg_ts_dict_dictowner,
537 : : InvalidAttrNumber,
538 : : OBJECT_TSDICTIONARY,
539 : : true
540 : : },
541 : : {
542 : : "text search parser",
543 : : TSParserRelationId,
544 : : TSParserOidIndexId,
545 : : TSPARSEROID,
546 : : TSPARSERNAMENSP,
547 : : Anum_pg_ts_parser_oid,
548 : : Anum_pg_ts_parser_prsname,
549 : : Anum_pg_ts_parser_prsnamespace,
550 : : InvalidAttrNumber,
551 : : InvalidAttrNumber,
552 : : OBJECT_TSPARSER,
553 : : true
554 : : },
555 : : {
556 : : "text search template",
557 : : TSTemplateRelationId,
558 : : TSTemplateOidIndexId,
559 : : TSTEMPLATEOID,
560 : : TSTEMPLATENAMENSP,
561 : : Anum_pg_ts_template_oid,
562 : : Anum_pg_ts_template_tmplname,
563 : : Anum_pg_ts_template_tmplnamespace,
564 : : InvalidAttrNumber,
565 : : InvalidAttrNumber,
566 : : OBJECT_TSTEMPLATE,
567 : : true,
568 : : },
569 : : {
570 : : "type",
571 : : TypeRelationId,
572 : : TypeOidIndexId,
573 : : TYPEOID,
574 : : TYPENAMENSP,
575 : : Anum_pg_type_oid,
576 : : Anum_pg_type_typname,
577 : : Anum_pg_type_typnamespace,
578 : : Anum_pg_type_typowner,
579 : : Anum_pg_type_typacl,
580 : : OBJECT_TYPE,
581 : : true
582 : : },
583 : : {
584 : : "publication",
585 : : PublicationRelationId,
586 : : PublicationObjectIndexId,
587 : : PUBLICATIONOID,
588 : : PUBLICATIONNAME,
589 : : Anum_pg_publication_oid,
590 : : Anum_pg_publication_pubname,
591 : : InvalidAttrNumber,
592 : : Anum_pg_publication_pubowner,
593 : : InvalidAttrNumber,
594 : : OBJECT_PUBLICATION,
595 : : true
596 : : },
597 : : {
598 : : "subscription",
599 : : SubscriptionRelationId,
600 : : SubscriptionObjectIndexId,
601 : : SUBSCRIPTIONOID,
602 : : SUBSCRIPTIONNAME,
603 : : Anum_pg_subscription_oid,
604 : : Anum_pg_subscription_subname,
605 : : InvalidAttrNumber,
606 : : Anum_pg_subscription_subowner,
607 : : InvalidAttrNumber,
608 : : OBJECT_SUBSCRIPTION,
609 : : true
610 : : },
611 : : {
612 : : "extended statistics",
613 : : StatisticExtRelationId,
614 : : StatisticExtOidIndexId,
615 : : STATEXTOID,
616 : : STATEXTNAMENSP,
617 : : Anum_pg_statistic_ext_oid,
618 : : Anum_pg_statistic_ext_stxname,
619 : : Anum_pg_statistic_ext_stxnamespace,
620 : : Anum_pg_statistic_ext_stxowner,
621 : : InvalidAttrNumber, /* no ACL (same as relation) */
622 : : OBJECT_STATISTIC_EXT,
623 : : true
624 : : },
625 : : {
626 : : "user mapping",
627 : : UserMappingRelationId,
628 : : UserMappingOidIndexId,
629 : : USERMAPPINGOID,
630 : : SYSCACHEID_INVALID,
631 : : Anum_pg_user_mapping_oid,
632 : : InvalidAttrNumber,
633 : : InvalidAttrNumber,
634 : : InvalidAttrNumber,
635 : : InvalidAttrNumber,
636 : : OBJECT_USER_MAPPING,
637 : : false
638 : : },
639 : : };
640 : :
641 : : /*
642 : : * This struct maps the string object types as returned by
643 : : * getObjectTypeDescription into ObjectType enum values. Note that some enum
644 : : * values can be obtained by different names, and that some string object types
645 : : * do not have corresponding values in the output enum. The user of this map
646 : : * must be careful to test for invalid values being returned.
647 : : *
648 : : * To ease maintenance, this follows the order of getObjectTypeDescription.
649 : : */
650 : : static const struct object_type_map
651 : : {
652 : : const char *tm_name;
653 : : ObjectType tm_type;
654 : : }
655 : :
656 : : ObjectTypeMap[] =
657 : : {
658 : : {
659 : : "table", OBJECT_TABLE
660 : : },
661 : : {
662 : : "index", OBJECT_INDEX
663 : : },
664 : : {
665 : : "sequence", OBJECT_SEQUENCE
666 : : },
667 : : {
668 : : "toast table", -1
669 : : }, /* unmapped */
670 : : {
671 : : "view", OBJECT_VIEW
672 : : },
673 : : {
674 : : "materialized view", OBJECT_MATVIEW
675 : : },
676 : : {
677 : : "composite type", -1
678 : : }, /* unmapped */
679 : : {
680 : : "foreign table", OBJECT_FOREIGN_TABLE
681 : : },
682 : : {
683 : : "table column", OBJECT_COLUMN
684 : : },
685 : : {
686 : : "index column", -1
687 : : }, /* unmapped */
688 : : {
689 : : "sequence column", -1
690 : : }, /* unmapped */
691 : : {
692 : : "toast table column", -1
693 : : }, /* unmapped */
694 : : {
695 : : "view column", -1
696 : : }, /* unmapped */
697 : : {
698 : : "materialized view column", -1
699 : : }, /* unmapped */
700 : : {
701 : : "composite type column", -1
702 : : }, /* unmapped */
703 : : {
704 : : "foreign table column", OBJECT_COLUMN
705 : : },
706 : : {
707 : : "aggregate", OBJECT_AGGREGATE
708 : : },
709 : : {
710 : : "function", OBJECT_FUNCTION
711 : : },
712 : : {
713 : : "procedure", OBJECT_PROCEDURE
714 : : },
715 : : {
716 : : "type", OBJECT_TYPE
717 : : },
718 : : {
719 : : "cast", OBJECT_CAST
720 : : },
721 : : {
722 : : "collation", OBJECT_COLLATION
723 : : },
724 : : {
725 : : "table constraint", OBJECT_TABCONSTRAINT
726 : : },
727 : : {
728 : : "domain constraint", OBJECT_DOMCONSTRAINT
729 : : },
730 : : {
731 : : "conversion", OBJECT_CONVERSION
732 : : },
733 : : {
734 : : "default value", OBJECT_DEFAULT
735 : : },
736 : : {
737 : : "language", OBJECT_LANGUAGE
738 : : },
739 : : {
740 : : "large object", OBJECT_LARGEOBJECT
741 : : },
742 : : {
743 : : "operator", OBJECT_OPERATOR
744 : : },
745 : : {
746 : : "operator class", OBJECT_OPCLASS
747 : : },
748 : : {
749 : : "operator family", OBJECT_OPFAMILY
750 : : },
751 : : {
752 : : "access method", OBJECT_ACCESS_METHOD
753 : : },
754 : : {
755 : : "operator of access method", OBJECT_AMOP
756 : : },
757 : : {
758 : : "function of access method", OBJECT_AMPROC
759 : : },
760 : : {
761 : : "rule", OBJECT_RULE
762 : : },
763 : : {
764 : : "trigger", OBJECT_TRIGGER
765 : : },
766 : : {
767 : : "schema", OBJECT_SCHEMA
768 : : },
769 : : {
770 : : "text search parser", OBJECT_TSPARSER
771 : : },
772 : : {
773 : : "text search dictionary", OBJECT_TSDICTIONARY
774 : : },
775 : : {
776 : : "text search template", OBJECT_TSTEMPLATE
777 : : },
778 : : {
779 : : "text search configuration", OBJECT_TSCONFIGURATION
780 : : },
781 : : {
782 : : "role", OBJECT_ROLE
783 : : },
784 : : {
785 : : "role membership", -1 /* unmapped */
786 : : },
787 : : {
788 : : "database", OBJECT_DATABASE
789 : : },
790 : : {
791 : : "tablespace", OBJECT_TABLESPACE
792 : : },
793 : : {
794 : : "foreign-data wrapper", OBJECT_FDW
795 : : },
796 : : {
797 : : "server", OBJECT_FOREIGN_SERVER
798 : : },
799 : : {
800 : : "user mapping", OBJECT_USER_MAPPING
801 : : },
802 : : {
803 : : "default acl", OBJECT_DEFACL
804 : : },
805 : : {
806 : : "extension", OBJECT_EXTENSION
807 : : },
808 : : {
809 : : "event trigger", OBJECT_EVENT_TRIGGER
810 : : },
811 : : {
812 : : "parameter ACL", OBJECT_PARAMETER_ACL
813 : : },
814 : : {
815 : : "policy", OBJECT_POLICY
816 : : },
817 : : {
818 : : "publication", OBJECT_PUBLICATION
819 : : },
820 : : {
821 : : "publication namespace", OBJECT_PUBLICATION_NAMESPACE
822 : : },
823 : : {
824 : : "publication relation", OBJECT_PUBLICATION_REL
825 : : },
826 : : {
827 : : "subscription", OBJECT_SUBSCRIPTION
828 : : },
829 : : {
830 : : "transform", OBJECT_TRANSFORM
831 : : },
832 : : {
833 : : "statistics object", OBJECT_STATISTIC_EXT
834 : : }
835 : : };
836 : :
837 : : const ObjectAddress InvalidObjectAddress =
838 : : {
839 : : InvalidOid,
840 : : InvalidOid,
841 : : 0
842 : : };
843 : :
844 : : static ObjectAddress get_object_address_unqualified(ObjectType objtype,
845 : : String *strval, bool missing_ok);
846 : : static ObjectAddress get_relation_by_qualified_name(ObjectType objtype,
847 : : List *object, Relation *relp,
848 : : LOCKMODE lockmode, bool missing_ok);
849 : : static ObjectAddress get_object_address_relobject(ObjectType objtype,
850 : : List *object, Relation *relp, bool missing_ok);
851 : : static ObjectAddress get_object_address_attribute(ObjectType objtype,
852 : : List *object, Relation *relp,
853 : : LOCKMODE lockmode, bool missing_ok);
854 : : static ObjectAddress get_object_address_attrdef(ObjectType objtype,
855 : : List *object, Relation *relp, LOCKMODE lockmode,
856 : : bool missing_ok);
857 : : static ObjectAddress get_object_address_type(ObjectType objtype,
858 : : TypeName *typename, bool missing_ok);
859 : : static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object,
860 : : bool missing_ok);
861 : : static ObjectAddress get_object_address_opf_member(ObjectType objtype,
862 : : List *object, bool missing_ok);
863 : :
864 : : static ObjectAddress get_object_address_usermapping(List *object,
865 : : bool missing_ok);
866 : : static ObjectAddress get_object_address_publication_rel(List *object,
867 : : Relation *relp,
868 : : bool missing_ok);
869 : : static ObjectAddress get_object_address_publication_schema(List *object,
870 : : bool missing_ok);
871 : : static ObjectAddress get_object_address_defacl(List *object,
872 : : bool missing_ok);
873 : : static const ObjectPropertyType *get_object_property_data(Oid class_id);
874 : :
875 : : static void getRelationDescription(StringInfo buffer, Oid relid,
876 : : bool missing_ok);
877 : : static void getOpFamilyDescription(StringInfo buffer, Oid opfid,
878 : : bool missing_ok);
879 : : static void getRelationTypeDescription(StringInfo buffer, Oid relid,
880 : : int32 objectSubId, bool missing_ok);
881 : : static void getProcedureTypeDescription(StringInfo buffer, Oid procid,
882 : : bool missing_ok);
883 : : static void getConstraintTypeDescription(StringInfo buffer, Oid constroid,
884 : : bool missing_ok);
885 : : static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
886 : : bool missing_ok);
887 : : static void getRelationIdentity(StringInfo buffer, Oid relid, List **object,
888 : : bool missing_ok);
889 : :
890 : : /*
891 : : * Translate an object name and arguments (as passed by the parser) to an
892 : : * ObjectAddress.
893 : : *
894 : : * The returned object will be locked using the specified lockmode. If a
895 : : * sub-object is looked up, the parent object will be locked instead.
896 : : *
897 : : * If the object is a relation or a child object of a relation (e.g. an
898 : : * attribute or constraint), the relation is also opened and *relp receives
899 : : * the open relcache entry pointer; otherwise, *relp is set to NULL.
900 : : * (relp can be NULL if the caller never passes a relation-related object.) This
901 : : * is a bit grotty but it makes life simpler, since the caller will
902 : : * typically need the relcache entry too. Caller must close the relcache
903 : : * entry when done with it. The relation is locked with the specified lockmode
904 : : * if the target object is the relation itself or an attribute, but for other
905 : : * child objects, only AccessShareLock is acquired on the relation.
906 : : *
907 : : * If the object is not found, an error is thrown, unless missing_ok is
908 : : * true. In this case, no lock is acquired, relp is set to NULL, and the
909 : : * returned address has objectId set to InvalidOid.
910 : : *
911 : : * We don't currently provide a function to release the locks acquired here;
912 : : * typically, the lock must be held until commit to guard against a concurrent
913 : : * drop operation.
914 : : *
915 : : * Note: If the object is not found, we don't give any indication of the
916 : : * reason. (It might have been a missing schema if the name was qualified, or
917 : : * a nonexistent type name in case of a cast, function or operator; etc).
918 : : * Currently there is only one caller that might be interested in such info, so
919 : : * we don't spend much effort here. If more callers start to care, it might be
920 : : * better to add some support for that in this function.
921 : : */
922 : : ObjectAddress
3410 peter_e@gmx.net 923 :CBC 12020 : get_object_address(ObjectType objtype, Node *object,
924 : : Relation *relp, LOCKMODE lockmode, bool missing_ok)
925 : : {
1214 peter@eisentraut.org 926 : 12020 : ObjectAddress address = {InvalidOid, InvalidOid, 0};
5232 rhaas@postgresql.org 927 : 12020 : ObjectAddress old_address = {InvalidOid, InvalidOid, 0};
5453 bruce@momjian.us 928 : 12020 : Relation relation = NULL;
929 : : uint64 inval_count;
930 : :
931 : : /* Some kind of lock must be taken. */
5679 rhaas@postgresql.org 932 [ + - ]: 12020 : Assert(lockmode != NoLock);
933 : :
934 : : for (;;)
935 : : {
936 : : /*
937 : : * Remember this value, so that, after looking up the object name and
938 : : * locking it, we can check whether any invalidation messages have
939 : : * been processed that might require a do-over.
940 : : */
5232 941 : 12118 : inval_count = SharedInvalidMessageCounter;
942 : :
943 : : /* Look up object address. */
944 [ + + + + : 12118 : switch (objtype)
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ - ]
945 : : {
946 : 308 : case OBJECT_INDEX:
947 : : case OBJECT_SEQUENCE:
948 : : case OBJECT_TABLE:
949 : : case OBJECT_VIEW:
950 : : case OBJECT_MATVIEW:
951 : : case OBJECT_FOREIGN_TABLE:
952 : : address =
3410 peter_e@gmx.net 953 : 308 : get_relation_by_qualified_name(objtype, castNode(List, object),
954 : : &relation, lockmode,
955 : : missing_ok);
5232 rhaas@postgresql.org 956 : 187 : break;
1214 peter@eisentraut.org 957 : 164 : case OBJECT_ATTRIBUTE:
958 : : case OBJECT_COLUMN:
959 : : address =
3410 peter_e@gmx.net 960 : 164 : get_object_address_attribute(objtype, castNode(List, object),
961 : : &relation, lockmode,
962 : : missing_ok);
5232 rhaas@postgresql.org 963 : 118 : break;
4100 alvherre@alvh.no-ip. 964 : 24 : case OBJECT_DEFAULT:
965 : : address =
3410 peter_e@gmx.net 966 : 24 : get_object_address_attrdef(objtype, castNode(List, object),
967 : : &relation, lockmode,
968 : : missing_ok);
4100 alvherre@alvh.no-ip. 969 : 6 : break;
5232 rhaas@postgresql.org 970 : 858 : case OBJECT_RULE:
971 : : case OBJECT_TRIGGER:
972 : : case OBJECT_TABCONSTRAINT:
973 : : case OBJECT_POLICY:
3410 peter_e@gmx.net 974 : 858 : address = get_object_address_relobject(objtype, castNode(List, object),
975 : : &relation, missing_ok);
5232 rhaas@postgresql.org 976 : 738 : break;
4100 alvherre@alvh.no-ip. 977 : 36 : case OBJECT_DOMCONSTRAINT:
978 : : {
979 : : List *objlist;
980 : : ObjectAddress domaddr;
981 : : char *constrname;
982 : :
3410 peter_e@gmx.net 983 : 36 : objlist = castNode(List, object);
4017 alvherre@alvh.no-ip. 984 : 36 : domaddr = get_object_address_type(OBJECT_DOMAIN,
3189 tgl@sss.pgh.pa.us 985 : 36 : linitial_node(TypeName, objlist),
986 : : missing_ok);
3410 peter_e@gmx.net 987 : 30 : constrname = strVal(lsecond(objlist));
988 : :
4100 alvherre@alvh.no-ip. 989 : 30 : address.classId = ConstraintRelationId;
990 : 30 : address.objectId = get_domain_constraint_oid(domaddr.objectId,
991 : : constrname, missing_ok);
992 : 27 : address.objectSubId = 0;
993 : : }
994 : 27 : break;
5232 rhaas@postgresql.org 995 : 2203 : case OBJECT_DATABASE:
996 : : case OBJECT_EXTENSION:
997 : : case OBJECT_TABLESPACE:
998 : : case OBJECT_ROLE:
999 : : case OBJECT_SCHEMA:
1000 : : case OBJECT_LANGUAGE:
1001 : : case OBJECT_FDW:
1002 : : case OBJECT_FOREIGN_SERVER:
1003 : : case OBJECT_EVENT_TRIGGER:
1004 : : case OBJECT_PARAMETER_ACL:
1005 : : case OBJECT_ACCESS_METHOD:
1006 : : case OBJECT_PUBLICATION:
1007 : : case OBJECT_SUBSCRIPTION:
1008 : 2203 : address = get_object_address_unqualified(objtype,
1648 peter@eisentraut.org 1009 : 2203 : castNode(String, object), missing_ok);
5232 rhaas@postgresql.org 1010 : 2136 : break;
1011 : 883 : case OBJECT_TYPE:
1012 : : case OBJECT_DOMAIN:
3410 peter_e@gmx.net 1013 : 883 : address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
5232 rhaas@postgresql.org 1014 : 847 : break;
1015 : 3312 : case OBJECT_AGGREGATE:
1016 : : case OBJECT_FUNCTION:
1017 : : case OBJECT_PROCEDURE:
1018 : : case OBJECT_ROUTINE:
3364 peter_e@gmx.net 1019 : 3312 : address.classId = ProcedureRelationId;
3027 1020 : 3312 : address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
3364 1021 : 3166 : address.objectSubId = 0;
1022 : 3166 : break;
5232 rhaas@postgresql.org 1023 : 175 : case OBJECT_OPERATOR:
3364 peter_e@gmx.net 1024 : 175 : address.classId = OperatorRelationId;
1025 : 175 : address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
1026 : 145 : address.objectSubId = 0;
1027 : 145 : break;
5232 rhaas@postgresql.org 1028 : 81 : case OBJECT_COLLATION:
1029 : 81 : address.classId = CollationRelationId;
3410 peter_e@gmx.net 1030 : 81 : address.objectId = get_collation_oid(castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1031 : 75 : address.objectSubId = 0;
1032 : 75 : break;
1033 : 89 : case OBJECT_CONVERSION:
1034 : 89 : address.classId = ConversionRelationId;
3410 peter_e@gmx.net 1035 : 89 : address.objectId = get_conversion_oid(castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1036 : 65 : address.objectSubId = 0;
1037 : 65 : break;
1038 : 227 : case OBJECT_OPCLASS:
1039 : : case OBJECT_OPFAMILY:
3410 peter_e@gmx.net 1040 : 227 : address = get_object_address_opcf(objtype, castNode(List, object), missing_ok);
4017 alvherre@alvh.no-ip. 1041 : 185 : break;
1042 : 25 : case OBJECT_AMOP:
1043 : : case OBJECT_AMPROC:
3410 peter_e@gmx.net 1044 : 25 : address = get_object_address_opf_member(objtype, castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1045 : 13 : break;
1046 : 96 : case OBJECT_LARGEOBJECT:
1047 : 96 : address.classId = LargeObjectRelationId;
3410 peter_e@gmx.net 1048 : 96 : address.objectId = oidparse(object);
5232 rhaas@postgresql.org 1049 : 93 : address.objectSubId = 0;
1050 [ + + ]: 93 : if (!LargeObjectExists(address.objectId))
1051 : : {
1052 [ + + ]: 19 : if (!missing_ok)
5026 bruce@momjian.us 1053 [ + - ]: 9 : ereport(ERROR,
1054 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1055 : : errmsg("large object %u does not exist",
1056 : : address.objectId)));
1057 : : }
5232 rhaas@postgresql.org 1058 : 84 : break;
1059 : 41 : case OBJECT_CAST:
1060 : : {
3261 tgl@sss.pgh.pa.us 1061 : 41 : TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
1062 : 41 : TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
1063 : : Oid sourcetypeid;
1064 : : Oid targettypeid;
1065 : :
4434 alvherre@alvh.no-ip. 1066 : 41 : sourcetypeid = LookupTypeNameOid(NULL, sourcetype, missing_ok);
1067 : 38 : targettypeid = LookupTypeNameOid(NULL, targettype, missing_ok);
5232 rhaas@postgresql.org 1068 : 38 : address.classId = CastRelationId;
1069 : 35 : address.objectId =
1070 : 38 : get_cast_oid(sourcetypeid, targettypeid, missing_ok);
1071 : 35 : address.objectSubId = 0;
1072 : : }
1073 : 35 : break;
3976 peter_e@gmx.net 1074 : 25 : case OBJECT_TRANSFORM:
1075 : : {
3261 tgl@sss.pgh.pa.us 1076 : 25 : TypeName *typename = linitial_node(TypeName, castNode(List, object));
3410 peter_e@gmx.net 1077 : 25 : char *langname = strVal(lsecond(castNode(List, object)));
3976 1078 : 25 : Oid type_id = LookupTypeNameOid(NULL, typename, missing_ok);
1079 : 21 : Oid lang_id = get_language_oid(langname, missing_ok);
1080 : :
1081 : 20 : address.classId = TransformRelationId;
1082 : 20 : address.objectId =
1083 : 20 : get_transform_oid(type_id, lang_id, missing_ok);
1084 : 20 : address.objectSubId = 0;
1085 : : }
1086 : 20 : break;
5232 rhaas@postgresql.org 1087 : 49 : case OBJECT_TSPARSER:
1088 : 49 : address.classId = TSParserRelationId;
3410 peter_e@gmx.net 1089 : 49 : address.objectId = get_ts_parser_oid(castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1090 : 28 : address.objectSubId = 0;
1091 : 28 : break;
1092 : 1603 : case OBJECT_TSDICTIONARY:
1093 : 1603 : address.classId = TSDictionaryRelationId;
3410 peter_e@gmx.net 1094 : 1603 : address.objectId = get_ts_dict_oid(castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1095 : 1582 : address.objectSubId = 0;
1096 : 1582 : break;
1097 : 99 : case OBJECT_TSTEMPLATE:
1098 : 99 : address.classId = TSTemplateRelationId;
3410 peter_e@gmx.net 1099 : 99 : address.objectId = get_ts_template_oid(castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1100 : 78 : address.objectSubId = 0;
1101 : 78 : break;
1102 : 1601 : case OBJECT_TSCONFIGURATION:
1103 : 1601 : address.classId = TSConfigRelationId;
3410 peter_e@gmx.net 1104 : 1601 : address.objectId = get_ts_config_oid(castNode(List, object), missing_ok);
5232 rhaas@postgresql.org 1105 : 1580 : address.objectSubId = 0;
1106 : 1580 : break;
4022 alvherre@alvh.no-ip. 1107 : 9 : case OBJECT_USER_MAPPING:
3410 peter_e@gmx.net 1108 : 9 : address = get_object_address_usermapping(castNode(List, object),
1109 : : missing_ok);
4022 alvherre@alvh.no-ip. 1110 : 6 : break;
1600 akapila@postgresql.o 1111 : 9 : case OBJECT_PUBLICATION_NAMESPACE:
1112 : 9 : address = get_object_address_publication_schema(castNode(List, object),
1113 : : missing_ok);
1114 : 6 : break;
3342 peter_e@gmx.net 1115 : 15 : case OBJECT_PUBLICATION_REL:
3410 1116 : 15 : address = get_object_address_publication_rel(castNode(List, object),
1117 : : &relation,
1118 : : missing_ok);
3339 1119 : 6 : break;
4022 alvherre@alvh.no-ip. 1120 : 21 : case OBJECT_DEFACL:
3410 peter_e@gmx.net 1121 : 21 : address = get_object_address_defacl(castNode(List, object),
1122 : : missing_ok);
4022 alvherre@alvh.no-ip. 1123 : 12 : break;
3278 1124 : 165 : case OBJECT_STATISTIC_EXT:
1125 : 165 : address.classId = StatisticExtRelationId;
3227 tgl@sss.pgh.pa.us 1126 : 165 : address.objectId = get_statistics_object_oid(castNode(List, object),
1127 : : missing_ok);
3278 alvherre@alvh.no-ip. 1128 : 162 : address.objectSubId = 0;
1129 : 162 : break;
1130 : : /* no default, to let compiler warn about missing case */
1131 : : }
1132 : :
1214 peter@eisentraut.org 1133 [ - + ]: 11307 : if (!address.classId)
1214 peter@eisentraut.org 1134 [ # # ]:UBC 0 : elog(ERROR, "unrecognized object type: %d", (int) objtype);
1135 : :
1136 : : /*
1137 : : * If we could not find the supplied object, return without locking.
1138 : : */
5232 rhaas@postgresql.org 1139 [ + + ]:CBC 11307 : if (!OidIsValid(address.objectId))
1140 : : {
1141 [ - + ]: 197 : Assert(missing_ok);
1142 : 197 : return address;
1143 : : }
1144 : :
1145 : : /*
1146 : : * If we're retrying, see if we got the same answer as last time. If
1147 : : * so, we're done; if not, we locked the wrong thing, so give up our
1148 : : * lock.
1149 : : */
1150 [ + + ]: 11110 : if (OidIsValid(old_address.classId))
1151 : : {
1152 [ + - ]: 98 : if (old_address.classId == address.classId
1153 [ + - ]: 98 : && old_address.objectId == address.objectId
1154 [ + - ]: 98 : && old_address.objectSubId == address.objectSubId)
1155 : 98 : break;
5232 rhaas@postgresql.org 1156 [ # # ]:UBC 0 : if (old_address.classId != RelationRelationId)
1157 : : {
1158 [ # # ]: 0 : if (IsSharedRelation(old_address.classId))
1159 : 0 : UnlockSharedObject(old_address.classId,
1160 : : old_address.objectId,
1161 : : 0, lockmode);
1162 : : else
1163 : 0 : UnlockDatabaseObject(old_address.classId,
1164 : : old_address.objectId,
1165 : : 0, lockmode);
1166 : : }
1167 : : }
1168 : :
1169 : : /*
1170 : : * If we're dealing with a relation or attribute, then the relation is
1171 : : * already locked. Otherwise, we lock it now.
1172 : : */
5232 rhaas@postgresql.org 1173 [ + + ]:CBC 11012 : if (address.classId != RelationRelationId)
1174 : : {
1175 [ + + ]: 10707 : if (IsSharedRelation(address.classId))
1176 : 366 : LockSharedObject(address.classId, address.objectId, 0,
1177 : : lockmode);
1178 : : else
1179 : 10341 : LockDatabaseObject(address.classId, address.objectId, 0,
1180 : : lockmode);
1181 : : }
1182 : :
1183 : : /*
1184 : : * At this point, we've resolved the name to an OID and locked the
1185 : : * corresponding database object. However, it's possible that by the
1186 : : * time we acquire the lock on the object, concurrent DDL has modified
1187 : : * the database in such a way that the name we originally looked up no
1188 : : * longer resolves to that OID.
1189 : : *
1190 : : * We can be certain that this isn't an issue if (a) no shared
1191 : : * invalidation messages have been processed or (b) we've locked a
1192 : : * relation somewhere along the line. All the relation name lookups
1193 : : * in this module ultimately use RangeVarGetRelid() to acquire a
1194 : : * relation lock, and that function protects against the same kinds of
1195 : : * races we're worried about here. Even when operating on a
1196 : : * constraint, rule, or trigger, we still acquire AccessShareLock on
1197 : : * the relation, which is enough to freeze out any concurrent DDL.
1198 : : *
1199 : : * In all other cases, however, it's possible that the name we looked
1200 : : * up no longer refers to the object we locked, so we retry the lookup
1201 : : * and see whether we get the same answer.
1202 : : */
5026 bruce@momjian.us 1203 [ + + + + ]: 11012 : if (inval_count == SharedInvalidMessageCounter || relation != NULL)
1204 : : break;
1205 : 98 : old_address = address;
1206 : : }
1207 : :
1208 : : /* relp must be given if it's a relation */
485 peter@eisentraut.org 1209 [ + + - + ]: 11012 : Assert(!relation || relp);
1210 : :
1211 : : /* Return the object address and the relation. */
1212 [ + + ]: 11012 : if (relp)
1213 : 8869 : *relp = relation;
5679 rhaas@postgresql.org 1214 : 11012 : return address;
1215 : : }
1216 : :
1217 : : /*
1218 : : * Return an ObjectAddress based on a RangeVar and an object name. The
1219 : : * name of the relation identified by the RangeVar is prepended to the
1220 : : * (possibly empty) list passed in as object. This is useful to find
1221 : : * the ObjectAddress of objects that depend on a relation. All other
1222 : : * considerations are exactly as for get_object_address above.
1223 : : */
1224 : : ObjectAddress
3410 peter_e@gmx.net 1225 : 23 : get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object,
1226 : : Relation *relp, LOCKMODE lockmode,
1227 : : bool missing_ok)
1228 : : {
3631 alvherre@alvh.no-ip. 1229 [ + + ]: 23 : if (rel)
1230 : : {
3410 peter_e@gmx.net 1231 : 17 : object = lcons(makeString(rel->relname), object);
3631 alvherre@alvh.no-ip. 1232 [ + + ]: 17 : if (rel->schemaname)
3410 peter_e@gmx.net 1233 : 2 : object = lcons(makeString(rel->schemaname), object);
3631 alvherre@alvh.no-ip. 1234 [ - + ]: 17 : if (rel->catalogname)
3410 peter_e@gmx.net 1235 :UBC 0 : object = lcons(makeString(rel->catalogname), object);
1236 : : }
1237 : :
3410 peter_e@gmx.net 1238 :CBC 23 : return get_object_address(objtype, (Node *) object,
1239 : : relp, lockmode, missing_ok);
1240 : : }
1241 : :
1242 : : /*
1243 : : * Find an ObjectAddress for a type of object that is identified by an
1244 : : * unqualified name.
1245 : : */
1246 : : static ObjectAddress
5375 rhaas@postgresql.org 1247 : 2203 : get_object_address_unqualified(ObjectType objtype,
1248 : : String *strval, bool missing_ok)
1249 : : {
1250 : : const char *name;
1251 : : ObjectAddress address;
1252 : :
3410 peter_e@gmx.net 1253 : 2203 : name = strVal(strval);
1254 : :
1255 : : /* Translate name to OID. */
5679 rhaas@postgresql.org 1256 [ + + + + : 2203 : switch (objtype)
+ + + + +
+ + + +
- ]
1257 : : {
3644 alvherre@alvh.no-ip. 1258 : 39 : case OBJECT_ACCESS_METHOD:
1259 : 39 : address.classId = AccessMethodRelationId;
1260 : 39 : address.objectId = get_am_oid(name, missing_ok);
1261 : 33 : address.objectSubId = 0;
1262 : 33 : break;
5679 rhaas@postgresql.org 1263 : 305 : case OBJECT_DATABASE:
1264 : 305 : address.classId = DatabaseRelationId;
5375 1265 : 305 : address.objectId = get_database_oid(name, missing_ok);
5679 1266 : 302 : address.objectSubId = 0;
1267 : 302 : break;
5514 tgl@sss.pgh.pa.us 1268 : 250 : case OBJECT_EXTENSION:
1269 : 250 : address.classId = ExtensionRelationId;
5375 rhaas@postgresql.org 1270 : 250 : address.objectId = get_extension_oid(name, missing_ok);
5514 tgl@sss.pgh.pa.us 1271 : 244 : address.objectSubId = 0;
1272 : 244 : break;
5679 rhaas@postgresql.org 1273 : 9 : case OBJECT_TABLESPACE:
1274 : 9 : address.classId = TableSpaceRelationId;
5375 1275 : 9 : address.objectId = get_tablespace_oid(name, missing_ok);
5679 1276 : 6 : address.objectSubId = 0;
1277 : 6 : break;
1278 : 31 : case OBJECT_ROLE:
1279 : 31 : address.classId = AuthIdRelationId;
5375 1280 : 31 : address.objectId = get_role_oid(name, missing_ok);
5679 1281 : 27 : address.objectSubId = 0;
1282 : 27 : break;
1283 : 652 : case OBJECT_SCHEMA:
1284 : 652 : address.classId = NamespaceRelationId;
5375 1285 : 652 : address.objectId = get_namespace_oid(name, missing_ok);
5679 1286 : 643 : address.objectSubId = 0;
1287 : 643 : break;
1288 : 193 : case OBJECT_LANGUAGE:
1289 : 193 : address.classId = LanguageRelationId;
5375 1290 : 193 : address.objectId = get_language_oid(name, missing_ok);
5679 1291 : 187 : address.objectSubId = 0;
1292 : 187 : break;
5462 1293 : 147 : case OBJECT_FDW:
1294 : 147 : address.classId = ForeignDataWrapperRelationId;
5375 1295 : 147 : address.objectId = get_foreign_data_wrapper_oid(name, missing_ok);
5462 1296 : 138 : address.objectSubId = 0;
1297 : 138 : break;
1298 : 147 : case OBJECT_FOREIGN_SERVER:
1299 : 147 : address.classId = ForeignServerRelationId;
5375 1300 : 147 : address.objectId = get_foreign_server_oid(name, missing_ok);
5462 1301 : 138 : address.objectSubId = 0;
1302 : 138 : break;
4988 1303 : 86 : case OBJECT_EVENT_TRIGGER:
1304 : 86 : address.classId = EventTriggerRelationId;
1305 : 86 : address.objectId = get_event_trigger_oid(name, missing_ok);
1306 : 80 : address.objectSubId = 0;
1307 : 80 : break;
1439 tgl@sss.pgh.pa.us 1308 : 1 : case OBJECT_PARAMETER_ACL:
1309 : 1 : address.classId = ParameterAclRelationId;
1310 : 1 : address.objectId = ParameterAclLookup(name, missing_ok);
1311 : 1 : address.objectSubId = 0;
1312 : 1 : break;
3342 peter_e@gmx.net 1313 : 309 : case OBJECT_PUBLICATION:
1314 : 309 : address.classId = PublicationRelationId;
1315 : 309 : address.objectId = get_publication_oid(name, missing_ok);
1316 : 306 : address.objectSubId = 0;
1317 : 306 : break;
1318 : 34 : case OBJECT_SUBSCRIPTION:
1319 : 34 : address.classId = SubscriptionRelationId;
1320 : 34 : address.objectId = get_subscription_oid(name, missing_ok);
1321 : 31 : address.objectSubId = 0;
1322 : 31 : break;
5679 rhaas@postgresql.org 1323 :UBC 0 : default:
1223 peter@eisentraut.org 1324 [ # # ]: 0 : elog(ERROR, "unrecognized object type: %d", (int) objtype);
1325 : : /* placate compiler, which doesn't know elog won't return */
1326 : : address.classId = InvalidOid;
1327 : : address.objectId = InvalidOid;
1328 : : address.objectSubId = 0;
1329 : : }
1330 : :
5679 rhaas@postgresql.org 1331 :CBC 2136 : return address;
1332 : : }
1333 : :
1334 : : /*
1335 : : * Locate a relation by qualified name.
1336 : : */
1337 : : static ObjectAddress
3410 peter_e@gmx.net 1338 : 308 : get_relation_by_qualified_name(ObjectType objtype, List *object,
1339 : : Relation *relp, LOCKMODE lockmode,
1340 : : bool missing_ok)
1341 : : {
1342 : : Relation relation;
1343 : : ObjectAddress address;
1344 : :
5375 rhaas@postgresql.org 1345 : 308 : address.classId = RelationRelationId;
1346 : 308 : address.objectId = InvalidOid;
1347 : 308 : address.objectSubId = 0;
1348 : :
3410 peter_e@gmx.net 1349 : 308 : relation = relation_openrv_extended(makeRangeVarFromNameList(object),
1350 : : lockmode, missing_ok);
5375 rhaas@postgresql.org 1351 [ - + ]: 187 : if (!relation)
5375 rhaas@postgresql.org 1352 :UBC 0 : return address;
1353 : :
5679 rhaas@postgresql.org 1354 [ + + + + :CBC 187 : switch (objtype)
+ + - ]
1355 : : {
1356 : 61 : case OBJECT_INDEX:
2977 alvherre@alvh.no-ip. 1357 [ + + ]: 61 : if (relation->rd_rel->relkind != RELKIND_INDEX &&
1358 [ - + ]: 9 : relation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
5679 rhaas@postgresql.org 1359 [ # # ]:UBC 0 : ereport(ERROR,
1360 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1361 : : errmsg("\"%s\" is not an index",
1362 : : RelationGetRelationName(relation))));
5679 rhaas@postgresql.org 1363 :CBC 61 : break;
1364 : 14 : case OBJECT_SEQUENCE:
1365 [ - + ]: 14 : if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
5679 rhaas@postgresql.org 1366 [ # # ]:UBC 0 : ereport(ERROR,
1367 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1368 : : errmsg("\"%s\" is not a sequence",
1369 : : RelationGetRelationName(relation))));
5679 rhaas@postgresql.org 1370 :CBC 14 : break;
1371 : 41 : case OBJECT_TABLE:
3385 1372 [ + + ]: 41 : if (relation->rd_rel->relkind != RELKIND_RELATION &&
1373 [ - + ]: 9 : relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
5679 rhaas@postgresql.org 1374 [ # # ]:UBC 0 : ereport(ERROR,
1375 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1376 : : errmsg("\"%s\" is not a table",
1377 : : RelationGetRelationName(relation))));
5679 rhaas@postgresql.org 1378 :CBC 41 : break;
1379 : 41 : case OBJECT_VIEW:
1380 [ - + ]: 41 : if (relation->rd_rel->relkind != RELKIND_VIEW)
5679 rhaas@postgresql.org 1381 [ # # ]:UBC 0 : ereport(ERROR,
1382 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1383 : : errmsg("\"%s\" is not a view",
1384 : : RelationGetRelationName(relation))));
5679 rhaas@postgresql.org 1385 :CBC 41 : break;
4760 kgrittn@postgresql.o 1386 : 13 : case OBJECT_MATVIEW:
1387 [ - + ]: 13 : if (relation->rd_rel->relkind != RELKIND_MATVIEW)
4760 kgrittn@postgresql.o 1388 [ # # ]:UBC 0 : ereport(ERROR,
1389 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1390 : : errmsg("\"%s\" is not a materialized view",
1391 : : RelationGetRelationName(relation))));
4760 kgrittn@postgresql.o 1392 :CBC 13 : break;
5552 rhaas@postgresql.org 1393 : 17 : case OBJECT_FOREIGN_TABLE:
1394 [ - + ]: 17 : if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
5552 rhaas@postgresql.org 1395 [ # # ]:UBC 0 : ereport(ERROR,
1396 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1397 : : errmsg("\"%s\" is not a foreign table",
1398 : : RelationGetRelationName(relation))));
5552 rhaas@postgresql.org 1399 :CBC 17 : break;
5679 rhaas@postgresql.org 1400 :UBC 0 : default:
1223 peter@eisentraut.org 1401 [ # # ]: 0 : elog(ERROR, "unrecognized object type: %d", (int) objtype);
1402 : : break;
1403 : : }
1404 : :
1405 : : /* Done. */
5375 rhaas@postgresql.org 1406 :CBC 187 : address.objectId = RelationGetRelid(relation);
1407 : 187 : *relp = relation;
1408 : :
1409 : 187 : return address;
1410 : : }
1411 : :
1412 : : /*
1413 : : * Find object address for an object that is attached to a relation.
1414 : : *
1415 : : * Note that we take only an AccessShareLock on the relation. We need not
1416 : : * pass down the LOCKMODE from get_object_address(), because that is the lock
1417 : : * mode for the object itself, not the relation to which it is attached.
1418 : : */
1419 : : static ObjectAddress
3410 peter_e@gmx.net 1420 : 858 : get_object_address_relobject(ObjectType objtype, List *object,
1421 : : Relation *relp, bool missing_ok)
1422 : : {
1423 : : ObjectAddress address;
5679 rhaas@postgresql.org 1424 : 858 : Relation relation = NULL;
1425 : : int nnames;
1426 : : const char *depname;
1427 : : List *relname;
1428 : : Oid reloid;
1429 : :
1430 : : /* Extract name of dependent object. */
3410 peter_e@gmx.net 1431 : 858 : depname = strVal(llast(object));
1432 : :
1433 : : /* Separate relation name from dependent object name. */
1434 : 858 : nnames = list_length(object);
5679 rhaas@postgresql.org 1435 [ + + ]: 858 : if (nnames < 2)
3308 peter_e@gmx.net 1436 [ + - ]: 24 : ereport(ERROR,
1437 : : (errcode(ERRCODE_SYNTAX_ERROR),
1438 : : errmsg("must specify relation and object name")));
1439 : :
1440 : : /* Extract relation name and open relation. */
1341 drowley@postgresql.o 1441 : 834 : relname = list_copy_head(object, nnames - 1);
2610 andres@anarazel.de 1442 : 834 : relation = table_openrv_extended(makeRangeVarFromNameList(relname),
1443 : : AccessShareLock,
1444 : : missing_ok);
1445 : :
3308 peter_e@gmx.net 1446 [ + + ]: 768 : reloid = relation ? RelationGetRelid(relation) : InvalidOid;
1447 : :
1448 [ + + + + : 768 : switch (objtype)
- ]
1449 : : {
1450 : 128 : case OBJECT_RULE:
1451 : 128 : address.classId = RewriteRelationId;
1452 : 122 : address.objectId = relation ?
1453 [ + + ]: 128 : get_rewrite_oid(reloid, depname, missing_ok) : InvalidOid;
1454 : 122 : address.objectSubId = 0;
1455 : 122 : break;
1456 : 404 : case OBJECT_TRIGGER:
1457 : 404 : address.classId = TriggerRelationId;
1458 : 392 : address.objectId = relation ?
1459 [ + + ]: 404 : get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
1460 : 392 : address.objectSubId = 0;
1461 : 392 : break;
1462 : 138 : case OBJECT_TABCONSTRAINT:
1463 : 138 : address.classId = ConstraintRelationId;
1464 : 132 : address.objectId = relation ?
1465 [ + - ]: 138 : get_relation_constraint_oid(reloid, depname, missing_ok) :
1466 : : InvalidOid;
1467 : 132 : address.objectSubId = 0;
1468 : 132 : break;
1469 : 98 : case OBJECT_POLICY:
1470 : 98 : address.classId = PolicyRelationId;
1471 : 92 : address.objectId = relation ?
1472 [ + - ]: 98 : get_relation_policy_oid(reloid, depname, missing_ok) :
1473 : : InvalidOid;
1474 : 92 : address.objectSubId = 0;
1475 : 92 : break;
3308 peter_e@gmx.net 1476 :UBC 0 : default:
1223 peter@eisentraut.org 1477 [ # # ]: 0 : elog(ERROR, "unrecognized object type: %d", (int) objtype);
1478 : : }
1479 : :
1480 : : /* Avoid relcache leak when object not found. */
3308 peter_e@gmx.net 1481 [ + + ]:CBC 738 : if (!OidIsValid(address.objectId))
1482 : : {
1483 [ + + ]: 24 : if (relation != NULL)
2610 andres@anarazel.de 1484 : 6 : table_close(relation, AccessShareLock);
1485 : :
3224 bruce@momjian.us 1486 : 24 : relation = NULL; /* department of accident prevention */
3308 peter_e@gmx.net 1487 : 24 : return address;
1488 : : }
1489 : :
1490 : : /* Done. */
5679 rhaas@postgresql.org 1491 : 714 : *relp = relation;
1492 : 714 : return address;
1493 : : }
1494 : :
1495 : : /*
1496 : : * Find the ObjectAddress for an attribute.
1497 : : */
1498 : : static ObjectAddress
3410 peter_e@gmx.net 1499 : 164 : get_object_address_attribute(ObjectType objtype, List *object,
1500 : : Relation *relp, LOCKMODE lockmode,
1501 : : bool missing_ok)
1502 : : {
1503 : : ObjectAddress address;
1504 : : List *relname;
1505 : : Oid reloid;
1506 : : Relation relation;
1507 : : const char *attname;
1508 : : AttrNumber attnum;
1509 : :
1510 : : /* Extract relation name and open relation. */
1511 [ + + ]: 164 : if (list_length(object) < 2)
5045 rhaas@postgresql.org 1512 [ + - ]: 13 : ereport(ERROR,
1513 : : (errcode(ERRCODE_SYNTAX_ERROR),
1514 : : errmsg("column name must be qualified")));
1995 tgl@sss.pgh.pa.us 1515 : 151 : attname = strVal(llast(object));
1341 drowley@postgresql.o 1516 : 151 : relname = list_copy_head(object, list_length(object) - 1);
1517 : : /* XXX no missing_ok support here */
5626 rhaas@postgresql.org 1518 : 151 : relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
5679 1519 : 127 : reloid = RelationGetRelid(relation);
1520 : :
1521 : : /* Look up attribute and construct return value. */
5375 1522 : 127 : attnum = get_attnum(reloid, attname);
1523 [ + + ]: 127 : if (attnum == InvalidAttrNumber)
1524 : : {
1525 [ + - ]: 9 : if (!missing_ok)
1526 [ + - ]: 9 : ereport(ERROR,
1527 : : (errcode(ERRCODE_UNDEFINED_COLUMN),
1528 : : errmsg("column \"%s\" of relation \"%s\" does not exist",
1529 : : attname, NameListToString(relname))));
1530 : :
5375 rhaas@postgresql.org 1531 :UBC 0 : address.classId = RelationRelationId;
1532 : 0 : address.objectId = InvalidOid;
1533 : 0 : address.objectSubId = InvalidAttrNumber;
4436 1534 : 0 : relation_close(relation, lockmode);
5375 1535 : 0 : return address;
1536 : : }
1537 : :
5679 rhaas@postgresql.org 1538 :CBC 118 : address.classId = RelationRelationId;
1539 : 118 : address.objectId = reloid;
5375 1540 : 118 : address.objectSubId = attnum;
1541 : :
5679 1542 : 118 : *relp = relation;
1543 : 118 : return address;
1544 : : }
1545 : :
1546 : : /*
1547 : : * Find the ObjectAddress for an attribute's default value.
1548 : : */
1549 : : static ObjectAddress
3410 peter_e@gmx.net 1550 : 24 : get_object_address_attrdef(ObjectType objtype, List *object,
1551 : : Relation *relp, LOCKMODE lockmode,
1552 : : bool missing_ok)
1553 : : {
1554 : : ObjectAddress address;
1555 : : List *relname;
1556 : : Oid reloid;
1557 : : Relation relation;
1558 : : const char *attname;
1559 : : AttrNumber attnum;
1560 : : TupleDesc tupdesc;
1561 : : Oid defoid;
1562 : :
1563 : : /* Extract relation name and open relation. */
1564 [ + + ]: 24 : if (list_length(object) < 2)
4100 alvherre@alvh.no-ip. 1565 [ + - ]: 6 : ereport(ERROR,
1566 : : (errcode(ERRCODE_SYNTAX_ERROR),
1567 : : errmsg("column name must be qualified")));
3410 peter_e@gmx.net 1568 : 18 : attname = strVal(llast(object));
1341 drowley@postgresql.o 1569 : 18 : relname = list_copy_head(object, list_length(object) - 1);
1570 : : /* XXX no missing_ok support here */
4100 alvherre@alvh.no-ip. 1571 : 18 : relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
1572 : 6 : reloid = RelationGetRelid(relation);
1573 : :
1574 : 6 : tupdesc = RelationGetDescr(relation);
1575 : :
1576 : : /* Look up attribute number and fetch the pg_attrdef OID */
1577 : 6 : attnum = get_attnum(reloid, attname);
1578 : 6 : defoid = InvalidOid;
1579 [ + - + - ]: 6 : if (attnum != InvalidAttrNumber && tupdesc->constr != NULL)
1455 tgl@sss.pgh.pa.us 1580 : 6 : defoid = GetAttrDefaultOid(reloid, attnum);
4100 alvherre@alvh.no-ip. 1581 [ - + ]: 6 : if (!OidIsValid(defoid))
1582 : : {
4100 alvherre@alvh.no-ip. 1583 [ # # ]:UBC 0 : if (!missing_ok)
1584 [ # # ]: 0 : ereport(ERROR,
1585 : : (errcode(ERRCODE_UNDEFINED_COLUMN),
1586 : : errmsg("default value for column \"%s\" of relation \"%s\" does not exist",
1587 : : attname, NameListToString(relname))));
1588 : :
1589 : 0 : address.classId = AttrDefaultRelationId;
1590 : 0 : address.objectId = InvalidOid;
1591 : 0 : address.objectSubId = InvalidAttrNumber;
1592 : 0 : relation_close(relation, lockmode);
1593 : 0 : return address;
1594 : : }
1595 : :
4100 alvherre@alvh.no-ip. 1596 :CBC 6 : address.classId = AttrDefaultRelationId;
1597 : 6 : address.objectId = defoid;
1598 : 6 : address.objectSubId = 0;
1599 : :
1600 : 6 : *relp = relation;
1601 : 6 : return address;
1602 : : }
1603 : :
1604 : : /*
1605 : : * Find the ObjectAddress for a type or domain
1606 : : */
1607 : : static ObjectAddress
3410 peter_e@gmx.net 1608 : 969 : get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
1609 : : {
1610 : : ObjectAddress address;
1611 : : Type tup;
1612 : :
5375 rhaas@postgresql.org 1613 : 969 : address.classId = TypeRelationId;
1614 : 969 : address.objectId = InvalidOid;
1615 : 969 : address.objectSubId = 0;
1616 : :
4434 alvherre@alvh.no-ip. 1617 : 969 : tup = LookupTypeName(NULL, typename, NULL, missing_ok);
5375 rhaas@postgresql.org 1618 [ + + ]: 969 : if (!HeapTupleIsValid(tup))
1619 : : {
1620 [ + + ]: 53 : if (!missing_ok)
1621 [ + - ]: 39 : ereport(ERROR,
1622 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1623 : : errmsg("type \"%s\" does not exist",
1624 : : TypeNameToString(typename))));
1625 : 14 : return address;
1626 : : }
1627 : 916 : address.objectId = typeTypeId(tup);
1628 : :
1629 [ + + ]: 916 : if (objtype == OBJECT_DOMAIN)
1630 : : {
1631 [ + + ]: 315 : if (((Form_pg_type) GETSTRUCT(tup))->typtype != TYPTYPE_DOMAIN)
1632 [ + - ]: 3 : ereport(ERROR,
1633 : : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1634 : : errmsg("\"%s\" is not a domain",
1635 : : TypeNameToString(typename))));
1636 : : }
1637 : :
1638 : 913 : ReleaseSysCache(tup);
1639 : :
1640 : 913 : return address;
1641 : : }
1642 : :
1643 : : /*
1644 : : * Find the ObjectAddress for an opclass or opfamily.
1645 : : */
1646 : : static ObjectAddress
3410 peter_e@gmx.net 1647 : 252 : get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
1648 : : {
1649 : : Oid amoid;
1650 : : ObjectAddress address;
1651 : :
1652 : : /* XXX no missing_ok support here */
1653 : 252 : amoid = get_index_am_oid(strVal(linitial(object)), false);
1654 : 216 : object = list_copy_tail(object, 1);
1655 : :
5679 rhaas@postgresql.org 1656 [ + + - ]: 216 : switch (objtype)
1657 : : {
1658 : 84 : case OBJECT_OPCLASS:
1659 : 84 : address.classId = OperatorClassRelationId;
3410 peter_e@gmx.net 1660 : 84 : address.objectId = get_opclass_oid(amoid, object, missing_ok);
5679 rhaas@postgresql.org 1661 : 81 : address.objectSubId = 0;
1662 : 81 : break;
1663 : 132 : case OBJECT_OPFAMILY:
1664 : 132 : address.classId = OperatorFamilyRelationId;
3410 peter_e@gmx.net 1665 : 132 : address.objectId = get_opfamily_oid(amoid, object, missing_ok);
5679 rhaas@postgresql.org 1666 : 129 : address.objectSubId = 0;
1667 : 129 : break;
5679 rhaas@postgresql.org 1668 :UBC 0 : default:
1223 peter@eisentraut.org 1669 [ # # ]: 0 : elog(ERROR, "unrecognized object type: %d", (int) objtype);
1670 : : /* placate compiler, which doesn't know elog won't return */
1671 : : address.classId = InvalidOid;
1672 : : address.objectId = InvalidOid;
1673 : : address.objectSubId = 0;
1674 : : }
1675 : :
5679 rhaas@postgresql.org 1676 :CBC 210 : return address;
1677 : : }
1678 : :
1679 : : /*
1680 : : * Find the ObjectAddress for an opclass/opfamily member.
1681 : : *
1682 : : * (The returned address corresponds to a pg_amop/pg_amproc object).
1683 : : */
1684 : : static ObjectAddress
4017 alvherre@alvh.no-ip. 1685 : 25 : get_object_address_opf_member(ObjectType objtype,
1686 : : List *object, bool missing_ok)
1687 : : {
1688 : : ObjectAddress famaddr;
1689 : : ObjectAddress address;
1690 : : ListCell *cell;
1691 : : List *copy;
1692 : : TypeName *typenames[2];
1693 : : Oid typeoids[2];
1694 : : int membernum;
1695 : : int i;
1696 : :
1697 : : /*
1698 : : * The last element of the object list contains the strategy or procedure
1699 : : * number. We need to strip that out before getting the opclass/family
1700 : : * address. The rest can be used directly by get_object_address_opcf().
1701 : : */
3410 peter_e@gmx.net 1702 : 25 : membernum = atoi(strVal(llast(linitial(object))));
1341 drowley@postgresql.o 1703 : 25 : copy = list_copy_head(linitial(object), list_length(linitial(object)) - 1);
1704 : :
1705 : : /* no missing_ok support here */
4017 alvherre@alvh.no-ip. 1706 : 25 : famaddr = get_object_address_opcf(OBJECT_OPFAMILY, copy, false);
1707 : :
1708 : : /* find out left/right type names and OIDs */
2951 tgl@sss.pgh.pa.us 1709 : 25 : typenames[0] = typenames[1] = NULL;
1710 : 25 : typeoids[0] = typeoids[1] = InvalidOid;
4017 alvherre@alvh.no-ip. 1711 : 25 : i = 0;
3410 peter_e@gmx.net 1712 [ + - + - : 50 : foreach(cell, lsecond(object))
+ - ]
1713 : : {
1714 : : ObjectAddress typaddr;
1715 : :
3261 tgl@sss.pgh.pa.us 1716 : 50 : typenames[i] = lfirst_node(TypeName, cell);
3286 alvherre@alvh.no-ip. 1717 : 50 : typaddr = get_object_address_type(OBJECT_TYPE, typenames[i], missing_ok);
4017 1718 : 50 : typeoids[i] = typaddr.objectId;
1719 [ + + ]: 50 : if (++i >= 2)
1720 : 25 : break;
1721 : : }
1722 : :
1723 [ + + - ]: 25 : switch (objtype)
1724 : : {
1725 : 12 : case OBJECT_AMOP:
1726 : : {
1727 : : HeapTuple tp;
1728 : :
1729 : 12 : ObjectAddressSet(address, AccessMethodOperatorRelationId,
1730 : : InvalidOid);
1731 : :
1732 : 12 : tp = SearchSysCache4(AMOPSTRATEGY,
1733 : : ObjectIdGetDatum(famaddr.objectId),
1734 : : ObjectIdGetDatum(typeoids[0]),
1735 : : ObjectIdGetDatum(typeoids[1]),
1736 : : Int16GetDatum(membernum));
1737 [ + + ]: 12 : if (!HeapTupleIsValid(tp))
1738 : : {
1739 [ + - ]: 6 : if (!missing_ok)
1740 [ + - ]: 6 : ereport(ERROR,
1741 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1742 : : errmsg("operator %d (%s, %s) of %s does not exist",
1743 : : membernum,
1744 : : TypeNameToString(typenames[0]),
1745 : : TypeNameToString(typenames[1]),
1746 : : getObjectDescription(&famaddr, false))));
1747 : : }
1748 : : else
1749 : : {
2672 andres@anarazel.de 1750 : 6 : address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid;
4017 alvherre@alvh.no-ip. 1751 : 6 : ReleaseSysCache(tp);
1752 : : }
1753 : : }
1754 : 6 : break;
1755 : :
1756 : 13 : case OBJECT_AMPROC:
1757 : : {
1758 : : HeapTuple tp;
1759 : :
1760 : 13 : ObjectAddressSet(address, AccessMethodProcedureRelationId,
1761 : : InvalidOid);
1762 : :
1763 : 13 : tp = SearchSysCache4(AMPROCNUM,
1764 : : ObjectIdGetDatum(famaddr.objectId),
1765 : : ObjectIdGetDatum(typeoids[0]),
1766 : : ObjectIdGetDatum(typeoids[1]),
1767 : : Int16GetDatum(membernum));
1768 [ + + ]: 13 : if (!HeapTupleIsValid(tp))
1769 : : {
1770 [ + - ]: 6 : if (!missing_ok)
1771 [ + - ]: 6 : ereport(ERROR,
1772 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1773 : : errmsg("function %d (%s, %s) of %s does not exist",
1774 : : membernum,
1775 : : TypeNameToString(typenames[0]),
1776 : : TypeNameToString(typenames[1]),
1777 : : getObjectDescription(&famaddr, false))));
1778 : : }
1779 : : else
1780 : : {
2672 andres@anarazel.de 1781 : 7 : address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid;
4017 alvherre@alvh.no-ip. 1782 : 7 : ReleaseSysCache(tp);
1783 : : }
1784 : : }
1785 : 7 : break;
4017 alvherre@alvh.no-ip. 1786 :UBC 0 : default:
1223 peter@eisentraut.org 1787 [ # # ]: 0 : elog(ERROR, "unrecognized object type: %d", (int) objtype);
1788 : : }
1789 : :
4017 alvherre@alvh.no-ip. 1790 :CBC 13 : return address;
1791 : : }
1792 : :
1793 : : /*
1794 : : * Find the ObjectAddress for a user mapping.
1795 : : */
1796 : : static ObjectAddress
3410 peter_e@gmx.net 1797 : 9 : get_object_address_usermapping(List *object, bool missing_ok)
1798 : : {
1799 : : ObjectAddress address;
1800 : : Oid userid;
1801 : : char *username;
1802 : : char *servername;
1803 : : ForeignServer *server;
1804 : : HeapTuple tp;
1805 : :
4022 alvherre@alvh.no-ip. 1806 : 9 : ObjectAddressSet(address, UserMappingRelationId, InvalidOid);
1807 : :
1808 : : /* fetch string names from input lists, for error messages */
3410 peter_e@gmx.net 1809 : 9 : username = strVal(linitial(object));
1810 : 9 : servername = strVal(lsecond(object));
1811 : :
1812 : : /* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
4022 alvherre@alvh.no-ip. 1813 [ - + ]: 9 : if (strcmp(username, "public") == 0)
4022 alvherre@alvh.no-ip. 1814 :UBC 0 : userid = InvalidOid;
1815 : : else
1816 : : {
4022 alvherre@alvh.no-ip. 1817 :CBC 9 : tp = SearchSysCache1(AUTHNAME,
1818 : : CStringGetDatum(username));
1819 [ + + ]: 9 : if (!HeapTupleIsValid(tp))
1820 : : {
1821 [ + - ]: 3 : if (!missing_ok)
1822 [ + - ]: 3 : ereport(ERROR,
1823 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1824 : : errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
1825 : : username, servername)));
4022 alvherre@alvh.no-ip. 1826 :UBC 0 : return address;
1827 : : }
2672 andres@anarazel.de 1828 :CBC 6 : userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
4022 alvherre@alvh.no-ip. 1829 : 6 : ReleaseSysCache(tp);
1830 : : }
1831 : :
1832 : : /* Now look up the pg_user_mapping tuple */
1833 : 6 : server = GetForeignServerByName(servername, true);
1834 [ - + ]: 6 : if (!server)
1835 : : {
4022 alvherre@alvh.no-ip. 1836 [ # # ]:UBC 0 : if (!missing_ok)
1837 [ # # ]: 0 : ereport(ERROR,
1838 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1839 : : errmsg("server \"%s\" does not exist", servername)));
1840 : 0 : return address;
1841 : : }
4022 alvherre@alvh.no-ip. 1842 :CBC 6 : tp = SearchSysCache2(USERMAPPINGUSERSERVER,
1843 : : ObjectIdGetDatum(userid),
1844 : : ObjectIdGetDatum(server->serverid));
1845 [ - + ]: 6 : if (!HeapTupleIsValid(tp))
1846 : : {
4022 alvherre@alvh.no-ip. 1847 [ # # ]:UBC 0 : if (!missing_ok)
1848 [ # # ]: 0 : ereport(ERROR,
1849 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1850 : : errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
1851 : : username, servername)));
1852 : 0 : return address;
1853 : : }
1854 : :
2672 andres@anarazel.de 1855 :CBC 6 : address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
1856 : :
4022 alvherre@alvh.no-ip. 1857 : 6 : ReleaseSysCache(tp);
1858 : :
1859 : 6 : return address;
1860 : : }
1861 : :
1862 : : /*
1863 : : * Find the ObjectAddress for a publication relation. The first element of
1864 : : * the object parameter is the relation name, the second is the
1865 : : * publication name.
1866 : : */
1867 : : static ObjectAddress
3410 peter_e@gmx.net 1868 : 15 : get_object_address_publication_rel(List *object,
1869 : : Relation *relp, bool missing_ok)
1870 : : {
1871 : : ObjectAddress address;
1872 : : Relation relation;
1873 : : List *relname;
1874 : : char *pubname;
1875 : : Publication *pub;
1876 : :
3342 1877 : 15 : ObjectAddressSet(address, PublicationRelRelationId, InvalidOid);
1878 : :
3410 1879 : 15 : relname = linitial(object);
1880 : 15 : relation = relation_openrv_extended(makeRangeVarFromNameList(relname),
1881 : : AccessShareLock, missing_ok);
3342 1882 [ - + ]: 6 : if (!relation)
3342 peter_e@gmx.net 1883 :UBC 0 : return address;
1884 : :
1885 : : /* fetch publication name from input list */
3410 peter_e@gmx.net 1886 :CBC 6 : pubname = strVal(lsecond(object));
1887 : :
1888 : : /* Now look up the pg_publication tuple */
3342 1889 : 6 : pub = GetPublicationByName(pubname, missing_ok);
1890 [ - + ]: 6 : if (!pub)
1891 : : {
3323 peter_e@gmx.net 1892 :UBC 0 : relation_close(relation, AccessShareLock);
3342 1893 : 0 : return address;
1894 : : }
1895 : :
1896 : : /* Find the publication relation mapping in syscache. */
3342 peter_e@gmx.net 1897 :CBC 6 : address.objectId =
2672 andres@anarazel.de 1898 : 6 : GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid,
1899 : : ObjectIdGetDatum(RelationGetRelid(relation)),
1900 : : ObjectIdGetDatum(pub->oid));
3342 peter_e@gmx.net 1901 [ - + ]: 6 : if (!OidIsValid(address.objectId))
1902 : : {
3342 peter_e@gmx.net 1903 [ # # ]:UBC 0 : if (!missing_ok)
1904 [ # # ]: 0 : ereport(ERROR,
1905 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1906 : : errmsg("publication relation \"%s\" in publication \"%s\" does not exist",
1907 : : RelationGetRelationName(relation), pubname)));
3323 1908 : 0 : relation_close(relation, AccessShareLock);
3342 1909 : 0 : return address;
1910 : : }
1911 : :
3338 peter_e@gmx.net 1912 :CBC 6 : *relp = relation;
3342 1913 : 6 : return address;
1914 : : }
1915 : :
1916 : : /*
1917 : : * Find the ObjectAddress for a publication schema. The first element of the
1918 : : * object parameter is the schema name, the second is the publication name.
1919 : : */
1920 : : static ObjectAddress
1600 akapila@postgresql.o 1921 : 9 : get_object_address_publication_schema(List *object, bool missing_ok)
1922 : : {
1923 : : ObjectAddress address;
1924 : : Publication *pub;
1925 : : char *pubname;
1926 : : char *schemaname;
1927 : : Oid schemaid;
1928 : :
1929 : 9 : ObjectAddressSet(address, PublicationNamespaceRelationId, InvalidOid);
1930 : :
1931 : : /* Fetch schema name and publication name from input list */
1932 : 9 : schemaname = strVal(linitial(object));
1933 : 9 : pubname = strVal(lsecond(object));
1934 : :
1935 : 9 : schemaid = get_namespace_oid(schemaname, missing_ok);
1936 [ - + ]: 6 : if (!OidIsValid(schemaid))
1600 akapila@postgresql.o 1937 :UBC 0 : return address;
1938 : :
1939 : : /* Now look up the pg_publication tuple */
1600 akapila@postgresql.o 1940 :CBC 6 : pub = GetPublicationByName(pubname, missing_ok);
1941 [ - + ]: 6 : if (!pub)
1600 akapila@postgresql.o 1942 :UBC 0 : return address;
1943 : :
1944 : : /* Find the publication schema mapping in syscache */
1600 akapila@postgresql.o 1945 :CBC 6 : address.objectId =
1438 tomas.vondra@postgre 1946 : 6 : GetSysCacheOid2(PUBLICATIONNAMESPACEMAP,
1947 : : Anum_pg_publication_namespace_oid,
1948 : : ObjectIdGetDatum(schemaid),
1949 : : ObjectIdGetDatum(pub->oid));
1600 akapila@postgresql.o 1950 [ - + - - ]: 6 : if (!OidIsValid(address.objectId) && !missing_ok)
1600 akapila@postgresql.o 1951 [ # # ]:UBC 0 : ereport(ERROR,
1952 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
1953 : : errmsg("publication schema \"%s\" in publication \"%s\" does not exist",
1954 : : schemaname, pubname)));
1955 : :
1600 akapila@postgresql.o 1956 :CBC 6 : return address;
1957 : : }
1958 : :
1959 : : /*
1960 : : * Find the ObjectAddress for a default ACL.
1961 : : */
1962 : : static ObjectAddress
3410 peter_e@gmx.net 1963 : 21 : get_object_address_defacl(List *object, bool missing_ok)
1964 : : {
1965 : : HeapTuple tp;
1966 : : Oid userid;
1967 : : Oid schemaid;
1968 : : char *username;
1969 : : char *schema;
1970 : : char objtype;
1971 : : char *objtype_str;
1972 : : ObjectAddress address;
1973 : :
4022 alvherre@alvh.no-ip. 1974 : 21 : ObjectAddressSet(address, DefaultAclRelationId, InvalidOid);
1975 : :
1976 : : /*
1977 : : * First figure out the textual attributes so that they can be used for
1978 : : * error reporting.
1979 : : */
3410 peter_e@gmx.net 1980 : 21 : username = strVal(lsecond(object));
1981 [ + + ]: 21 : if (list_length(object) >= 3)
1982 : 12 : schema = (char *) strVal(lthird(object));
1983 : : else
4022 alvherre@alvh.no-ip. 1984 : 9 : schema = NULL;
1985 : :
1986 : : /*
1987 : : * Decode defaclobjtype. Only first char is considered; the rest of the
1988 : : * string, if any, is blissfully ignored.
1989 : : */
3410 peter_e@gmx.net 1990 : 21 : objtype = ((char *) strVal(linitial(object)))[0];
4022 alvherre@alvh.no-ip. 1991 [ + - - - : 21 : switch (objtype)
- - + ]
1992 : : {
1993 : 12 : case DEFACLOBJ_RELATION:
1994 : 12 : objtype_str = "tables";
1995 : 12 : break;
4022 alvherre@alvh.no-ip. 1996 :UBC 0 : case DEFACLOBJ_SEQUENCE:
1997 : 0 : objtype_str = "sequences";
1998 : 0 : break;
1999 : 0 : case DEFACLOBJ_FUNCTION:
2000 : 0 : objtype_str = "functions";
2001 : 0 : break;
2002 : 0 : case DEFACLOBJ_TYPE:
2003 : 0 : objtype_str = "types";
2004 : 0 : break;
3274 teodor@sigaev.ru 2005 : 0 : case DEFACLOBJ_NAMESPACE:
2006 : 0 : objtype_str = "schemas";
2007 : 0 : break;
345 fujii@postgresql.org 2008 : 0 : case DEFACLOBJ_LARGEOBJECT:
2009 : 0 : objtype_str = "large objects";
2010 : 0 : break;
4022 alvherre@alvh.no-ip. 2011 :CBC 9 : default:
2012 [ + - ]: 9 : ereport(ERROR,
2013 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2014 : : errmsg("unrecognized default ACL object type \"%c\"", objtype),
2015 : : errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".",
2016 : : DEFACLOBJ_RELATION,
2017 : : DEFACLOBJ_SEQUENCE,
2018 : : DEFACLOBJ_FUNCTION,
2019 : : DEFACLOBJ_TYPE,
2020 : : DEFACLOBJ_NAMESPACE,
2021 : : DEFACLOBJ_LARGEOBJECT)));
2022 : : }
2023 : :
2024 : : /*
2025 : : * Look up user ID. Behave as "default ACL not found" if the user doesn't
2026 : : * exist.
2027 : : */
2028 : 12 : tp = SearchSysCache1(AUTHNAME,
2029 : : CStringGetDatum(username));
2030 [ - + ]: 12 : if (!HeapTupleIsValid(tp))
4022 alvherre@alvh.no-ip. 2031 :UBC 0 : goto not_found;
2672 andres@anarazel.de 2032 :CBC 12 : userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
4022 alvherre@alvh.no-ip. 2033 : 12 : ReleaseSysCache(tp);
2034 : :
2035 : : /*
2036 : : * If a schema name was given, look up its OID. If it doesn't exist,
2037 : : * behave as "default ACL not found".
2038 : : */
2039 [ + + ]: 12 : if (schema)
2040 : : {
2041 : 6 : schemaid = get_namespace_oid(schema, true);
2042 [ - + ]: 6 : if (schemaid == InvalidOid)
4022 alvherre@alvh.no-ip. 2043 :UBC 0 : goto not_found;
2044 : : }
2045 : : else
4022 alvherre@alvh.no-ip. 2046 :CBC 6 : schemaid = InvalidOid;
2047 : :
2048 : : /* Finally, look up the pg_default_acl object */
2049 : 12 : tp = SearchSysCache3(DEFACLROLENSPOBJ,
2050 : : ObjectIdGetDatum(userid),
2051 : : ObjectIdGetDatum(schemaid),
2052 : : CharGetDatum(objtype));
2053 [ - + ]: 12 : if (!HeapTupleIsValid(tp))
4022 alvherre@alvh.no-ip. 2054 :UBC 0 : goto not_found;
2055 : :
2672 andres@anarazel.de 2056 :CBC 12 : address.objectId = ((Form_pg_default_acl) GETSTRUCT(tp))->oid;
4022 alvherre@alvh.no-ip. 2057 : 12 : ReleaseSysCache(tp);
2058 : :
2059 : 12 : return address;
2060 : :
4022 alvherre@alvh.no-ip. 2061 :UBC 0 : not_found:
2062 [ # # ]: 0 : if (!missing_ok)
2063 : : {
2064 [ # # ]: 0 : if (schema)
2065 [ # # ]: 0 : ereport(ERROR,
2066 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
2067 : : errmsg("default ACL for user \"%s\" in schema \"%s\" on %s does not exist",
2068 : : username, schema, objtype_str)));
2069 : : else
2070 [ # # ]: 0 : ereport(ERROR,
2071 : : (errcode(ERRCODE_UNDEFINED_OBJECT),
2072 : : errmsg("default ACL for user \"%s\" on %s does not exist",
2073 : : username, objtype_str)));
2074 : : }
2075 : 0 : return address;
2076 : : }
2077 : :
2078 : : /*
2079 : : * Convert an array of TEXT into a List of string Values, as emitted by the
2080 : : * parser, which is what get_object_address uses as input.
2081 : : */
2082 : : static List *
4100 alvherre@alvh.no-ip. 2083 :CBC 1694 : textarray_to_strvaluelist(ArrayType *arr)
2084 : : {
2085 : : Datum *elems;
2086 : : bool *nulls;
2087 : : int nelems;
3949 bruce@momjian.us 2088 : 1694 : List *list = NIL;
2089 : : int i;
2090 : :
1353 peter@eisentraut.org 2091 : 1694 : deconstruct_array_builtin(arr, TEXTOID, &elems, &nulls, &nelems);
2092 : :
4100 alvherre@alvh.no-ip. 2093 [ + + ]: 3693 : for (i = 0; i < nelems; i++)
2094 : : {
2095 [ + + ]: 2002 : if (nulls[i])
2096 [ + - ]: 3 : ereport(ERROR,
2097 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2098 : : errmsg("name or argument lists may not contain nulls")));
2099 : 1999 : list = lappend(list, makeString(TextDatumGetCString(elems[i])));
2100 : : }
2101 : :
2102 : 1691 : return list;
2103 : : }
2104 : :
2105 : : /*
2106 : : * SQL-callable version of get_object_address
2107 : : */
2108 : : Datum
2109 : 1042 : pg_get_object_address(PG_FUNCTION_ARGS)
2110 : : {
3909 tgl@sss.pgh.pa.us 2111 : 1042 : char *ttype = TextDatumGetCString(PG_GETARG_DATUM(0));
3949 bruce@momjian.us 2112 : 1042 : ArrayType *namearr = PG_GETARG_ARRAYTYPE_P(1);
2113 : 1042 : ArrayType *argsarr = PG_GETARG_ARRAYTYPE_P(2);
2114 : : int itype;
2115 : : ObjectType type;
3410 peter_e@gmx.net 2116 : 1042 : List *name = NIL;
2117 : 1042 : TypeName *typename = NULL;
2118 : 1042 : List *args = NIL;
2119 : 1042 : Node *objnode = NULL;
2120 : : ObjectAddress addr;
2121 : : TupleDesc tupdesc;
2122 : : Datum values[3];
2123 : : bool nulls[3];
2124 : : HeapTuple htup;
2125 : : Relation relation;
2126 : :
2127 : : /* Decode object type, raise error if unknown */
4100 alvherre@alvh.no-ip. 2128 : 1042 : itype = read_objtype_from_string(ttype);
2129 [ + + ]: 1039 : if (itype < 0)
2130 [ + - ]: 18 : ereport(ERROR,
2131 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2132 : : errmsg("unsupported object type \"%s\"", ttype)));
2133 : 1021 : type = (ObjectType) itype;
2134 : :
2135 : : /*
2136 : : * Convert the text array to the representation appropriate for the given
2137 : : * object type. Most use a simple string Values list, but there are some
2138 : : * exceptions.
2139 : : */
4093 2140 [ + + + - : 1021 : if (type == OBJECT_TYPE || type == OBJECT_DOMAIN || type == OBJECT_CAST ||
+ + + + ]
3920 2141 [ + + ]: 931 : type == OBJECT_TRANSFORM || type == OBJECT_DOMCONSTRAINT)
4100 2142 : 66 : {
2143 : : Datum *elems;
2144 : : bool *nulls;
2145 : : int nelems;
2146 : :
1353 peter@eisentraut.org 2147 : 114 : deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, &nelems);
4100 alvherre@alvh.no-ip. 2148 [ + + ]: 114 : if (nelems != 1)
2149 [ + - ]: 48 : ereport(ERROR,
2150 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2151 : : errmsg("name list length must be exactly %d", 1)));
2152 [ - + ]: 66 : if (nulls[0])
4100 alvherre@alvh.no-ip. 2153 [ # # ]:UBC 0 : ereport(ERROR,
2154 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2155 : : errmsg("name or argument lists may not contain nulls")));
1174 tgl@sss.pgh.pa.us 2156 :CBC 66 : typename = typeStringToTypeName(TextDatumGetCString(elems[0]), NULL);
2157 : : }
4100 alvherre@alvh.no-ip. 2158 [ + + ]: 907 : else if (type == OBJECT_LARGEOBJECT)
2159 : : {
2160 : : Datum *elems;
2161 : : bool *nulls;
2162 : : int nelems;
2163 : :
1353 peter@eisentraut.org 2164 : 9 : deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, &nelems);
4100 alvherre@alvh.no-ip. 2165 [ + + ]: 9 : if (nelems != 1)
2166 [ + - ]: 3 : ereport(ERROR,
2167 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2168 : : errmsg("name list length must be exactly %d", 1)));
2169 [ - + ]: 6 : if (nulls[0])
4100 alvherre@alvh.no-ip. 2170 [ # # ]:UBC 0 : ereport(ERROR,
2171 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2172 : : errmsg("large object OID may not be null")));
3410 peter_e@gmx.net 2173 :CBC 6 : objnode = (Node *) makeFloat(TextDatumGetCString(elems[0]));
2174 : : }
2175 : : else
2176 : : {
4100 alvherre@alvh.no-ip. 2177 : 898 : name = textarray_to_strvaluelist(namearr);
1306 tgl@sss.pgh.pa.us 2178 [ + + ]: 895 : if (name == NIL)
4100 alvherre@alvh.no-ip. 2179 [ + - ]: 3 : ereport(ERROR,
2180 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2181 : : errmsg("name list length must be at least %d", 1)));
2182 : : }
2183 : :
2184 : : /*
2185 : : * If args are given, decode them according to the object type.
2186 : : */
2187 [ + + + + ]: 964 : if (type == OBJECT_AGGREGATE ||
2188 [ + + ]: 916 : type == OBJECT_FUNCTION ||
3027 peter_e@gmx.net 2189 [ + - ]: 892 : type == OBJECT_PROCEDURE ||
2190 [ + + ]: 892 : type == OBJECT_ROUTINE ||
4100 alvherre@alvh.no-ip. 2191 [ + + ]: 868 : type == OBJECT_OPERATOR ||
4017 2192 [ + + ]: 856 : type == OBJECT_CAST ||
2193 [ + + ]: 826 : type == OBJECT_AMOP ||
2194 : : type == OBJECT_AMPROC)
4100 2195 : 168 : {
2196 : : /* in these cases, the args list must be of TypeName */
2197 : : Datum *elems;
2198 : : bool *nulls;
2199 : : int nelems;
2200 : : int i;
2201 : :
1353 peter@eisentraut.org 2202 : 168 : deconstruct_array_builtin(argsarr, TEXTOID, &elems, &nulls, &nelems);
2203 : :
4100 alvherre@alvh.no-ip. 2204 : 168 : args = NIL;
2205 [ + + ]: 321 : for (i = 0; i < nelems; i++)
2206 : : {
2207 [ - + ]: 153 : if (nulls[i])
4100 alvherre@alvh.no-ip. 2208 [ # # ]:UBC 0 : ereport(ERROR,
2209 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2210 : : errmsg("name or argument lists may not contain nulls")));
4100 alvherre@alvh.no-ip. 2211 :CBC 153 : args = lappend(args,
1174 tgl@sss.pgh.pa.us 2212 : 153 : typeStringToTypeName(TextDatumGetCString(elems[i]),
2213 : : NULL));
2214 : : }
2215 : : }
2216 : : else
2217 : : {
2218 : : /* For all other object types, use string Values */
4100 alvherre@alvh.no-ip. 2219 : 796 : args = textarray_to_strvaluelist(argsarr);
2220 : : }
2221 : :
2222 : : /*
2223 : : * get_object_address is pretty sensitive to the length of its input
2224 : : * lists; check that they're what it wants.
2225 : : */
2226 [ + + + + : 964 : switch (type)
+ + ]
2227 : : {
1271 peter@eisentraut.org 2228 : 48 : case OBJECT_PUBLICATION_NAMESPACE:
2229 : : case OBJECT_USER_MAPPING:
2230 [ + + ]: 48 : if (list_length(name) != 1)
2231 [ + - ]: 24 : ereport(ERROR,
2232 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2233 : : errmsg("name list length must be exactly %d", 1)));
2234 : : /* fall through to check args length */
2235 : : pg_fallthrough;
2236 : : case OBJECT_DOMCONSTRAINT:
2237 : : case OBJECT_CAST:
2238 : : case OBJECT_PUBLICATION_REL:
2239 : : case OBJECT_DEFACL:
2240 : : case OBJECT_TRANSFORM:
4100 alvherre@alvh.no-ip. 2241 [ + + ]: 114 : if (list_length(args) != 1)
2242 [ + - ]: 33 : ereport(ERROR,
2243 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2244 : : errmsg("argument list length must be exactly %d", 1)));
2245 : 81 : break;
4017 2246 : 48 : case OBJECT_OPFAMILY:
2247 : : case OBJECT_OPCLASS:
2248 [ + + ]: 48 : if (list_length(name) < 2)
2249 [ + - ]: 12 : ereport(ERROR,
2250 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2251 : : errmsg("name list length must be at least %d", 2)));
2252 : 36 : break;
2253 : 60 : case OBJECT_AMOP:
2254 : : case OBJECT_AMPROC:
2255 [ + + ]: 60 : if (list_length(name) < 3)
2256 [ + - ]: 24 : ereport(ERROR,
2257 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2258 : : errmsg("name list length must be at least %d", 3)));
2259 : : /* fall through to check args length */
2260 : : pg_fallthrough;
2261 : : case OBJECT_OPERATOR:
4100 2262 [ + + ]: 60 : if (list_length(args) != 2)
2263 [ + - ]: 30 : ereport(ERROR,
2264 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2265 : : errmsg("argument list length must be exactly %d", 2)));
2266 : 30 : break;
2267 : 694 : default:
2268 : 694 : break;
2269 : : }
2270 : :
2271 : : /*
2272 : : * Now build the Node type that get_object_address() expects for the given
2273 : : * type.
2274 : : */
3410 peter_e@gmx.net 2275 [ + + + + : 841 : switch (type)
+ + + + +
+ - ]
2276 : : {
2277 : 492 : case OBJECT_TABLE:
2278 : : case OBJECT_SEQUENCE:
2279 : : case OBJECT_VIEW:
2280 : : case OBJECT_MATVIEW:
2281 : : case OBJECT_INDEX:
2282 : : case OBJECT_FOREIGN_TABLE:
2283 : : case OBJECT_COLUMN:
2284 : : case OBJECT_ATTRIBUTE:
2285 : : case OBJECT_COLLATION:
2286 : : case OBJECT_CONVERSION:
2287 : : case OBJECT_STATISTIC_EXT:
2288 : : case OBJECT_TSPARSER:
2289 : : case OBJECT_TSDICTIONARY:
2290 : : case OBJECT_TSTEMPLATE:
2291 : : case OBJECT_TSCONFIGURATION:
2292 : : case OBJECT_DEFAULT:
2293 : : case OBJECT_POLICY:
2294 : : case OBJECT_RULE:
2295 : : case OBJECT_TRIGGER:
2296 : : case OBJECT_TABCONSTRAINT:
2297 : : case OBJECT_OPCLASS:
2298 : : case OBJECT_OPFAMILY:
2299 : 492 : objnode = (Node *) name;
2300 : 492 : break;
2301 : 130 : case OBJECT_ACCESS_METHOD:
2302 : : case OBJECT_DATABASE:
2303 : : case OBJECT_EVENT_TRIGGER:
2304 : : case OBJECT_EXTENSION:
2305 : : case OBJECT_FDW:
2306 : : case OBJECT_FOREIGN_SERVER:
2307 : : case OBJECT_LANGUAGE:
2308 : : case OBJECT_PARAMETER_ACL:
2309 : : case OBJECT_PUBLICATION:
2310 : : case OBJECT_ROLE:
2311 : : case OBJECT_SCHEMA:
2312 : : case OBJECT_SUBSCRIPTION:
2313 : : case OBJECT_TABLESPACE:
2314 [ + + ]: 130 : if (list_length(name) != 1)
2315 [ + - ]: 36 : ereport(ERROR,
2316 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2317 : : errmsg("name list length must be exactly %d", 1)));
2318 : 94 : objnode = linitial(name);
2319 : 94 : break;
2320 : 30 : case OBJECT_TYPE:
2321 : : case OBJECT_DOMAIN:
2322 : 30 : objnode = (Node *) typename;
2323 : 30 : break;
2324 : 27 : case OBJECT_CAST:
2325 : : case OBJECT_DOMCONSTRAINT:
2326 : : case OBJECT_TRANSFORM:
2327 : 27 : objnode = (Node *) list_make2(typename, linitial(args));
2328 : 27 : break;
2329 : 15 : case OBJECT_PUBLICATION_REL:
2330 : 15 : objnode = (Node *) list_make2(name, linitial(args));
2331 : 15 : break;
1600 akapila@postgresql.o 2332 : 18 : case OBJECT_PUBLICATION_NAMESPACE:
2333 : : case OBJECT_USER_MAPPING:
3410 peter_e@gmx.net 2334 : 18 : objnode = (Node *) list_make2(linitial(name), linitial(args));
2335 : 18 : break;
2336 : 21 : case OBJECT_DEFACL:
2337 : 21 : objnode = (Node *) lcons(linitial(args), name);
2338 : 21 : break;
2339 : 24 : case OBJECT_AMOP:
2340 : : case OBJECT_AMPROC:
2341 : 24 : objnode = (Node *) list_make2(name, args);
2342 : 24 : break;
2343 : 78 : case OBJECT_FUNCTION:
2344 : : case OBJECT_PROCEDURE:
2345 : : case OBJECT_ROUTINE:
2346 : : case OBJECT_AGGREGATE:
2347 : : case OBJECT_OPERATOR:
2348 : : {
3224 bruce@momjian.us 2349 : 78 : ObjectWithArgs *owa = makeNode(ObjectWithArgs);
2350 : :
2351 : 78 : owa->objname = name;
2352 : 78 : owa->objargs = args;
2353 : 78 : objnode = (Node *) owa;
2354 : 78 : break;
2355 : : }
3410 peter_e@gmx.net 2356 : 6 : case OBJECT_LARGEOBJECT:
2357 : : /* already handled above */
2358 : 6 : break;
2359 : : /* no default, to let compiler warn about missing case */
2360 : : }
2361 : :
2362 [ - + ]: 805 : if (objnode == NULL)
3410 peter_e@gmx.net 2363 [ # # ]:UBC 0 : elog(ERROR, "unrecognized object type: %d", type);
2364 : :
3410 peter_e@gmx.net 2365 :CBC 805 : addr = get_object_address(type, objnode,
2366 : : &relation, AccessShareLock, false);
2367 : :
2368 : : /* We don't need the relcache entry, thank you very much */
4100 alvherre@alvh.no-ip. 2369 [ + + ]: 310 : if (relation)
2370 : 96 : relation_close(relation, AccessShareLock);
2371 : :
1180 michael@paquier.xyz 2372 [ - + ]: 310 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1180 michael@paquier.xyz 2373 [ # # ]:UBC 0 : elog(ERROR, "return type must be a row type");
2374 : :
4100 alvherre@alvh.no-ip. 2375 :CBC 310 : values[0] = ObjectIdGetDatum(addr.classId);
2376 : 310 : values[1] = ObjectIdGetDatum(addr.objectId);
2377 : 310 : values[2] = Int32GetDatum(addr.objectSubId);
2378 : 310 : nulls[0] = false;
2379 : 310 : nulls[1] = false;
2380 : 310 : nulls[2] = false;
2381 : :
2382 : 310 : htup = heap_form_tuple(tupdesc, values, nulls);
2383 : :
2384 : 310 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
2385 : : }
2386 : :
2387 : : /*
2388 : : * Check ownership of an object previously identified by get_object_address.
2389 : : */
2390 : : void
5490 tgl@sss.pgh.pa.us 2391 : 5540 : check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
2392 : : Node *object, Relation relation)
2393 : : {
2394 [ + + + + : 5540 : switch (objtype)
+ + + + +
+ + - - ]
2395 : : {
2396 : 935 : case OBJECT_INDEX:
2397 : : case OBJECT_SEQUENCE:
2398 : : case OBJECT_TABLE:
2399 : : case OBJECT_VIEW:
2400 : : case OBJECT_MATVIEW:
2401 : : case OBJECT_FOREIGN_TABLE:
2402 : : case OBJECT_COLUMN:
2403 : : case OBJECT_RULE:
2404 : : case OBJECT_TRIGGER:
2405 : : case OBJECT_POLICY:
2406 : : case OBJECT_TABCONSTRAINT:
1218 peter@eisentraut.org 2407 [ + + ]: 935 : if (!object_ownercheck(RelationRelationId, RelationGetRelid(relation), roleid))
3025 peter_e@gmx.net 2408 : 11 : aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
5490 tgl@sss.pgh.pa.us 2409 : 11 : RelationGetRelationName(relation));
2410 : 924 : break;
2411 : 46 : case OBJECT_TYPE:
2412 : : case OBJECT_DOMAIN:
2413 : : case OBJECT_ATTRIBUTE:
1218 peter@eisentraut.org 2414 [ - + ]: 46 : if (!object_ownercheck(address.classId, address.objectId, roleid))
5021 peter_e@gmx.net 2415 :UBC 0 : aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId);
5490 tgl@sss.pgh.pa.us 2416 :CBC 46 : break;
2468 michael@paquier.xyz 2417 : 21 : case OBJECT_DOMCONSTRAINT:
2418 : : {
2419 : : HeapTuple tuple;
2420 : : Oid contypid;
2421 : :
2422 : 21 : tuple = SearchSysCache1(CONSTROID,
2423 : : ObjectIdGetDatum(address.objectId));
2424 [ - + ]: 21 : if (!HeapTupleIsValid(tuple))
2468 michael@paquier.xyz 2425 [ # # ]:UBC 0 : elog(ERROR, "constraint with OID %u does not exist",
2426 : : address.objectId);
2427 : :
2468 michael@paquier.xyz 2428 :CBC 21 : contypid = ((Form_pg_constraint) GETSTRUCT(tuple))->contypid;
2429 : :
2430 : 21 : ReleaseSysCache(tuple);
2431 : :
2432 : : /*
2433 : : * Fallback to type ownership check in this case as this is
2434 : : * what domain constraints rely on.
2435 : : */
1218 peter@eisentraut.org 2436 [ + + ]: 21 : if (!object_ownercheck(TypeRelationId, contypid, roleid))
2468 michael@paquier.xyz 2437 : 3 : aclcheck_error_type(ACLCHECK_NOT_OWNER, contypid);
2438 : : }
2439 : 18 : break;
5490 tgl@sss.pgh.pa.us 2440 : 231 : case OBJECT_AGGREGATE:
2441 : : case OBJECT_FUNCTION:
2442 : : case OBJECT_PROCEDURE:
2443 : : case OBJECT_ROUTINE:
2444 : : case OBJECT_OPERATOR:
1218 peter@eisentraut.org 2445 [ + + ]: 231 : if (!object_ownercheck(address.classId, address.objectId, roleid))
3025 peter_e@gmx.net 2446 : 9 : aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
3410 2447 : 9 : NameListToString((castNode(ObjectWithArgs, object))->objname));
5490 tgl@sss.pgh.pa.us 2448 : 222 : break;
1218 peter@eisentraut.org 2449 : 1078 : case OBJECT_DATABASE:
2450 : : case OBJECT_EVENT_TRIGGER:
2451 : : case OBJECT_EXTENSION:
2452 : : case OBJECT_FDW:
2453 : : case OBJECT_FOREIGN_SERVER:
2454 : : case OBJECT_LANGUAGE:
2455 : : case OBJECT_PUBLICATION:
2456 : : case OBJECT_SCHEMA:
2457 : : case OBJECT_SUBSCRIPTION:
2458 : : case OBJECT_TABLESPACE:
2459 [ + + ]: 1078 : if (!object_ownercheck(address.classId, address.objectId, roleid))
3025 peter_e@gmx.net 2460 : 21 : aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
1648 peter@eisentraut.org 2461 : 21 : strVal(object));
5490 tgl@sss.pgh.pa.us 2462 : 1057 : break;
1218 peter@eisentraut.org 2463 : 3079 : case OBJECT_COLLATION:
2464 : : case OBJECT_CONVERSION:
2465 : : case OBJECT_OPCLASS:
2466 : : case OBJECT_OPFAMILY:
2467 : : case OBJECT_STATISTIC_EXT:
2468 : : case OBJECT_TSDICTIONARY:
2469 : : case OBJECT_TSCONFIGURATION:
2470 [ + + ]: 3079 : if (!object_ownercheck(address.classId, address.objectId, roleid))
3025 peter_e@gmx.net 2471 : 6 : aclcheck_error(ACLCHECK_NOT_OWNER, objtype,
3410 2472 : 6 : NameListToString(castNode(List, object)));
5490 tgl@sss.pgh.pa.us 2473 : 3073 : break;
2474 : 30 : case OBJECT_LARGEOBJECT:
2475 [ + - ]: 30 : if (!lo_compat_privileges &&
1218 peter@eisentraut.org 2476 [ - + ]: 30 : !object_ownercheck(address.classId, address.objectId, roleid))
5490 tgl@sss.pgh.pa.us 2477 [ # # ]:UBC 0 : ereport(ERROR,
2478 : : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2479 : : errmsg("must be owner of large object %u",
2480 : : address.objectId)));
5490 tgl@sss.pgh.pa.us 2481 :CBC 30 : break;
2482 : 14 : case OBJECT_CAST:
2483 : : {
2484 : : /* We can only check permissions on the source/target types */
3261 2485 : 14 : TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
2486 : 14 : TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
5453 bruce@momjian.us 2487 : 14 : Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
2488 : 14 : Oid targettypeid = typenameTypeId(NULL, targettype);
2489 : :
1218 peter@eisentraut.org 2490 [ - + ]: 14 : if (!object_ownercheck(TypeRelationId, sourcetypeid, roleid)
1218 peter@eisentraut.org 2491 [ # # ]:UBC 0 : && !object_ownercheck(TypeRelationId, targettypeid, roleid))
5490 tgl@sss.pgh.pa.us 2492 [ # # ]: 0 : ereport(ERROR,
2493 : : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2494 : : errmsg("must be owner of type %s or type %s",
2495 : : format_type_be(sourcetypeid),
2496 : : format_type_be(targettypeid))));
2497 : : }
5490 tgl@sss.pgh.pa.us 2498 :CBC 14 : break;
3976 peter_e@gmx.net 2499 : 11 : case OBJECT_TRANSFORM:
2500 : : {
3261 tgl@sss.pgh.pa.us 2501 : 11 : TypeName *typename = linitial_node(TypeName, castNode(List, object));
3976 peter_e@gmx.net 2502 : 11 : Oid typeid = typenameTypeId(NULL, typename);
2503 : :
1218 peter@eisentraut.org 2504 [ - + ]: 11 : if (!object_ownercheck(TypeRelationId, typeid, roleid))
3976 peter_e@gmx.net 2505 :UBC 0 : aclcheck_error_type(ACLCHECK_NOT_OWNER, typeid);
2506 : : }
3976 peter_e@gmx.net 2507 :CBC 11 : break;
5485 tgl@sss.pgh.pa.us 2508 : 21 : case OBJECT_ROLE:
2509 : :
2510 : : /*
2511 : : * We treat roles as being "owned" by those with CREATEROLE priv,
2512 : : * provided that they also have admin option on the role.
2513 : : *
2514 : : * However, superusers are only owned by superusers.
2515 : : */
2516 [ - + ]: 21 : if (superuser_arg(address.objectId))
2517 : : {
5485 tgl@sss.pgh.pa.us 2518 [ # # ]:UBC 0 : if (!superuser_arg(roleid))
2519 [ # # ]: 0 : ereport(ERROR,
2520 : : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2521 : : errmsg("permission denied"),
2522 : : errdetail("The current user must have the %s attribute.",
2523 : : "SUPERUSER")));
2524 : : }
2525 : : else
2526 : : {
4100 alvherre@alvh.no-ip. 2527 [ + + ]:CBC 21 : if (!has_createrole_privilege(roleid))
5485 tgl@sss.pgh.pa.us 2528 [ + - ]: 1 : ereport(ERROR,
2529 : : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2530 : : errmsg("permission denied"),
2531 : : errdetail("The current user must have the %s attribute.",
2532 : : "CREATEROLE")));
1160 rhaas@postgresql.org 2533 [ + + ]: 20 : if (!is_admin_of_role(roleid, address.objectId))
2534 [ + - ]: 3 : ereport(ERROR,
2535 : : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2536 : : errmsg("permission denied"),
2537 : : errdetail("The current user must have the %s option on role \"%s\".",
2538 : : "ADMIN",
2539 : : GetUserNameFromId(address.objectId,
2540 : : true))));
2541 : : }
5485 tgl@sss.pgh.pa.us 2542 : 17 : break;
5490 2543 : 74 : case OBJECT_TSPARSER:
2544 : : case OBJECT_TSTEMPLATE:
2545 : : case OBJECT_ACCESS_METHOD:
2546 : : case OBJECT_PARAMETER_ACL:
2547 : : /* We treat these object types as being owned by superusers */
2548 [ - + ]: 74 : if (!superuser_arg(roleid))
5490 tgl@sss.pgh.pa.us 2549 [ # # ]:UBC 0 : ereport(ERROR,
2550 : : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2551 : : errmsg("must be superuser")));
5490 tgl@sss.pgh.pa.us 2552 :CBC 74 : break;
1214 peter@eisentraut.org 2553 :UBC 0 : case OBJECT_AMOP:
2554 : : case OBJECT_AMPROC:
2555 : : case OBJECT_DEFAULT:
2556 : : case OBJECT_DEFACL:
2557 : : case OBJECT_PUBLICATION_NAMESPACE:
2558 : : case OBJECT_PUBLICATION_REL:
2559 : : case OBJECT_USER_MAPPING:
2560 : : /* These are currently not supported or don't make sense here. */
2561 [ # # ]: 0 : elog(ERROR, "unsupported object type: %d", (int) objtype);
2562 : : break;
2563 : : }
5490 tgl@sss.pgh.pa.us 2564 :CBC 5486 : }
2565 : :
2566 : : /*
2567 : : * get_object_namespace
2568 : : *
2569 : : * Find the schema containing the specified object. For non-schema objects,
2570 : : * this function returns InvalidOid.
2571 : : */
2572 : : Oid
5261 rhaas@postgresql.org 2573 : 447747 : get_object_namespace(const ObjectAddress *address)
2574 : : {
2575 : : SysCacheIdentifier cache;
2576 : : HeapTuple tuple;
2577 : : Oid oid;
2578 : : const ObjectPropertyType *property;
2579 : :
2580 : : /* If not owned by a namespace, just return InvalidOid. */
2581 : 447747 : property = get_object_property_data(address->classId);
2582 [ + + ]: 447747 : if (property->attnum_namespace == InvalidAttrNumber)
2583 : 25422 : return InvalidOid;
2584 : :
2585 : : /* Currently, we can only handle object types with system caches. */
2586 : 422325 : cache = property->oid_catcache_id;
25 michael@paquier.xyz 2587 [ - + ]:GNC 422325 : Assert(cache != SYSCACHEID_INVALID);
2588 : :
2589 : : /* Fetch tuple from syscache and extract namespace attribute. */
5261 rhaas@postgresql.org 2590 :CBC 422325 : tuple = SearchSysCache1(cache, ObjectIdGetDatum(address->objectId));
2591 [ - + ]: 422325 : if (!HeapTupleIsValid(tuple))
5261 rhaas@postgresql.org 2592 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for cache %d oid %u",
2593 : : cache, address->objectId);
1086 dgustafsson@postgres 2594 :CBC 422325 : oid = DatumGetObjectId(SysCacheGetAttrNotNull(cache,
2595 : : tuple,
2596 : 422325 : property->attnum_namespace));
5261 rhaas@postgresql.org 2597 : 422325 : ReleaseSysCache(tuple);
2598 : :
2599 : 422325 : return oid;
2600 : : }
2601 : :
2602 : : /*
2603 : : * Return ObjectType for the given object type as given by
2604 : : * getObjectTypeDescription; if no valid ObjectType code exists, but it's a
2605 : : * possible output type from getObjectTypeDescription, return -1.
2606 : : * Otherwise, an error is thrown.
2607 : : */
2608 : : int
4100 alvherre@alvh.no-ip. 2609 : 1042 : read_objtype_from_string(const char *objtype)
2610 : : {
2611 : : int i;
2612 : :
2613 [ + + ]: 30697 : for (i = 0; i < lengthof(ObjectTypeMap); i++)
2614 : : {
2615 [ + + ]: 30694 : if (strcmp(ObjectTypeMap[i].tm_name, objtype) == 0)
3455 2616 : 1039 : return ObjectTypeMap[i].tm_type;
2617 : : }
2618 [ + - ]: 3 : ereport(ERROR,
2619 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2620 : : errmsg("unrecognized object type \"%s\"", objtype)));
2621 : :
2622 : : return -1; /* keep compiler quiet */
2623 : : }
2624 : :
2625 : : /*
2626 : : * Interfaces to reference fields of ObjectPropertyType
2627 : : */
2628 : : const char *
2105 peter@eisentraut.org 2629 :UBC 0 : get_object_class_descr(Oid class_id)
2630 : : {
2631 : 0 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2632 : :
2633 : 0 : return prop->class_descr;
2634 : : }
2635 : :
2636 : : Oid
4917 alvherre@alvh.no-ip. 2637 :CBC 2431 : get_object_oid_index(Oid class_id)
2638 : : {
4439 tgl@sss.pgh.pa.us 2639 : 2431 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2640 : :
4917 alvherre@alvh.no-ip. 2641 : 2431 : return prop->oid_index_oid;
2642 : : }
2643 : :
2644 : : SysCacheIdentifier
2645 : 38595 : get_object_catcache_oid(Oid class_id)
2646 : : {
4439 tgl@sss.pgh.pa.us 2647 : 38595 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2648 : :
4917 alvherre@alvh.no-ip. 2649 : 38595 : return prop->oid_catcache_id;
2650 : : }
2651 : :
2652 : : SysCacheIdentifier
2653 : 354 : get_object_catcache_name(Oid class_id)
2654 : : {
4439 tgl@sss.pgh.pa.us 2655 : 354 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2656 : :
4917 alvherre@alvh.no-ip. 2657 : 354 : return prop->name_catcache_id;
2658 : : }
2659 : :
2660 : : AttrNumber
2672 andres@anarazel.de 2661 : 5859 : get_object_attnum_oid(Oid class_id)
2662 : : {
2663 : 5859 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2664 : :
2665 : 5859 : return prop->attnum_oid;
2666 : : }
2667 : :
2668 : : AttrNumber
4917 alvherre@alvh.no-ip. 2669 : 4070 : get_object_attnum_name(Oid class_id)
2670 : : {
4439 tgl@sss.pgh.pa.us 2671 : 4070 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2672 : :
4917 alvherre@alvh.no-ip. 2673 : 4070 : return prop->attnum_name;
2674 : : }
2675 : :
2676 : : AttrNumber
2677 : 4122 : get_object_attnum_namespace(Oid class_id)
2678 : : {
4439 tgl@sss.pgh.pa.us 2679 : 4122 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2680 : :
4917 alvherre@alvh.no-ip. 2681 : 4122 : return prop->attnum_namespace;
2682 : : }
2683 : :
2684 : : AttrNumber
2685 : 31755 : get_object_attnum_owner(Oid class_id)
2686 : : {
4439 tgl@sss.pgh.pa.us 2687 : 31755 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2688 : :
4917 alvherre@alvh.no-ip. 2689 : 31755 : return prop->attnum_owner;
2690 : : }
2691 : :
2692 : : AttrNumber
2693 : 28002 : get_object_attnum_acl(Oid class_id)
2694 : : {
4439 tgl@sss.pgh.pa.us 2695 : 28002 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2696 : :
4917 alvherre@alvh.no-ip. 2697 : 28002 : return prop->attnum_acl;
2698 : : }
2699 : :
2700 : : /*
2701 : : * get_object_type
2702 : : *
2703 : : * Return the object type associated with a given object. This routine
2704 : : * is primarily used to determine the object type to mention in ACL check
2705 : : * error messages, so it's desirable for it to avoid failing.
2706 : : */
2707 : : ObjectType
3025 peter_e@gmx.net 2708 : 24338 : get_object_type(Oid class_id, Oid object_id)
2709 : : {
4439 tgl@sss.pgh.pa.us 2710 : 24338 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2711 : :
3025 peter_e@gmx.net 2712 [ - + ]: 24338 : if (prop->objtype == OBJECT_TABLE)
2713 : : {
2714 : : /*
2715 : : * If the property data says it's a table, dig a little deeper to get
2716 : : * the real relation kind, so that callers can produce more precise
2717 : : * error messages.
2718 : : */
3025 peter_e@gmx.net 2719 :UBC 0 : return get_relkind_objtype(get_rel_relkind(object_id));
2720 : : }
2721 : : else
3025 peter_e@gmx.net 2722 :CBC 24338 : return prop->objtype;
2723 : : }
2724 : :
2725 : : bool
4743 alvherre@alvh.no-ip. 2726 : 2801 : get_object_namensp_unique(Oid class_id)
2727 : : {
4439 tgl@sss.pgh.pa.us 2728 : 2801 : const ObjectPropertyType *prop = get_object_property_data(class_id);
2729 : :
4743 alvherre@alvh.no-ip. 2730 : 2801 : return prop->is_nsp_name_unique;
2731 : : }
2732 : :
2733 : : /*
2734 : : * Return whether we have useful data for the given object class in the
2735 : : * ObjectProperty table.
2736 : : */
2737 : : bool
2738 : 3324 : is_objectclass_supported(Oid class_id)
2739 : : {
2740 : : int index;
2741 : :
2742 [ + + ]: 75763 : for (index = 0; index < lengthof(ObjectProperty); index++)
2743 : : {
2744 [ + + ]: 75693 : if (ObjectProperty[index].class_oid == class_id)
2745 : 3254 : return true;
2746 : : }
2747 : :
2748 : 70 : return false;
2749 : : }
2750 : :
2751 : : /*
2752 : : * Find ObjectProperty structure by class_id.
2753 : : */
2754 : : static const ObjectPropertyType *
5261 rhaas@postgresql.org 2755 : 590074 : get_object_property_data(Oid class_id)
2756 : : {
2757 : : static const ObjectPropertyType *prop_last = NULL;
2758 : : int index;
2759 : :
2760 : : /*
2761 : : * A shortcut to speed up multiple consecutive lookups of a particular
2762 : : * object class.
2763 : : */
4917 alvherre@alvh.no-ip. 2764 [ + + + + ]: 590074 : if (prop_last && prop_last->class_oid == class_id)
2765 : 303074 : return prop_last;
2766 : :
5261 rhaas@postgresql.org 2767 [ + - ]: 6477731 : for (index = 0; index < lengthof(ObjectProperty); index++)
2768 : : {
2769 [ + + ]: 6477731 : if (ObjectProperty[index].class_oid == class_id)
2770 : : {
4917 alvherre@alvh.no-ip. 2771 : 287000 : prop_last = &ObjectProperty[index];
5261 rhaas@postgresql.org 2772 : 287000 : return &ObjectProperty[index];
2773 : : }
2774 : : }
2775 : :
4917 alvherre@alvh.no-ip. 2776 [ # # ]:UBC 0 : ereport(ERROR,
2777 : : (errmsg_internal("unrecognized class ID: %u", class_id)));
2778 : :
2779 : : return NULL; /* keep MSC compiler happy */
2780 : : }
2781 : :
2782 : : /*
2783 : : * Return a copy of the tuple for the object with the given object OID, from
2784 : : * the given catalog (which must have been opened by the caller and suitably
2785 : : * locked). NULL is returned if the OID is not found.
2786 : : *
2787 : : * We try a syscache first, if available.
2788 : : */
2789 : : HeapTuple
2672 andres@anarazel.de 2790 :CBC 3779 : get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
2791 : : {
2792 : : return
442 noah@leadboat.com 2793 : 3779 : get_catalog_object_by_oid_extended(catalog, oidcol, objectId, false);
2794 : : }
2795 : :
2796 : : /*
2797 : : * Same as get_catalog_object_by_oid(), but with an additional "locktup"
2798 : : * argument controlling whether to acquire a LOCKTAG_TUPLE at mode
2799 : : * InplaceUpdateTupleLock. See README.tuplock section "Locking to write
2800 : : * inplace-updated tables".
2801 : : */
2802 : : HeapTuple
2803 : 4400 : get_catalog_object_by_oid_extended(Relation catalog,
2804 : : AttrNumber oidcol,
2805 : : Oid objectId,
2806 : : bool locktup)
2807 : : {
2808 : : HeapTuple tuple;
4743 alvherre@alvh.no-ip. 2809 : 4400 : Oid classId = RelationGetRelid(catalog);
25 michael@paquier.xyz 2810 :GNC 4400 : SysCacheIdentifier oidCacheId = get_object_catcache_oid(classId);
2811 : :
2812 [ + + ]: 4400 : if (oidCacheId >= 0)
2813 : : {
442 noah@leadboat.com 2814 [ + + ]:CBC 3985 : if (locktup)
2815 : 612 : tuple = SearchSysCacheLockedCopy1(oidCacheId,
2816 : : ObjectIdGetDatum(objectId));
2817 : : else
2818 : 3373 : tuple = SearchSysCacheCopy1(oidCacheId,
2819 : : ObjectIdGetDatum(objectId));
4673 bruce@momjian.us 2820 [ + + ]: 3985 : if (!HeapTupleIsValid(tuple)) /* should not happen */
4743 alvherre@alvh.no-ip. 2821 : 96 : return NULL;
2822 : : }
2823 : : else
2824 : : {
2825 : 415 : Oid oidIndexId = get_object_oid_index(classId);
2826 : : SysScanDesc scan;
2827 : : ScanKeyData skey;
2828 : :
2829 [ - + ]: 415 : Assert(OidIsValid(oidIndexId));
2830 : :
2831 : 415 : ScanKeyInit(&skey,
2832 : : oidcol,
2833 : : BTEqualStrategyNumber, F_OIDEQ,
2834 : : ObjectIdGetDatum(objectId));
2835 : :
2836 : 415 : scan = systable_beginscan(catalog, oidIndexId, true,
2837 : : NULL, 1, &skey);
2838 : 415 : tuple = systable_getnext(scan);
2839 [ + + ]: 415 : if (!HeapTupleIsValid(tuple))
2840 : : {
2841 : 51 : systable_endscan(scan);
2842 : 51 : return NULL;
2843 : : }
2844 : :
442 noah@leadboat.com 2845 [ + + ]: 364 : if (locktup)
2846 : 9 : LockTuple(catalog, &tuple->t_self, InplaceUpdateTupleLock);
2847 : :
4743 alvherre@alvh.no-ip. 2848 : 364 : tuple = heap_copytuple(tuple);
2849 : :
2850 : 364 : systable_endscan(scan);
2851 : : }
2852 : :
2853 : 4253 : return tuple;
2854 : : }
2855 : :
2856 : : /*
2857 : : * getPublicationSchemaInfo
2858 : : *
2859 : : * Get publication name and schema name from the object address into pubname and
2860 : : * nspname. Both pubname and nspname are palloc'd strings which will be freed by
2861 : : * the caller.
2862 : : */
2863 : : static bool
1600 akapila@postgresql.o 2864 : 101 : getPublicationSchemaInfo(const ObjectAddress *object, bool missing_ok,
2865 : : char **pubname, char **nspname)
2866 : : {
2867 : : HeapTuple tup;
2868 : : Form_pg_publication_namespace pnform;
2869 : :
2870 : 101 : tup = SearchSysCache1(PUBLICATIONNAMESPACE,
2871 : 101 : ObjectIdGetDatum(object->objectId));
2872 [ + + ]: 101 : if (!HeapTupleIsValid(tup))
2873 : : {
2874 [ - + ]: 9 : if (!missing_ok)
1600 akapila@postgresql.o 2875 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for publication schema %u",
2876 : : object->objectId);
1600 akapila@postgresql.o 2877 :CBC 9 : return false;
2878 : : }
2879 : :
2880 : 92 : pnform = (Form_pg_publication_namespace) GETSTRUCT(tup);
2881 : 92 : *pubname = get_publication_name(pnform->pnpubid, missing_ok);
2882 [ - + ]: 92 : if (!(*pubname))
2883 : : {
1600 akapila@postgresql.o 2884 :UBC 0 : ReleaseSysCache(tup);
2885 : 0 : return false;
2886 : : }
2887 : :
1600 akapila@postgresql.o 2888 :CBC 92 : *nspname = get_namespace_name(pnform->pnnspid);
2889 [ - + ]: 92 : if (!(*nspname))
2890 : : {
1600 akapila@postgresql.o 2891 :UBC 0 : Oid schemaid = pnform->pnnspid;
2892 : :
2893 : 0 : pfree(*pubname);
2894 : 0 : ReleaseSysCache(tup);
2895 [ # # ]: 0 : if (!missing_ok)
2896 [ # # ]: 0 : elog(ERROR, "cache lookup failed for schema %u",
2897 : : schemaid);
2898 : 0 : return false;
2899 : : }
2900 : :
1600 akapila@postgresql.o 2901 :CBC 92 : ReleaseSysCache(tup);
2902 : 92 : return true;
2903 : : }
2904 : :
2905 : : /*
2906 : : * getObjectDescription: build an object description for messages
2907 : : *
2908 : : * The result is a palloc'd string. NULL is returned for an undefined
2909 : : * object if missing_ok is true, else an error is generated.
2910 : : */
2911 : : char *
2069 michael@paquier.xyz 2912 : 97661 : getObjectDescription(const ObjectAddress *object, bool missing_ok)
2913 : : {
2914 : : StringInfoData buffer;
2915 : :
4743 alvherre@alvh.no-ip. 2916 : 97661 : initStringInfo(&buffer);
2917 : :
719 peter@eisentraut.org 2918 [ + + + + : 97661 : switch (object->classId)
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + - ]
2919 : : {
2920 : 27190 : case RelationRelationId:
2852 tgl@sss.pgh.pa.us 2921 [ + + ]: 27190 : if (object->objectSubId == 0)
2069 michael@paquier.xyz 2922 : 25327 : getRelationDescription(&buffer, object->objectId, missing_ok);
2923 : : else
2924 : : {
2925 : : /* column, not whole relation */
2926 : : StringInfoData rel;
2927 : 1863 : char *attname = get_attname(object->objectId,
2928 : 1863 : object->objectSubId,
2929 : : missing_ok);
2930 : :
2931 [ + + ]: 1863 : if (!attname)
2932 : 3 : break;
2933 : :
2852 tgl@sss.pgh.pa.us 2934 : 1860 : initStringInfo(&rel);
2069 michael@paquier.xyz 2935 : 1860 : getRelationDescription(&rel, object->objectId, missing_ok);
2936 : : /* translator: second %s is, e.g., "table %s" */
2852 tgl@sss.pgh.pa.us 2937 : 1860 : appendStringInfo(&buffer, _("column %s of %s"),
2938 : : attname, rel.data);
2939 : 1860 : pfree(rel.data);
2940 : : }
4743 alvherre@alvh.no-ip. 2941 : 27187 : break;
2942 : :
719 peter@eisentraut.org 2943 : 2461 : case ProcedureRelationId:
2944 : : {
2069 michael@paquier.xyz 2945 : 2461 : bits16 flags = FORMAT_PROC_INVALID_AS_NULL;
2946 : 2461 : char *proname = format_procedure_extended(object->objectId,
2947 : : flags);
2948 : :
2949 [ + + ]: 2461 : if (proname == NULL)
2950 : 3 : break;
2951 : :
2952 : 2458 : appendStringInfo(&buffer, _("function %s"), proname);
2953 : 2458 : break;
2954 : : }
2955 : :
719 peter@eisentraut.org 2956 : 39999 : case TypeRelationId:
2957 : : {
2069 michael@paquier.xyz 2958 : 39999 : bits16 flags = FORMAT_TYPE_INVALID_AS_NULL;
2959 : 39999 : char *typname = format_type_extended(object->objectId, -1,
2960 : : flags);
2961 : :
2962 [ + + ]: 39999 : if (typname == NULL)
2963 : 3 : break;
2964 : :
2965 : 39996 : appendStringInfo(&buffer, _("type %s"), typname);
2966 : 39996 : break;
2967 : : }
2968 : :
719 peter@eisentraut.org 2969 : 135 : case CastRelationId:
2970 : : {
2971 : : Relation castDesc;
2972 : : ScanKeyData skey[1];
2973 : : SysScanDesc rcscan;
2974 : : HeapTuple tup;
2975 : : Form_pg_cast castForm;
2976 : :
2610 andres@anarazel.de 2977 : 135 : castDesc = table_open(CastRelationId, AccessShareLock);
2978 : :
4743 alvherre@alvh.no-ip. 2979 : 135 : ScanKeyInit(&skey[0],
2980 : : Anum_pg_cast_oid,
2981 : : BTEqualStrategyNumber, F_OIDEQ,
2982 : 135 : ObjectIdGetDatum(object->objectId));
2983 : :
2984 : 135 : rcscan = systable_beginscan(castDesc, CastOidIndexId, true,
2985 : : NULL, 1, skey);
2986 : :
2987 : 135 : tup = systable_getnext(rcscan);
2988 : :
2989 [ + + ]: 135 : if (!HeapTupleIsValid(tup))
2990 : : {
2069 michael@paquier.xyz 2991 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 2992 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for cast %u",
2993 : : object->objectId);
2994 : :
2069 michael@paquier.xyz 2995 :CBC 3 : systable_endscan(rcscan);
2996 : 3 : table_close(castDesc, AccessShareLock);
2997 : 3 : break;
2998 : : }
2999 : :
4743 alvherre@alvh.no-ip. 3000 : 132 : castForm = (Form_pg_cast) GETSTRUCT(tup);
3001 : :
3002 : 132 : appendStringInfo(&buffer, _("cast from %s to %s"),
3003 : : format_type_be(castForm->castsource),
3004 : : format_type_be(castForm->casttarget));
3005 : :
3006 : 132 : systable_endscan(rcscan);
2610 andres@anarazel.de 3007 : 132 : table_close(castDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 3008 : 132 : break;
3009 : : }
3010 : :
719 peter@eisentraut.org 3011 : 36 : case CollationRelationId:
3012 : : {
3013 : : HeapTuple collTup;
3014 : : Form_pg_collation coll;
3015 : : char *nspname;
3016 : :
4743 alvherre@alvh.no-ip. 3017 : 36 : collTup = SearchSysCache1(COLLOID,
3018 : 36 : ObjectIdGetDatum(object->objectId));
3019 [ + + ]: 36 : if (!HeapTupleIsValid(collTup))
3020 : : {
2069 michael@paquier.xyz 3021 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3022 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for collation %u",
3023 : : object->objectId);
2069 michael@paquier.xyz 3024 :CBC 3 : break;
3025 : : }
3026 : :
4743 alvherre@alvh.no-ip. 3027 : 33 : coll = (Form_pg_collation) GETSTRUCT(collTup);
3028 : :
3029 : : /* Qualify the name if not visible in search path */
2852 tgl@sss.pgh.pa.us 3030 [ + - ]: 33 : if (CollationIsVisible(object->objectId))
3031 : 33 : nspname = NULL;
3032 : : else
2852 tgl@sss.pgh.pa.us 3033 :UBC 0 : nspname = get_namespace_name(coll->collnamespace);
3034 : :
4743 alvherre@alvh.no-ip. 3035 :CBC 33 : appendStringInfo(&buffer, _("collation %s"),
3036 : : quote_qualified_identifier(nspname,
2852 tgl@sss.pgh.pa.us 3037 : 33 : NameStr(coll->collname)));
4743 alvherre@alvh.no-ip. 3038 : 33 : ReleaseSysCache(collTup);
3039 : 33 : break;
3040 : : }
3041 : :
719 peter@eisentraut.org 3042 : 13776 : case ConstraintRelationId:
3043 : : {
3044 : : HeapTuple conTup;
3045 : : Form_pg_constraint con;
3046 : :
4743 alvherre@alvh.no-ip. 3047 : 13776 : conTup = SearchSysCache1(CONSTROID,
3048 : 13776 : ObjectIdGetDatum(object->objectId));
3049 [ + + ]: 13776 : if (!HeapTupleIsValid(conTup))
3050 : : {
2069 michael@paquier.xyz 3051 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3052 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for constraint %u",
3053 : : object->objectId);
2069 michael@paquier.xyz 3054 :CBC 3 : break;
3055 : : }
3056 : :
4743 alvherre@alvh.no-ip. 3057 : 13773 : con = (Form_pg_constraint) GETSTRUCT(conTup);
3058 : :
3059 [ + + ]: 13773 : if (OidIsValid(con->conrelid))
3060 : : {
3061 : : StringInfoData rel;
3062 : :
3063 : 13601 : initStringInfo(&rel);
2069 michael@paquier.xyz 3064 : 13601 : getRelationDescription(&rel, con->conrelid, false);
3065 : : /* translator: second %s is, e.g., "table %s" */
4743 alvherre@alvh.no-ip. 3066 : 13601 : appendStringInfo(&buffer, _("constraint %s on %s"),
3067 : 13601 : NameStr(con->conname), rel.data);
3068 : 13601 : pfree(rel.data);
3069 : : }
3070 : : else
3071 : : {
3072 : 172 : appendStringInfo(&buffer, _("constraint %s"),
3073 : 172 : NameStr(con->conname));
3074 : : }
3075 : :
3076 : 13773 : ReleaseSysCache(conTup);
3077 : 13773 : break;
3078 : : }
3079 : :
719 peter@eisentraut.org 3080 : 18 : case ConversionRelationId:
3081 : : {
3082 : : HeapTuple conTup;
3083 : : Form_pg_conversion conv;
3084 : : char *nspname;
3085 : :
4743 alvherre@alvh.no-ip. 3086 : 18 : conTup = SearchSysCache1(CONVOID,
3087 : 18 : ObjectIdGetDatum(object->objectId));
3088 [ + + ]: 18 : if (!HeapTupleIsValid(conTup))
3089 : : {
2069 michael@paquier.xyz 3090 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3091 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for conversion %u",
3092 : : object->objectId);
2069 michael@paquier.xyz 3093 :CBC 3 : break;
3094 : : }
3095 : :
2852 tgl@sss.pgh.pa.us 3096 : 15 : conv = (Form_pg_conversion) GETSTRUCT(conTup);
3097 : :
3098 : : /* Qualify the name if not visible in search path */
3099 [ + + ]: 15 : if (ConversionIsVisible(object->objectId))
3100 : 9 : nspname = NULL;
3101 : : else
3102 : 6 : nspname = get_namespace_name(conv->connamespace);
3103 : :
4743 alvherre@alvh.no-ip. 3104 : 15 : appendStringInfo(&buffer, _("conversion %s"),
3105 : : quote_qualified_identifier(nspname,
2852 tgl@sss.pgh.pa.us 3106 : 15 : NameStr(conv->conname)));
4743 alvherre@alvh.no-ip. 3107 : 15 : ReleaseSysCache(conTup);
3108 : 15 : break;
3109 : : }
3110 : :
719 peter@eisentraut.org 3111 : 1650 : case AttrDefaultRelationId:
3112 : : {
3113 : : ObjectAddress colobject;
3114 : :
1455 tgl@sss.pgh.pa.us 3115 : 1650 : colobject = GetAttrDefaultColumnAddress(object->objectId);
3116 : :
3117 [ + + ]: 1650 : if (!OidIsValid(colobject.objectId))
3118 : : {
2069 michael@paquier.xyz 3119 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3120 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for attrdef %u",
3121 : : object->objectId);
2069 michael@paquier.xyz 3122 :CBC 3 : break;
3123 : : }
3124 : :
3125 : : /* translator: %s is typically "column %s of table %s" */
2852 tgl@sss.pgh.pa.us 3126 : 1647 : appendStringInfo(&buffer, _("default value for %s"),
3127 : : getObjectDescription(&colobject, false));
4743 alvherre@alvh.no-ip. 3128 : 1647 : break;
3129 : : }
3130 : :
719 peter@eisentraut.org 3131 : 12 : case LanguageRelationId:
3132 : : {
2069 michael@paquier.xyz 3133 : 12 : char *langname = get_language_name(object->objectId,
3134 : : missing_ok);
3135 : :
3136 [ + + ]: 12 : if (langname)
3137 : 9 : appendStringInfo(&buffer, _("language %s"),
3138 : 9 : get_language_name(object->objectId, false));
3139 : 12 : break;
3140 : : }
3141 : :
719 peter@eisentraut.org 3142 : 3 : case LargeObjectRelationId:
2069 michael@paquier.xyz 3143 [ + - ]: 3 : if (!LargeObjectExists(object->objectId))
3144 : 3 : break;
4743 alvherre@alvh.no-ip. 3145 :UBC 0 : appendStringInfo(&buffer, _("large object %u"),
3146 : 0 : object->objectId);
3147 : 0 : break;
3148 : :
719 peter@eisentraut.org 3149 :CBC 392 : case OperatorRelationId:
3150 : : {
2069 michael@paquier.xyz 3151 : 392 : bits16 flags = FORMAT_OPERATOR_INVALID_AS_NULL;
3152 : 392 : char *oprname = format_operator_extended(object->objectId,
3153 : : flags);
3154 : :
3155 [ + + ]: 392 : if (oprname == NULL)
3156 : 3 : break;
3157 : :
3158 : 389 : appendStringInfo(&buffer, _("operator %s"), oprname);
3159 : 389 : break;
3160 : : }
3161 : :
719 peter@eisentraut.org 3162 : 154 : case OperatorClassRelationId:
3163 : : {
3164 : : HeapTuple opcTup;
3165 : : Form_pg_opclass opcForm;
3166 : : HeapTuple amTup;
3167 : : Form_pg_am amForm;
3168 : : char *nspname;
3169 : :
4743 alvherre@alvh.no-ip. 3170 : 154 : opcTup = SearchSysCache1(CLAOID,
3171 : 154 : ObjectIdGetDatum(object->objectId));
3172 [ + + ]: 154 : if (!HeapTupleIsValid(opcTup))
3173 : : {
2069 michael@paquier.xyz 3174 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3175 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for opclass %u",
3176 : : object->objectId);
2069 michael@paquier.xyz 3177 :CBC 3 : break;
3178 : : }
3179 : :
4743 alvherre@alvh.no-ip. 3180 : 151 : opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
3181 : :
3182 : 151 : amTup = SearchSysCache1(AMOID,
3183 : : ObjectIdGetDatum(opcForm->opcmethod));
3184 [ - + ]: 151 : if (!HeapTupleIsValid(amTup))
4743 alvherre@alvh.no-ip. 3185 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for access method %u",
3186 : : opcForm->opcmethod);
4743 alvherre@alvh.no-ip. 3187 :CBC 151 : amForm = (Form_pg_am) GETSTRUCT(amTup);
3188 : :
3189 : : /* Qualify the name if not visible in search path */
3190 [ + + ]: 151 : if (OpclassIsVisible(object->objectId))
3191 : 137 : nspname = NULL;
3192 : : else
3193 : 14 : nspname = get_namespace_name(opcForm->opcnamespace);
3194 : :
3195 : 151 : appendStringInfo(&buffer, _("operator class %s for access method %s"),
3196 : : quote_qualified_identifier(nspname,
3189 tgl@sss.pgh.pa.us 3197 : 151 : NameStr(opcForm->opcname)),
4743 alvherre@alvh.no-ip. 3198 : 151 : NameStr(amForm->amname));
3199 : :
3200 : 151 : ReleaseSysCache(amTup);
3201 : 151 : ReleaseSysCache(opcTup);
3202 : 151 : break;
3203 : : }
3204 : :
719 peter@eisentraut.org 3205 : 155 : case OperatorFamilyRelationId:
2069 michael@paquier.xyz 3206 : 155 : getOpFamilyDescription(&buffer, object->objectId, missing_ok);
4743 alvherre@alvh.no-ip. 3207 : 155 : break;
3208 : :
719 peter@eisentraut.org 3209 : 34 : case AccessMethodRelationId:
3210 : : {
3211 : : HeapTuple tup;
3212 : :
3227 tgl@sss.pgh.pa.us 3213 : 34 : tup = SearchSysCache1(AMOID,
3214 : 34 : ObjectIdGetDatum(object->objectId));
3215 [ + + ]: 34 : if (!HeapTupleIsValid(tup))
3216 : : {
2069 michael@paquier.xyz 3217 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3218 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for access method %u",
3219 : : object->objectId);
2069 michael@paquier.xyz 3220 :CBC 3 : break;
3221 : : }
3222 : :
3227 tgl@sss.pgh.pa.us 3223 : 31 : appendStringInfo(&buffer, _("access method %s"),
3189 3224 : 31 : NameStr(((Form_pg_am) GETSTRUCT(tup))->amname));
3227 3225 : 31 : ReleaseSysCache(tup);
3226 : 31 : break;
3227 : : }
3228 : :
719 peter@eisentraut.org 3229 : 1047 : case AccessMethodOperatorRelationId:
3230 : : {
3231 : : Relation amopDesc;
3232 : : HeapTuple tup;
3233 : : ScanKeyData skey[1];
3234 : : SysScanDesc amscan;
3235 : : Form_pg_amop amopForm;
3236 : : StringInfoData opfam;
3237 : :
2610 andres@anarazel.de 3238 : 1047 : amopDesc = table_open(AccessMethodOperatorRelationId,
3239 : : AccessShareLock);
3240 : :
4743 alvherre@alvh.no-ip. 3241 : 1047 : ScanKeyInit(&skey[0],
3242 : : Anum_pg_amop_oid,
3243 : : BTEqualStrategyNumber, F_OIDEQ,
3244 : 1047 : ObjectIdGetDatum(object->objectId));
3245 : :
3246 : 1047 : amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
3247 : : NULL, 1, skey);
3248 : :
3249 : 1047 : tup = systable_getnext(amscan);
3250 : :
3251 [ + + ]: 1047 : if (!HeapTupleIsValid(tup))
3252 : : {
2069 michael@paquier.xyz 3253 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3254 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for amop entry %u",
3255 : : object->objectId);
3256 : :
2069 michael@paquier.xyz 3257 :CBC 3 : systable_endscan(amscan);
3258 : 3 : table_close(amopDesc, AccessShareLock);
3259 : 3 : break;
3260 : : }
3261 : :
4743 alvherre@alvh.no-ip. 3262 : 1044 : amopForm = (Form_pg_amop) GETSTRUCT(tup);
3263 : :
3264 : 1044 : initStringInfo(&opfam);
2069 michael@paquier.xyz 3265 : 1044 : getOpFamilyDescription(&opfam, amopForm->amopfamily, false);
3266 : :
3267 : : /*
3268 : : * We use FORMAT_TYPE_ALLOW_INVALID here so as not to fail
3269 : : * completely if the type links are dangling, which is a form
3270 : : * of catalog corruption that could occur due to old bugs.
3271 : : */
3272 : :
3273 : : /*------
3274 : : translator: %d is the operator strategy (a number), the
3275 : : first two %s's are data type names, the third %s is the
3276 : : description of the operator family, and the last %s is the
3277 : : textual form of the operator with arguments. */
4743 alvherre@alvh.no-ip. 3278 : 1044 : appendStringInfo(&buffer, _("operator %d (%s, %s) of %s: %s"),
3279 : 1044 : amopForm->amopstrategy,
3280 : : format_type_extended(amopForm->amoplefttype,
3281 : : -1, FORMAT_TYPE_ALLOW_INVALID),
3282 : : format_type_extended(amopForm->amoprighttype,
3283 : : -1, FORMAT_TYPE_ALLOW_INVALID),
3284 : : opfam.data,
3285 : : format_operator(amopForm->amopopr));
3286 : :
3287 : 1044 : pfree(opfam.data);
3288 : :
3289 : 1044 : systable_endscan(amscan);
2610 andres@anarazel.de 3290 : 1044 : table_close(amopDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 3291 : 1044 : break;
3292 : : }
3293 : :
719 peter@eisentraut.org 3294 : 865 : case AccessMethodProcedureRelationId:
3295 : : {
3296 : : Relation amprocDesc;
3297 : : ScanKeyData skey[1];
3298 : : SysScanDesc amscan;
3299 : : HeapTuple tup;
3300 : : Form_pg_amproc amprocForm;
3301 : : StringInfoData opfam;
3302 : :
2610 andres@anarazel.de 3303 : 865 : amprocDesc = table_open(AccessMethodProcedureRelationId,
3304 : : AccessShareLock);
3305 : :
4743 alvherre@alvh.no-ip. 3306 : 865 : ScanKeyInit(&skey[0],
3307 : : Anum_pg_amproc_oid,
3308 : : BTEqualStrategyNumber, F_OIDEQ,
3309 : 865 : ObjectIdGetDatum(object->objectId));
3310 : :
3311 : 865 : amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
3312 : : NULL, 1, skey);
3313 : :
3314 : 865 : tup = systable_getnext(amscan);
3315 : :
3316 [ + + ]: 865 : if (!HeapTupleIsValid(tup))
3317 : : {
2069 michael@paquier.xyz 3318 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3319 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for amproc entry %u",
3320 : : object->objectId);
3321 : :
2069 michael@paquier.xyz 3322 :CBC 3 : systable_endscan(amscan);
3323 : 3 : table_close(amprocDesc, AccessShareLock);
3324 : 3 : break;
3325 : : }
3326 : :
4743 alvherre@alvh.no-ip. 3327 : 862 : amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
3328 : :
3329 : 862 : initStringInfo(&opfam);
2069 michael@paquier.xyz 3330 : 862 : getOpFamilyDescription(&opfam, amprocForm->amprocfamily, false);
3331 : :
3332 : : /*
3333 : : * We use FORMAT_TYPE_ALLOW_INVALID here so as not to fail
3334 : : * completely if the type links are dangling, which is a form
3335 : : * of catalog corruption that could occur due to old bugs.
3336 : : */
3337 : :
3338 : : /*------
3339 : : translator: %d is the function number, the first two %s's
3340 : : are data type names, the third %s is the description of the
3341 : : operator family, and the last %s is the textual form of the
3342 : : function with arguments. */
4743 alvherre@alvh.no-ip. 3343 : 862 : appendStringInfo(&buffer, _("function %d (%s, %s) of %s: %s"),
3344 : 862 : amprocForm->amprocnum,
3345 : : format_type_extended(amprocForm->amproclefttype,
3346 : : -1, FORMAT_TYPE_ALLOW_INVALID),
3347 : : format_type_extended(amprocForm->amprocrighttype,
3348 : : -1, FORMAT_TYPE_ALLOW_INVALID),
3349 : : opfam.data,
3350 : : format_procedure(amprocForm->amproc));
3351 : :
3352 : 862 : pfree(opfam.data);
3353 : :
3354 : 862 : systable_endscan(amscan);
2610 andres@anarazel.de 3355 : 862 : table_close(amprocDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 3356 : 862 : break;
3357 : : }
3358 : :
719 peter@eisentraut.org 3359 : 1374 : case RewriteRelationId:
3360 : : {
3361 : : Relation ruleDesc;
3362 : : ScanKeyData skey[1];
3363 : : SysScanDesc rcscan;
3364 : : HeapTuple tup;
3365 : : Form_pg_rewrite rule;
3366 : : StringInfoData rel;
3367 : :
2610 andres@anarazel.de 3368 : 1374 : ruleDesc = table_open(RewriteRelationId, AccessShareLock);
3369 : :
4743 alvherre@alvh.no-ip. 3370 : 1374 : ScanKeyInit(&skey[0],
3371 : : Anum_pg_rewrite_oid,
3372 : : BTEqualStrategyNumber, F_OIDEQ,
3373 : 1374 : ObjectIdGetDatum(object->objectId));
3374 : :
3375 : 1374 : rcscan = systable_beginscan(ruleDesc, RewriteOidIndexId, true,
3376 : : NULL, 1, skey);
3377 : :
3378 : 1374 : tup = systable_getnext(rcscan);
3379 : :
3380 [ + + ]: 1374 : if (!HeapTupleIsValid(tup))
3381 : : {
2069 michael@paquier.xyz 3382 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3383 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for rule %u",
3384 : : object->objectId);
3385 : :
2069 michael@paquier.xyz 3386 :CBC 3 : systable_endscan(rcscan);
3387 : 3 : table_close(ruleDesc, AccessShareLock);
3388 : 3 : break;
3389 : : }
3390 : :
4743 alvherre@alvh.no-ip. 3391 : 1371 : rule = (Form_pg_rewrite) GETSTRUCT(tup);
3392 : :
2852 tgl@sss.pgh.pa.us 3393 : 1371 : initStringInfo(&rel);
2069 michael@paquier.xyz 3394 : 1371 : getRelationDescription(&rel, rule->ev_class, false);
3395 : :
3396 : : /* translator: second %s is, e.g., "table %s" */
2852 tgl@sss.pgh.pa.us 3397 : 1371 : appendStringInfo(&buffer, _("rule %s on %s"),
3398 : 1371 : NameStr(rule->rulename), rel.data);
3399 : 1371 : pfree(rel.data);
4743 alvherre@alvh.no-ip. 3400 : 1371 : systable_endscan(rcscan);
2610 andres@anarazel.de 3401 : 1371 : table_close(ruleDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 3402 : 1371 : break;
3403 : : }
3404 : :
719 peter@eisentraut.org 3405 : 6918 : case TriggerRelationId:
3406 : : {
3407 : : Relation trigDesc;
3408 : : ScanKeyData skey[1];
3409 : : SysScanDesc tgscan;
3410 : : HeapTuple tup;
3411 : : Form_pg_trigger trig;
3412 : : StringInfoData rel;
3413 : :
2610 andres@anarazel.de 3414 : 6918 : trigDesc = table_open(TriggerRelationId, AccessShareLock);
3415 : :
4743 alvherre@alvh.no-ip. 3416 : 6918 : ScanKeyInit(&skey[0],
3417 : : Anum_pg_trigger_oid,
3418 : : BTEqualStrategyNumber, F_OIDEQ,
3419 : 6918 : ObjectIdGetDatum(object->objectId));
3420 : :
3421 : 6918 : tgscan = systable_beginscan(trigDesc, TriggerOidIndexId, true,
3422 : : NULL, 1, skey);
3423 : :
3424 : 6918 : tup = systable_getnext(tgscan);
3425 : :
3426 [ + + ]: 6918 : if (!HeapTupleIsValid(tup))
3427 : : {
2069 michael@paquier.xyz 3428 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3429 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for trigger %u",
3430 : : object->objectId);
3431 : :
2069 michael@paquier.xyz 3432 :CBC 3 : systable_endscan(tgscan);
3433 : 3 : table_close(trigDesc, AccessShareLock);
3434 : 3 : break;
3435 : : }
3436 : :
4743 alvherre@alvh.no-ip. 3437 : 6915 : trig = (Form_pg_trigger) GETSTRUCT(tup);
3438 : :
2852 tgl@sss.pgh.pa.us 3439 : 6915 : initStringInfo(&rel);
2069 michael@paquier.xyz 3440 : 6915 : getRelationDescription(&rel, trig->tgrelid, false);
3441 : :
3442 : : /* translator: second %s is, e.g., "table %s" */
2852 tgl@sss.pgh.pa.us 3443 : 6915 : appendStringInfo(&buffer, _("trigger %s on %s"),
3444 : 6915 : NameStr(trig->tgname), rel.data);
3445 : 6915 : pfree(rel.data);
4743 alvherre@alvh.no-ip. 3446 : 6915 : systable_endscan(tgscan);
2610 andres@anarazel.de 3447 : 6915 : table_close(trigDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 3448 : 6915 : break;
3449 : : }
3450 : :
719 peter@eisentraut.org 3451 : 76 : case NamespaceRelationId:
3452 : : {
3453 : : char *nspname;
3454 : :
4743 alvherre@alvh.no-ip. 3455 : 76 : nspname = get_namespace_name(object->objectId);
3456 [ + + ]: 76 : if (!nspname)
3457 : : {
2069 michael@paquier.xyz 3458 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3459 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for namespace %u",
3460 : : object->objectId);
2069 michael@paquier.xyz 3461 :CBC 3 : break;
3462 : : }
4743 alvherre@alvh.no-ip. 3463 : 73 : appendStringInfo(&buffer, _("schema %s"), nspname);
3464 : 73 : break;
3465 : : }
3466 : :
719 peter@eisentraut.org 3467 : 260 : case StatisticExtRelationId:
3468 : : {
3469 : : HeapTuple stxTup;
3470 : : Form_pg_statistic_ext stxForm;
3471 : : char *nspname;
3472 : :
3227 tgl@sss.pgh.pa.us 3473 : 260 : stxTup = SearchSysCache1(STATEXTOID,
3474 : 260 : ObjectIdGetDatum(object->objectId));
3475 [ + + ]: 260 : if (!HeapTupleIsValid(stxTup))
3476 : : {
2069 michael@paquier.xyz 3477 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3478 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for statistics object %u",
3479 : : object->objectId);
2069 michael@paquier.xyz 3480 :CBC 3 : break;
3481 : : }
3482 : :
3227 tgl@sss.pgh.pa.us 3483 : 257 : stxForm = (Form_pg_statistic_ext) GETSTRUCT(stxTup);
3484 : :
3485 : : /* Qualify the name if not visible in search path */
2852 3486 [ + + ]: 257 : if (StatisticsObjIsVisible(object->objectId))
3487 : 167 : nspname = NULL;
3488 : : else
3489 : 90 : nspname = get_namespace_name(stxForm->stxnamespace);
3490 : :
3227 3491 : 257 : appendStringInfo(&buffer, _("statistics object %s"),
3492 : : quote_qualified_identifier(nspname,
2852 3493 : 257 : NameStr(stxForm->stxname)));
3494 : :
3227 3495 : 257 : ReleaseSysCache(stxTup);
3496 : 257 : break;
3497 : : }
3498 : :
719 peter@eisentraut.org 3499 : 18 : case TSParserRelationId:
3500 : : {
3501 : : HeapTuple tup;
3502 : : Form_pg_ts_parser prsForm;
3503 : : char *nspname;
3504 : :
4743 alvherre@alvh.no-ip. 3505 : 18 : tup = SearchSysCache1(TSPARSEROID,
3506 : 18 : ObjectIdGetDatum(object->objectId));
3507 [ + + ]: 18 : if (!HeapTupleIsValid(tup))
3508 : : {
2069 michael@paquier.xyz 3509 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3510 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search parser %u",
3511 : : object->objectId);
2069 michael@paquier.xyz 3512 :CBC 3 : break;
3513 : : }
2852 tgl@sss.pgh.pa.us 3514 : 15 : prsForm = (Form_pg_ts_parser) GETSTRUCT(tup);
3515 : :
3516 : : /* Qualify the name if not visible in search path */
3517 [ + + ]: 15 : if (TSParserIsVisible(object->objectId))
3518 : 9 : nspname = NULL;
3519 : : else
3520 : 6 : nspname = get_namespace_name(prsForm->prsnamespace);
3521 : :
4743 alvherre@alvh.no-ip. 3522 : 15 : appendStringInfo(&buffer, _("text search parser %s"),
3523 : : quote_qualified_identifier(nspname,
2852 tgl@sss.pgh.pa.us 3524 : 15 : NameStr(prsForm->prsname)));
4743 alvherre@alvh.no-ip. 3525 : 15 : ReleaseSysCache(tup);
3526 : 15 : break;
3527 : : }
3528 : :
719 peter@eisentraut.org 3529 : 21 : case TSDictionaryRelationId:
3530 : : {
3531 : : HeapTuple tup;
3532 : : Form_pg_ts_dict dictForm;
3533 : : char *nspname;
3534 : :
4743 alvherre@alvh.no-ip. 3535 : 21 : tup = SearchSysCache1(TSDICTOID,
3536 : 21 : ObjectIdGetDatum(object->objectId));
3537 [ + + ]: 21 : if (!HeapTupleIsValid(tup))
3538 : : {
2069 michael@paquier.xyz 3539 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3540 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search dictionary %u",
3541 : : object->objectId);
2069 michael@paquier.xyz 3542 :CBC 3 : break;
3543 : : }
3544 : :
2852 tgl@sss.pgh.pa.us 3545 : 18 : dictForm = (Form_pg_ts_dict) GETSTRUCT(tup);
3546 : :
3547 : : /* Qualify the name if not visible in search path */
3548 [ + + ]: 18 : if (TSDictionaryIsVisible(object->objectId))
3549 : 12 : nspname = NULL;
3550 : : else
3551 : 6 : nspname = get_namespace_name(dictForm->dictnamespace);
3552 : :
4743 alvherre@alvh.no-ip. 3553 : 18 : appendStringInfo(&buffer, _("text search dictionary %s"),
3554 : : quote_qualified_identifier(nspname,
2852 tgl@sss.pgh.pa.us 3555 : 18 : NameStr(dictForm->dictname)));
4743 alvherre@alvh.no-ip. 3556 : 18 : ReleaseSysCache(tup);
3557 : 18 : break;
3558 : : }
3559 : :
719 peter@eisentraut.org 3560 : 18 : case TSTemplateRelationId:
3561 : : {
3562 : : HeapTuple tup;
3563 : : Form_pg_ts_template tmplForm;
3564 : : char *nspname;
3565 : :
4743 alvherre@alvh.no-ip. 3566 : 18 : tup = SearchSysCache1(TSTEMPLATEOID,
3567 : 18 : ObjectIdGetDatum(object->objectId));
3568 [ + + ]: 18 : if (!HeapTupleIsValid(tup))
3569 : : {
2069 michael@paquier.xyz 3570 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3571 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search template %u",
3572 : : object->objectId);
2069 michael@paquier.xyz 3573 :CBC 3 : break;
3574 : : }
3575 : :
2852 tgl@sss.pgh.pa.us 3576 : 15 : tmplForm = (Form_pg_ts_template) GETSTRUCT(tup);
3577 : :
3578 : : /* Qualify the name if not visible in search path */
3579 [ + + ]: 15 : if (TSTemplateIsVisible(object->objectId))
3580 : 9 : nspname = NULL;
3581 : : else
3582 : 6 : nspname = get_namespace_name(tmplForm->tmplnamespace);
3583 : :
4743 alvherre@alvh.no-ip. 3584 : 15 : appendStringInfo(&buffer, _("text search template %s"),
3585 : : quote_qualified_identifier(nspname,
2852 tgl@sss.pgh.pa.us 3586 : 15 : NameStr(tmplForm->tmplname)));
4743 alvherre@alvh.no-ip. 3587 : 15 : ReleaseSysCache(tup);
3588 : 15 : break;
3589 : : }
3590 : :
719 peter@eisentraut.org 3591 : 21 : case TSConfigRelationId:
3592 : : {
3593 : : HeapTuple tup;
3594 : : Form_pg_ts_config cfgForm;
3595 : : char *nspname;
3596 : :
4743 alvherre@alvh.no-ip. 3597 : 21 : tup = SearchSysCache1(TSCONFIGOID,
3598 : 21 : ObjectIdGetDatum(object->objectId));
3599 [ + + ]: 21 : if (!HeapTupleIsValid(tup))
3600 : : {
2069 michael@paquier.xyz 3601 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3602 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search configuration %u",
3603 : : object->objectId);
2069 michael@paquier.xyz 3604 :CBC 3 : break;
3605 : : }
3606 : :
2852 tgl@sss.pgh.pa.us 3607 : 18 : cfgForm = (Form_pg_ts_config) GETSTRUCT(tup);
3608 : :
3609 : : /* Qualify the name if not visible in search path */
3610 [ + + ]: 18 : if (TSConfigIsVisible(object->objectId))
3611 : 12 : nspname = NULL;
3612 : : else
3613 : 6 : nspname = get_namespace_name(cfgForm->cfgnamespace);
3614 : :
4743 alvherre@alvh.no-ip. 3615 : 18 : appendStringInfo(&buffer, _("text search configuration %s"),
3616 : : quote_qualified_identifier(nspname,
2852 tgl@sss.pgh.pa.us 3617 : 18 : NameStr(cfgForm->cfgname)));
4743 alvherre@alvh.no-ip. 3618 : 18 : ReleaseSysCache(tup);
3619 : 18 : break;
3620 : : }
3621 : :
719 peter@eisentraut.org 3622 : 83 : case AuthIdRelationId:
3623 : : {
2069 michael@paquier.xyz 3624 : 83 : char *username = GetUserNameFromId(object->objectId,
3625 : : missing_ok);
3626 : :
3627 [ + + ]: 83 : if (username)
3628 : 80 : appendStringInfo(&buffer, _("role %s"), username);
4743 alvherre@alvh.no-ip. 3629 : 83 : break;
3630 : : }
3631 : :
719 peter@eisentraut.org 3632 : 27 : case AuthMemRelationId:
3633 : : {
3634 : : Relation amDesc;
3635 : : ScanKeyData skey[1];
3636 : : SysScanDesc rcscan;
3637 : : HeapTuple tup;
3638 : : Form_pg_auth_members amForm;
3639 : :
1305 rhaas@postgresql.org 3640 : 27 : amDesc = table_open(AuthMemRelationId, AccessShareLock);
3641 : :
3642 : 27 : ScanKeyInit(&skey[0],
3643 : : Anum_pg_auth_members_oid,
3644 : : BTEqualStrategyNumber, F_OIDEQ,
3645 : 27 : ObjectIdGetDatum(object->objectId));
3646 : :
3647 : 27 : rcscan = systable_beginscan(amDesc, AuthMemOidIndexId, true,
3648 : : NULL, 1, skey);
3649 : :
3650 : 27 : tup = systable_getnext(rcscan);
3651 : :
3652 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
3653 : : {
3654 [ - + ]: 3 : if (!missing_ok)
1305 rhaas@postgresql.org 3655 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for role membership %u",
3656 : : object->objectId);
3657 : :
1305 rhaas@postgresql.org 3658 :CBC 3 : systable_endscan(rcscan);
3659 : 3 : table_close(amDesc, AccessShareLock);
3660 : 3 : break;
3661 : : }
3662 : :
3663 : 24 : amForm = (Form_pg_auth_members) GETSTRUCT(tup);
3664 : :
3665 : 24 : appendStringInfo(&buffer, _("membership of role %s in role %s"),
3666 : : GetUserNameFromId(amForm->member, false),
3667 : : GetUserNameFromId(amForm->roleid, false));
3668 : :
3669 : 24 : systable_endscan(rcscan);
3670 : 24 : table_close(amDesc, AccessShareLock);
3671 : 24 : break;
3672 : : }
3673 : :
719 peter@eisentraut.org 3674 : 9 : case DatabaseRelationId:
3675 : : {
3676 : : char *datname;
3677 : :
4743 alvherre@alvh.no-ip. 3678 : 9 : datname = get_database_name(object->objectId);
3679 [ + + ]: 9 : if (!datname)
3680 : : {
2069 michael@paquier.xyz 3681 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3682 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for database %u",
3683 : : object->objectId);
2069 michael@paquier.xyz 3684 :CBC 3 : break;
3685 : : }
4743 alvherre@alvh.no-ip. 3686 : 6 : appendStringInfo(&buffer, _("database %s"), datname);
3687 : 6 : break;
3688 : : }
3689 : :
719 peter@eisentraut.org 3690 : 3 : case TableSpaceRelationId:
3691 : : {
3692 : : char *tblspace;
3693 : :
4743 alvherre@alvh.no-ip. 3694 : 3 : tblspace = get_tablespace_name(object->objectId);
3695 [ + - ]: 3 : if (!tblspace)
3696 : : {
2069 michael@paquier.xyz 3697 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3698 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for tablespace %u",
3699 : : object->objectId);
2069 michael@paquier.xyz 3700 :CBC 3 : break;
3701 : : }
4743 alvherre@alvh.no-ip. 3702 :UBC 0 : appendStringInfo(&buffer, _("tablespace %s"), tblspace);
3703 : 0 : break;
3704 : : }
3705 : :
719 peter@eisentraut.org 3706 :CBC 37 : case ForeignDataWrapperRelationId:
3707 : : {
3708 : : ForeignDataWrapper *fdw;
3709 : :
2069 michael@paquier.xyz 3710 : 37 : fdw = GetForeignDataWrapperExtended(object->objectId,
3711 : : missing_ok);
3712 [ + + ]: 37 : if (fdw)
3713 : 34 : appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
4743 alvherre@alvh.no-ip. 3714 : 37 : break;
3715 : : }
3716 : :
719 peter@eisentraut.org 3717 : 68 : case ForeignServerRelationId:
3718 : : {
3719 : : ForeignServer *srv;
3720 : :
2069 michael@paquier.xyz 3721 : 68 : srv = GetForeignServerExtended(object->objectId, missing_ok);
3722 [ + + ]: 68 : if (srv)
3723 : 65 : appendStringInfo(&buffer, _("server %s"), srv->servername);
4743 alvherre@alvh.no-ip. 3724 : 68 : break;
3725 : : }
3726 : :
719 peter@eisentraut.org 3727 : 70 : case UserMappingRelationId:
3728 : : {
3729 : : HeapTuple tup;
3730 : : Oid useid;
3731 : : char *usename;
3732 : : Form_pg_user_mapping umform;
3733 : : ForeignServer *srv;
3734 : :
4743 alvherre@alvh.no-ip. 3735 : 70 : tup = SearchSysCache1(USERMAPPINGOID,
3736 : 70 : ObjectIdGetDatum(object->objectId));
3737 [ + + ]: 70 : if (!HeapTupleIsValid(tup))
3738 : : {
2069 michael@paquier.xyz 3739 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3740 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for user mapping %u",
3741 : : object->objectId);
2069 michael@paquier.xyz 3742 :CBC 3 : break;
3743 : : }
3744 : :
4028 alvherre@alvh.no-ip. 3745 : 67 : umform = (Form_pg_user_mapping) GETSTRUCT(tup);
3746 : 67 : useid = umform->umuser;
3747 : 67 : srv = GetForeignServer(umform->umserver);
3748 : :
4743 3749 : 67 : ReleaseSysCache(tup);
3750 : :
3751 [ + + ]: 67 : if (OidIsValid(useid))
3963 andrew@dunslane.net 3752 : 50 : usename = GetUserNameFromId(useid, false);
3753 : : else
4743 alvherre@alvh.no-ip. 3754 : 17 : usename = "public";
3755 : :
4028 3756 : 67 : appendStringInfo(&buffer, _("user mapping for %s on server %s"), usename,
3757 : : srv->servername);
4743 3758 : 67 : break;
3759 : : }
3760 : :
719 peter@eisentraut.org 3761 : 24 : case DefaultAclRelationId:
3762 : : {
3763 : : Relation defaclrel;
3764 : : ScanKeyData skey[1];
3765 : : SysScanDesc rcscan;
3766 : : HeapTuple tup;
3767 : : Form_pg_default_acl defacl;
3768 : : char *rolename;
3769 : : char *nspname;
3770 : :
2610 andres@anarazel.de 3771 : 24 : defaclrel = table_open(DefaultAclRelationId, AccessShareLock);
3772 : :
4743 alvherre@alvh.no-ip. 3773 : 24 : ScanKeyInit(&skey[0],
3774 : : Anum_pg_default_acl_oid,
3775 : : BTEqualStrategyNumber, F_OIDEQ,
3776 : 24 : ObjectIdGetDatum(object->objectId));
3777 : :
3778 : 24 : rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
3779 : : true, NULL, 1, skey);
3780 : :
3781 : 24 : tup = systable_getnext(rcscan);
3782 : :
3783 [ + + ]: 24 : if (!HeapTupleIsValid(tup))
3784 : : {
2069 michael@paquier.xyz 3785 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3786 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for default ACL %u",
3787 : : object->objectId);
3788 : :
2069 michael@paquier.xyz 3789 :CBC 3 : systable_endscan(rcscan);
3790 : 3 : table_close(defaclrel, AccessShareLock);
3791 : 3 : break;
3792 : : }
3793 : :
4743 alvherre@alvh.no-ip. 3794 : 21 : defacl = (Form_pg_default_acl) GETSTRUCT(tup);
3795 : :
2852 tgl@sss.pgh.pa.us 3796 : 21 : rolename = GetUserNameFromId(defacl->defaclrole, false);
3797 : :
3798 [ + + ]: 21 : if (OidIsValid(defacl->defaclnamespace))
3799 : 15 : nspname = get_namespace_name(defacl->defaclnamespace);
3800 : : else
3801 : 6 : nspname = NULL;
3802 : :
4743 alvherre@alvh.no-ip. 3803 [ + - + + : 21 : switch (defacl->defaclobjtype)
- - - ]
3804 : : {
3805 : 15 : case DEFACLOBJ_RELATION:
2852 tgl@sss.pgh.pa.us 3806 [ + + ]: 15 : if (nspname)
3807 : 9 : appendStringInfo(&buffer,
3808 : 9 : _("default privileges on new relations belonging to role %s in schema %s"),
3809 : : rolename, nspname);
3810 : : else
3811 : 6 : appendStringInfo(&buffer,
3812 : 6 : _("default privileges on new relations belonging to role %s"),
3813 : : rolename);
4743 alvherre@alvh.no-ip. 3814 : 15 : break;
4743 alvherre@alvh.no-ip. 3815 :UBC 0 : case DEFACLOBJ_SEQUENCE:
2852 tgl@sss.pgh.pa.us 3816 [ # # ]: 0 : if (nspname)
3817 : 0 : appendStringInfo(&buffer,
3818 : 0 : _("default privileges on new sequences belonging to role %s in schema %s"),
3819 : : rolename, nspname);
3820 : : else
3821 : 0 : appendStringInfo(&buffer,
3822 : 0 : _("default privileges on new sequences belonging to role %s"),
3823 : : rolename);
4743 alvherre@alvh.no-ip. 3824 : 0 : break;
4743 alvherre@alvh.no-ip. 3825 :CBC 3 : case DEFACLOBJ_FUNCTION:
2852 tgl@sss.pgh.pa.us 3826 [ + - ]: 3 : if (nspname)
3827 : 3 : appendStringInfo(&buffer,
3828 : 3 : _("default privileges on new functions belonging to role %s in schema %s"),
3829 : : rolename, nspname);
3830 : : else
2852 tgl@sss.pgh.pa.us 3831 :UBC 0 : appendStringInfo(&buffer,
3832 : 0 : _("default privileges on new functions belonging to role %s"),
3833 : : rolename);
4743 alvherre@alvh.no-ip. 3834 :CBC 3 : break;
3835 : 3 : case DEFACLOBJ_TYPE:
2852 tgl@sss.pgh.pa.us 3836 [ + - ]: 3 : if (nspname)
3837 : 3 : appendStringInfo(&buffer,
3838 : 3 : _("default privileges on new types belonging to role %s in schema %s"),
3839 : : rolename, nspname);
3840 : : else
2852 tgl@sss.pgh.pa.us 3841 :UBC 0 : appendStringInfo(&buffer,
3842 : 0 : _("default privileges on new types belonging to role %s"),
3843 : : rolename);
4743 alvherre@alvh.no-ip. 3844 :CBC 3 : break;
3274 teodor@sigaev.ru 3845 :UBC 0 : case DEFACLOBJ_NAMESPACE:
2852 tgl@sss.pgh.pa.us 3846 [ # # ]: 0 : Assert(!nspname);
3274 teodor@sigaev.ru 3847 : 0 : appendStringInfo(&buffer,
3848 : 0 : _("default privileges on new schemas belonging to role %s"),
3849 : : rolename);
3850 : 0 : break;
345 fujii@postgresql.org 3851 : 0 : case DEFACLOBJ_LARGEOBJECT:
3852 [ # # ]: 0 : Assert(!nspname);
3853 : 0 : appendStringInfo(&buffer,
3854 : 0 : _("default privileges on new large objects belonging to role %s"),
3855 : : rolename);
3856 : 0 : break;
4743 alvherre@alvh.no-ip. 3857 : 0 : default:
3858 : : /* shouldn't get here */
2852 tgl@sss.pgh.pa.us 3859 [ # # ]: 0 : if (nspname)
3860 : 0 : appendStringInfo(&buffer,
3861 : 0 : _("default privileges belonging to role %s in schema %s"),
3862 : : rolename, nspname);
3863 : : else
3864 : 0 : appendStringInfo(&buffer,
3865 : 0 : _("default privileges belonging to role %s"),
3866 : : rolename);
4743 alvherre@alvh.no-ip. 3867 : 0 : break;
3868 : : }
3869 : :
4743 alvherre@alvh.no-ip. 3870 :CBC 21 : systable_endscan(rcscan);
2610 andres@anarazel.de 3871 : 21 : table_close(defaclrel, AccessShareLock);
4743 alvherre@alvh.no-ip. 3872 : 21 : break;
3873 : : }
3874 : :
719 peter@eisentraut.org 3875 : 29 : case ExtensionRelationId:
3876 : : {
3877 : : char *extname;
3878 : :
4743 alvherre@alvh.no-ip. 3879 : 29 : extname = get_extension_name(object->objectId);
3880 [ + + ]: 29 : if (!extname)
3881 : : {
2069 michael@paquier.xyz 3882 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3883 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for extension %u",
3884 : : object->objectId);
2069 michael@paquier.xyz 3885 :CBC 3 : break;
3886 : : }
4743 alvherre@alvh.no-ip. 3887 : 26 : appendStringInfo(&buffer, _("extension %s"), extname);
3888 : 26 : break;
3889 : : }
3890 : :
719 peter@eisentraut.org 3891 : 19 : case EventTriggerRelationId:
3892 : : {
3893 : : HeapTuple tup;
3894 : :
4743 alvherre@alvh.no-ip. 3895 : 19 : tup = SearchSysCache1(EVENTTRIGGEROID,
3896 : 19 : ObjectIdGetDatum(object->objectId));
3897 [ + + ]: 19 : if (!HeapTupleIsValid(tup))
3898 : : {
2069 michael@paquier.xyz 3899 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3900 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for event trigger %u",
3901 : : object->objectId);
2069 michael@paquier.xyz 3902 :CBC 3 : break;
3903 : : }
4743 alvherre@alvh.no-ip. 3904 : 16 : appendStringInfo(&buffer, _("event trigger %s"),
3189 tgl@sss.pgh.pa.us 3905 : 16 : NameStr(((Form_pg_event_trigger) GETSTRUCT(tup))->evtname));
4743 alvherre@alvh.no-ip. 3906 : 16 : ReleaseSysCache(tup);
3907 : 16 : break;
3908 : : }
3909 : :
719 peter@eisentraut.org 3910 : 64 : case ParameterAclRelationId:
3911 : : {
3912 : : HeapTuple tup;
3913 : : Datum nameDatum;
3914 : : char *parname;
3915 : :
1439 tgl@sss.pgh.pa.us 3916 : 64 : tup = SearchSysCache1(PARAMETERACLOID,
3917 : 64 : ObjectIdGetDatum(object->objectId));
3918 [ + + ]: 64 : if (!HeapTupleIsValid(tup))
3919 : : {
3920 [ - + ]: 3 : if (!missing_ok)
1439 tgl@sss.pgh.pa.us 3921 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for parameter ACL %u",
3922 : : object->objectId);
1439 tgl@sss.pgh.pa.us 3923 :CBC 3 : break;
3924 : : }
1086 dgustafsson@postgres 3925 : 61 : nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
3926 : : Anum_pg_parameter_acl_parname);
1439 tgl@sss.pgh.pa.us 3927 : 61 : parname = TextDatumGetCString(nameDatum);
3928 : 61 : appendStringInfo(&buffer, _("parameter %s"), parname);
3929 : 61 : ReleaseSysCache(tup);
3930 : 61 : break;
3931 : : }
3932 : :
719 peter@eisentraut.org 3933 : 269 : case PolicyRelationId:
3934 : : {
3935 : : Relation policy_rel;
3936 : : ScanKeyData skey[1];
3937 : : SysScanDesc sscan;
3938 : : HeapTuple tuple;
3939 : : Form_pg_policy form_policy;
3940 : : StringInfoData rel;
3941 : :
2610 andres@anarazel.de 3942 : 269 : policy_rel = table_open(PolicyRelationId, AccessShareLock);
3943 : :
4195 sfrost@snowman.net 3944 : 269 : ScanKeyInit(&skey[0],
3945 : : Anum_pg_policy_oid,
3946 : : BTEqualStrategyNumber, F_OIDEQ,
3947 : 269 : ObjectIdGetDatum(object->objectId));
3948 : :
4126 3949 : 269 : sscan = systable_beginscan(policy_rel, PolicyOidIndexId,
3950 : : true, NULL, 1, skey);
3951 : :
4195 3952 : 269 : tuple = systable_getnext(sscan);
3953 : :
3954 [ + + ]: 269 : if (!HeapTupleIsValid(tuple))
3955 : : {
2069 michael@paquier.xyz 3956 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 3957 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for policy %u",
3958 : : object->objectId);
3959 : :
2069 michael@paquier.xyz 3960 :CBC 3 : systable_endscan(sscan);
3961 : 3 : table_close(policy_rel, AccessShareLock);
3962 : 3 : break;
3963 : : }
3964 : :
4126 sfrost@snowman.net 3965 : 266 : form_policy = (Form_pg_policy) GETSTRUCT(tuple);
3966 : :
2852 tgl@sss.pgh.pa.us 3967 : 266 : initStringInfo(&rel);
2069 michael@paquier.xyz 3968 : 266 : getRelationDescription(&rel, form_policy->polrelid, false);
3969 : :
3970 : : /* translator: second %s is, e.g., "table %s" */
2852 tgl@sss.pgh.pa.us 3971 : 266 : appendStringInfo(&buffer, _("policy %s on %s"),
3972 : 266 : NameStr(form_policy->polname), rel.data);
3973 : 266 : pfree(rel.data);
4195 sfrost@snowman.net 3974 : 266 : systable_endscan(sscan);
2610 andres@anarazel.de 3975 : 266 : table_close(policy_rel, AccessShareLock);
4195 sfrost@snowman.net 3976 : 266 : break;
3977 : : }
3978 : :
719 peter@eisentraut.org 3979 : 3 : case PublicationRelationId:
3980 : : {
2069 michael@paquier.xyz 3981 : 3 : char *pubname = get_publication_name(object->objectId,
3982 : : missing_ok);
3983 : :
3984 [ - + ]: 3 : if (pubname)
2069 michael@paquier.xyz 3985 :UBC 0 : appendStringInfo(&buffer, _("publication %s"), pubname);
3342 peter_e@gmx.net 3986 :CBC 3 : break;
3987 : : }
3988 : :
719 peter@eisentraut.org 3989 : 74 : case PublicationNamespaceRelationId:
3990 : : {
3991 : : char *pubname;
3992 : : char *nspname;
3993 : :
1600 akapila@postgresql.o 3994 [ + + ]: 74 : if (!getPublicationSchemaInfo(object, missing_ok,
3995 : : &pubname, &nspname))
3996 : 3 : break;
3997 : :
1438 tomas.vondra@postgre 3998 : 71 : appendStringInfo(&buffer, _("publication of schema %s in publication %s"),
3999 : : nspname, pubname);
1600 akapila@postgresql.o 4000 : 71 : pfree(pubname);
4001 : 71 : pfree(nspname);
4002 : 71 : break;
4003 : : }
4004 : :
719 peter@eisentraut.org 4005 : 234 : case PublicationRelRelationId:
4006 : : {
4007 : : HeapTuple tup;
4008 : : char *pubname;
4009 : : Form_pg_publication_rel prform;
4010 : : StringInfoData rel;
4011 : :
3342 peter_e@gmx.net 4012 : 234 : tup = SearchSysCache1(PUBLICATIONREL,
4013 : 234 : ObjectIdGetDatum(object->objectId));
4014 [ + + ]: 234 : if (!HeapTupleIsValid(tup))
4015 : : {
2069 michael@paquier.xyz 4016 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 4017 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for publication table %u",
4018 : : object->objectId);
2069 michael@paquier.xyz 4019 :CBC 3 : break;
4020 : : }
4021 : :
3342 peter_e@gmx.net 4022 : 231 : prform = (Form_pg_publication_rel) GETSTRUCT(tup);
2735 michael@paquier.xyz 4023 : 231 : pubname = get_publication_name(prform->prpubid, false);
4024 : :
2852 tgl@sss.pgh.pa.us 4025 : 231 : initStringInfo(&rel);
2069 michael@paquier.xyz 4026 : 231 : getRelationDescription(&rel, prform->prrelid, false);
4027 : :
4028 : : /* translator: first %s is, e.g., "table %s" */
2852 tgl@sss.pgh.pa.us 4029 : 231 : appendStringInfo(&buffer, _("publication of %s in publication %s"),
4030 : : rel.data, pubname);
4031 : 231 : pfree(rel.data);
3342 peter_e@gmx.net 4032 : 231 : ReleaseSysCache(tup);
4033 : 231 : break;
4034 : : }
4035 : :
719 peter@eisentraut.org 4036 : 3 : case SubscriptionRelationId:
4037 : : {
2069 michael@paquier.xyz 4038 : 3 : char *subname = get_subscription_name(object->objectId,
4039 : : missing_ok);
4040 : :
4041 [ - + ]: 3 : if (subname)
2069 michael@paquier.xyz 4042 :UBC 0 : appendStringInfo(&buffer, _("subscription %s"), subname);
3342 peter_e@gmx.net 4043 :CBC 3 : break;
4044 : : }
4045 : :
719 peter@eisentraut.org 4046 : 12 : case TransformRelationId:
4047 : : {
4048 : : HeapTuple trfTup;
4049 : : Form_pg_transform trfForm;
4050 : :
3227 tgl@sss.pgh.pa.us 4051 : 12 : trfTup = SearchSysCache1(TRFOID,
4052 : 12 : ObjectIdGetDatum(object->objectId));
4053 [ + + ]: 12 : if (!HeapTupleIsValid(trfTup))
4054 : : {
2069 michael@paquier.xyz 4055 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 4056 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for transform %u",
4057 : : object->objectId);
2069 michael@paquier.xyz 4058 :CBC 3 : break;
4059 : : }
4060 : :
3227 tgl@sss.pgh.pa.us 4061 : 9 : trfForm = (Form_pg_transform) GETSTRUCT(trfTup);
4062 : :
4063 : 9 : appendStringInfo(&buffer, _("transform for %s language %s"),
4064 : : format_type_be(trfForm->trftype),
4065 : : get_language_name(trfForm->trflang, false));
4066 : :
4067 : 9 : ReleaseSysCache(trfTup);
4068 : 9 : break;
4069 : : }
4070 : :
719 peter@eisentraut.org 4071 :UBC 0 : default:
4072 [ # # ]: 0 : elog(ERROR, "unsupported object class: %u", object->classId);
4073 : : }
4074 : :
4075 : : /* an empty buffer is equivalent to no object found */
2069 michael@paquier.xyz 4076 [ + + ]:CBC 97661 : if (buffer.len == 0)
4077 : 126 : return NULL;
4078 : :
4743 alvherre@alvh.no-ip. 4079 : 97535 : return buffer.data;
4080 : : }
4081 : :
4082 : : /*
4083 : : * getObjectDescriptionOids: as above, except the object is specified by Oids
4084 : : */
4085 : : char *
4743 alvherre@alvh.no-ip. 4086 :UBC 0 : getObjectDescriptionOids(Oid classid, Oid objid)
4087 : : {
4088 : : ObjectAddress address;
4089 : :
4090 : 0 : address.classId = classid;
4091 : 0 : address.objectId = objid;
4092 : 0 : address.objectSubId = 0;
4093 : :
2069 michael@paquier.xyz 4094 : 0 : return getObjectDescription(&address, false);
4095 : : }
4096 : :
4097 : : /*
4098 : : * subroutine for getObjectDescription: describe a relation
4099 : : *
4100 : : * The result is appended to "buffer".
4101 : : */
4102 : : static void
2069 michael@paquier.xyz 4103 :CBC 49571 : getRelationDescription(StringInfo buffer, Oid relid, bool missing_ok)
4104 : : {
4105 : : HeapTuple relTup;
4106 : : Form_pg_class relForm;
4107 : : char *nspname;
4108 : : char *relname;
4109 : :
4743 alvherre@alvh.no-ip. 4110 : 49571 : relTup = SearchSysCache1(RELOID,
4111 : : ObjectIdGetDatum(relid));
4112 [ + + ]: 49571 : if (!HeapTupleIsValid(relTup))
4113 : : {
2069 michael@paquier.xyz 4114 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 4115 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for relation %u", relid);
2069 michael@paquier.xyz 4116 :CBC 3 : return;
4117 : : }
4743 alvherre@alvh.no-ip. 4118 : 49568 : relForm = (Form_pg_class) GETSTRUCT(relTup);
4119 : :
4120 : : /* Qualify the name if not visible in search path */
4121 [ + + ]: 49568 : if (RelationIsVisible(relid))
4122 : 34960 : nspname = NULL;
4123 : : else
4124 : 14608 : nspname = get_namespace_name(relForm->relnamespace);
4125 : :
4126 : 49568 : relname = quote_qualified_identifier(nspname, NameStr(relForm->relname));
4127 : :
4128 [ + + + + : 49568 : switch (relForm->relkind)
+ + + +
- ]
4129 : : {
4130 : 27902 : case RELKIND_RELATION:
4131 : : case RELKIND_PARTITIONED_TABLE:
4132 : 27902 : appendStringInfo(buffer, _("table %s"),
4133 : : relname);
4134 : 27902 : break;
4135 : 11686 : case RELKIND_INDEX:
4136 : : case RELKIND_PARTITIONED_INDEX:
4137 : 11686 : appendStringInfo(buffer, _("index %s"),
4138 : : relname);
4139 : 11686 : break;
4140 : 453 : case RELKIND_SEQUENCE:
4141 : 453 : appendStringInfo(buffer, _("sequence %s"),
4142 : : relname);
4143 : 453 : break;
4144 : 5035 : case RELKIND_TOASTVALUE:
4145 : 5035 : appendStringInfo(buffer, _("toast table %s"),
4146 : : relname);
4147 : 5035 : break;
4148 : 1838 : case RELKIND_VIEW:
4149 : 1838 : appendStringInfo(buffer, _("view %s"),
4150 : : relname);
4151 : 1838 : break;
4152 : 298 : case RELKIND_MATVIEW:
4153 : 298 : appendStringInfo(buffer, _("materialized view %s"),
4154 : : relname);
4155 : 298 : break;
4156 : 2140 : case RELKIND_COMPOSITE_TYPE:
4157 : 2140 : appendStringInfo(buffer, _("composite type %s"),
4158 : : relname);
4159 : 2140 : break;
4160 : 216 : case RELKIND_FOREIGN_TABLE:
4161 : 216 : appendStringInfo(buffer, _("foreign table %s"),
4162 : : relname);
4163 : 216 : break;
4743 alvherre@alvh.no-ip. 4164 :UBC 0 : default:
4165 : : /* shouldn't get here */
4166 : 0 : appendStringInfo(buffer, _("relation %s"),
4167 : : relname);
4168 : 0 : break;
4169 : : }
4170 : :
4743 alvherre@alvh.no-ip. 4171 :CBC 49568 : ReleaseSysCache(relTup);
4172 : : }
4173 : :
4174 : : /*
4175 : : * subroutine for getObjectDescription: describe an operator family
4176 : : */
4177 : : static void
2069 michael@paquier.xyz 4178 : 2061 : getOpFamilyDescription(StringInfo buffer, Oid opfid, bool missing_ok)
4179 : : {
4180 : : HeapTuple opfTup;
4181 : : Form_pg_opfamily opfForm;
4182 : : HeapTuple amTup;
4183 : : Form_pg_am amForm;
4184 : : char *nspname;
4185 : :
4743 alvherre@alvh.no-ip. 4186 : 2061 : opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
4187 [ + + ]: 2061 : if (!HeapTupleIsValid(opfTup))
4188 : : {
2069 michael@paquier.xyz 4189 [ - + ]: 3 : if (!missing_ok)
2069 michael@paquier.xyz 4190 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for opfamily %u", opfid);
2069 michael@paquier.xyz 4191 :CBC 3 : return;
4192 : : }
4743 alvherre@alvh.no-ip. 4193 : 2058 : opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup);
4194 : :
4195 : 2058 : amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod));
4196 [ - + ]: 2058 : if (!HeapTupleIsValid(amTup))
4743 alvherre@alvh.no-ip. 4197 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for access method %u",
4198 : : opfForm->opfmethod);
4743 alvherre@alvh.no-ip. 4199 :CBC 2058 : amForm = (Form_pg_am) GETSTRUCT(amTup);
4200 : :
4201 : : /* Qualify the name if not visible in search path */
4202 [ + + ]: 2058 : if (OpfamilyIsVisible(opfid))
4203 : 1960 : nspname = NULL;
4204 : : else
4205 : 98 : nspname = get_namespace_name(opfForm->opfnamespace);
4206 : :
4207 : 2058 : appendStringInfo(buffer, _("operator family %s for access method %s"),
4208 : : quote_qualified_identifier(nspname,
4209 : 2058 : NameStr(opfForm->opfname)),
4210 : 2058 : NameStr(amForm->amname));
4211 : :
4212 : 2058 : ReleaseSysCache(amTup);
4213 : 2058 : ReleaseSysCache(opfTup);
4214 : : }
4215 : :
4216 : : /*
4217 : : * SQL-level callable version of getObjectDescription
4218 : : */
4219 : : Datum
4220 : 1071 : pg_describe_object(PG_FUNCTION_ARGS)
4221 : : {
4222 : 1071 : Oid classid = PG_GETARG_OID(0);
4223 : 1071 : Oid objid = PG_GETARG_OID(1);
3301 peter_e@gmx.net 4224 : 1071 : int32 objsubid = PG_GETARG_INT32(2);
4225 : : char *description;
4226 : : ObjectAddress address;
4227 : :
4228 : : /* for "pinned" items in pg_depend, return null */
4743 alvherre@alvh.no-ip. 4229 [ - + - - ]: 1071 : if (!OidIsValid(classid) && !OidIsValid(objid))
4743 alvherre@alvh.no-ip. 4230 :UBC 0 : PG_RETURN_NULL();
4231 : :
4743 alvherre@alvh.no-ip. 4232 :CBC 1071 : address.classId = classid;
4233 : 1071 : address.objectId = objid;
3301 peter_e@gmx.net 4234 : 1071 : address.objectSubId = objsubid;
4235 : :
2069 michael@paquier.xyz 4236 : 1071 : description = getObjectDescription(&address, true);
4237 : :
4238 [ + + ]: 1071 : if (description == NULL)
4239 : 126 : PG_RETURN_NULL();
4240 : :
4743 alvherre@alvh.no-ip. 4241 : 945 : PG_RETURN_TEXT_P(cstring_to_text(description));
4242 : : }
4243 : :
4244 : : /*
4245 : : * SQL-level callable function to obtain object type + identity
4246 : : */
4247 : : Datum
4248 : 1041 : pg_identify_object(PG_FUNCTION_ARGS)
4249 : : {
4250 : 1041 : Oid classid = PG_GETARG_OID(0);
4251 : 1041 : Oid objid = PG_GETARG_OID(1);
3301 peter_e@gmx.net 4252 : 1041 : int32 objsubid = PG_GETARG_INT32(2);
4743 alvherre@alvh.no-ip. 4253 : 1041 : Oid schema_oid = InvalidOid;
4254 : 1041 : const char *objname = NULL;
4255 : : char *objidentity;
4256 : : ObjectAddress address;
4257 : : Datum values[4];
4258 : : bool nulls[4];
4259 : : TupleDesc tupdesc;
4260 : : HeapTuple htup;
4261 : :
4262 : 1041 : address.classId = classid;
4263 : 1041 : address.objectId = objid;
3301 peter_e@gmx.net 4264 : 1041 : address.objectSubId = objsubid;
4265 : :
1180 michael@paquier.xyz 4266 [ - + ]: 1041 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1180 michael@paquier.xyz 4267 [ # # ]:UBC 0 : elog(ERROR, "return type must be a row type");
4268 : :
4743 alvherre@alvh.no-ip. 4269 [ + + ]:CBC 1041 : if (is_objectclass_supported(address.classId))
4270 : : {
4271 : : HeapTuple objtup;
2610 andres@anarazel.de 4272 : 971 : Relation catalog = table_open(address.classId, AccessShareLock);
4273 : :
2672 4274 : 971 : objtup = get_catalog_object_by_oid(catalog,
4275 : 971 : get_object_attnum_oid(address.classId),
4276 : : address.objectId);
4743 alvherre@alvh.no-ip. 4277 [ + + ]: 971 : if (objtup != NULL)
4278 : : {
4279 : : bool isnull;
4280 : : AttrNumber nspAttnum;
4281 : : AttrNumber nameAttnum;
4282 : :
4283 : 863 : nspAttnum = get_object_attnum_namespace(address.classId);
4284 [ + + ]: 863 : if (nspAttnum != InvalidAttrNumber)
4285 : : {
219 peter@eisentraut.org 4286 :GNC 529 : schema_oid = DatumGetObjectId(heap_getattr(objtup, nspAttnum,
4287 : : RelationGetDescr(catalog), &isnull));
4743 alvherre@alvh.no-ip. 4288 [ - + ]:CBC 529 : if (isnull)
4743 alvherre@alvh.no-ip. 4289 [ # # ]:UBC 0 : elog(ERROR, "invalid null namespace in object %u/%u/%d",
4290 : : address.classId, address.objectId, address.objectSubId);
4291 : : }
4292 : :
4293 : : /*
4294 : : * We only return the object name if it can be used (together with
4295 : : * the schema name, if any) as a unique identifier.
4296 : : */
4743 alvherre@alvh.no-ip. 4297 [ + + ]:CBC 863 : if (get_object_namensp_unique(address.classId))
4298 : : {
4299 : 572 : nameAttnum = get_object_attnum_name(address.classId);
4300 [ + - ]: 572 : if (nameAttnum != InvalidAttrNumber)
4301 : : {
4302 : : Datum nameDatum;
4303 : :
4304 : 572 : nameDatum = heap_getattr(objtup, nameAttnum,
4305 : : RelationGetDescr(catalog), &isnull);
4306 [ - + ]: 572 : if (isnull)
4743 alvherre@alvh.no-ip. 4307 [ # # ]:UBC 0 : elog(ERROR, "invalid null name in object %u/%u/%d",
4308 : : address.classId, address.objectId, address.objectSubId);
4743 alvherre@alvh.no-ip. 4309 :CBC 572 : objname = quote_identifier(NameStr(*(DatumGetName(nameDatum))));
4310 : : }
4311 : : }
4312 : : }
4313 : :
2610 andres@anarazel.de 4314 : 971 : table_close(catalog, AccessShareLock);
4315 : : }
4316 : :
4317 : : /* object type, which can never be NULL */
2069 michael@paquier.xyz 4318 : 1041 : values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
4743 alvherre@alvh.no-ip. 4319 : 1041 : nulls[0] = false;
4320 : :
4321 : : /*
4322 : : * Before doing anything, extract the object identity. If the identity
4323 : : * could not be found, set all the fields except the object type to NULL.
4324 : : */
2069 michael@paquier.xyz 4325 : 1041 : objidentity = getObjectIdentity(&address, true);
4326 : :
4327 : : /* schema name */
4328 [ + + + + ]: 1041 : if (OidIsValid(schema_oid) && objidentity)
4743 alvherre@alvh.no-ip. 4329 : 526 : {
4673 bruce@momjian.us 4330 : 526 : const char *schema = quote_identifier(get_namespace_name(schema_oid));
4331 : :
4743 alvherre@alvh.no-ip. 4332 : 526 : values[1] = CStringGetTextDatum(schema);
4333 : 526 : nulls[1] = false;
4334 : : }
4335 : : else
4336 : 515 : nulls[1] = true;
4337 : :
4338 : : /* object name */
2069 michael@paquier.xyz 4339 [ + + + + ]: 1041 : if (objname && objidentity)
4340 : : {
4743 alvherre@alvh.no-ip. 4341 : 569 : values[2] = CStringGetTextDatum(objname);
4342 : 569 : nulls[2] = false;
4343 : : }
4344 : : else
4345 : 472 : nulls[2] = true;
4346 : :
4347 : : /* object identity */
2069 michael@paquier.xyz 4348 [ + + ]: 1041 : if (objidentity)
4349 : : {
4350 : 915 : values[3] = CStringGetTextDatum(objidentity);
4351 : 915 : nulls[3] = false;
4352 : : }
4353 : : else
4354 : 126 : nulls[3] = true;
4355 : :
4743 alvherre@alvh.no-ip. 4356 : 1041 : htup = heap_form_tuple(tupdesc, values, nulls);
4357 : :
4358 : 1041 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
4359 : : }
4360 : :
4361 : : /*
4362 : : * SQL-level callable function to obtain object type + identity
4363 : : */
4364 : : Datum
4093 4365 : 286 : pg_identify_object_as_address(PG_FUNCTION_ARGS)
4366 : : {
4367 : 286 : Oid classid = PG_GETARG_OID(0);
4368 : 286 : Oid objid = PG_GETARG_OID(1);
3301 peter_e@gmx.net 4369 : 286 : int32 objsubid = PG_GETARG_INT32(2);
4370 : : ObjectAddress address;
4371 : : char *identity;
4372 : : List *names;
4373 : : List *args;
4374 : : Datum values[3];
4375 : : bool nulls[3];
4376 : : TupleDesc tupdesc;
4377 : : HeapTuple htup;
4378 : :
4093 alvherre@alvh.no-ip. 4379 : 286 : address.classId = classid;
4380 : 286 : address.objectId = objid;
3301 peter_e@gmx.net 4381 : 286 : address.objectSubId = objsubid;
4382 : :
1180 michael@paquier.xyz 4383 [ - + ]: 286 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1180 michael@paquier.xyz 4384 [ # # ]:UBC 0 : elog(ERROR, "return type must be a row type");
4385 : :
4386 : : /* object type, which can never be NULL */
2069 michael@paquier.xyz 4387 :CBC 286 : values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
4093 alvherre@alvh.no-ip. 4388 : 286 : nulls[0] = false;
4389 : :
4390 : : /* object identity */
2069 michael@paquier.xyz 4391 : 286 : identity = getObjectIdentityParts(&address, &names, &args, true);
4392 [ + + ]: 286 : if (identity == NULL)
4393 : : {
4394 : 126 : nulls[1] = true;
4395 : 126 : nulls[2] = true;
4396 : : }
4397 : : else
4398 : : {
4399 : 160 : pfree(identity);
4400 : :
4401 : : /* object_names */
4402 [ + - ]: 160 : if (names != NIL)
4403 : 160 : values[1] = PointerGetDatum(strlist_to_textarray(names));
4404 : : else
2069 michael@paquier.xyz 4405 :UBC 0 : values[1] = PointerGetDatum(construct_empty_array(TEXTOID));
2069 michael@paquier.xyz 4406 :CBC 160 : nulls[1] = false;
4407 : :
4408 : : /* object_args */
4409 [ + + ]: 160 : if (args)
4410 : 42 : values[2] = PointerGetDatum(strlist_to_textarray(args));
4411 : : else
4412 : 118 : values[2] = PointerGetDatum(construct_empty_array(TEXTOID));
4413 : 160 : nulls[2] = false;
4414 : : }
4415 : :
4093 alvherre@alvh.no-ip. 4416 : 286 : htup = heap_form_tuple(tupdesc, values, nulls);
4417 : :
4418 : 286 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
4419 : : }
4420 : :
4421 : : /*
4422 : : * SQL-level callable function to obtain the ACL of a specified object, given
4423 : : * its catalog OID, object OID and sub-object ID.
4424 : : */
4425 : : Datum
619 michael@paquier.xyz 4426 : 39 : pg_get_acl(PG_FUNCTION_ARGS)
4427 : : {
4428 : 39 : Oid classId = PG_GETARG_OID(0);
4429 : 39 : Oid objectId = PG_GETARG_OID(1);
613 4430 : 39 : int32 objsubid = PG_GETARG_INT32(2);
4431 : : Oid catalogId;
4432 : : AttrNumber Anum_acl;
4433 : : Datum datum;
4434 : : bool isnull;
4435 : : HeapTuple tup;
4436 : :
4437 : : /* for "pinned" items in pg_depend, return null */
619 4438 [ + + + - ]: 39 : if (!OidIsValid(classId) && !OidIsValid(objectId))
4439 : 3 : PG_RETURN_NULL();
4440 : :
4441 : : /* for large objects, the catalog to look at is pg_largeobject_metadata */
4442 : 36 : catalogId = (classId == LargeObjectRelationId) ?
4443 [ + - ]: 36 : LargeObjectMetadataRelationId : classId;
4444 : 36 : Anum_acl = get_object_attnum_acl(catalogId);
4445 : :
4446 : : /* return NULL if no ACL field for this catalog */
4447 [ - + ]: 36 : if (Anum_acl == InvalidAttrNumber)
619 michael@paquier.xyz 4448 :UBC 0 : PG_RETURN_NULL();
4449 : :
4450 : : /*
4451 : : * If dealing with a relation's attribute (objsubid is set), the ACL is
4452 : : * retrieved from pg_attribute.
4453 : : */
613 michael@paquier.xyz 4454 [ + - + + ]:CBC 36 : if (classId == RelationRelationId && objsubid != 0)
4455 : 24 : {
4456 : 24 : AttrNumber attnum = (AttrNumber) objsubid;
4457 : :
4458 : 24 : tup = SearchSysCacheCopyAttNum(objectId, attnum);
4459 : :
4460 [ - + ]: 24 : if (!HeapTupleIsValid(tup))
613 michael@paquier.xyz 4461 :UBC 0 : PG_RETURN_NULL();
4462 : :
613 michael@paquier.xyz 4463 :CBC 24 : datum = SysCacheGetAttr(ATTNUM, tup, Anum_pg_attribute_attacl,
4464 : : &isnull);
4465 : : }
4466 : : else
4467 : : {
4468 : : Relation rel;
4469 : :
4470 : 12 : rel = table_open(catalogId, AccessShareLock);
4471 : :
4472 : 12 : tup = get_catalog_object_by_oid(rel, get_object_attnum_oid(catalogId),
4473 : : objectId);
4474 [ + + ]: 12 : if (!HeapTupleIsValid(tup))
4475 : : {
4476 : 3 : table_close(rel, AccessShareLock);
4477 : 3 : PG_RETURN_NULL();
4478 : : }
4479 : :
4480 : 9 : datum = heap_getattr(tup, Anum_acl, RelationGetDescr(rel), &isnull);
619 4481 : 9 : table_close(rel, AccessShareLock);
4482 : : }
4483 : :
4484 [ + + ]: 33 : if (isnull)
4485 : 9 : PG_RETURN_NULL();
4486 : :
4487 : 24 : PG_RETURN_DATUM(datum);
4488 : : }
4489 : :
4490 : : /*
4491 : : * Return a palloc'ed string that describes the type of object that the
4492 : : * passed address is for.
4493 : : *
4494 : : * Keep ObjectTypeMap in sync with this.
4495 : : */
4496 : : char *
2069 4497 : 3643 : getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
4498 : : {
4499 : : StringInfoData buffer;
4500 : :
4743 alvherre@alvh.no-ip. 4501 : 3643 : initStringInfo(&buffer);
4502 : :
719 peter@eisentraut.org 4503 [ + + + + : 3643 : switch (object->classId)
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + - ]
4504 : : {
4505 : 1103 : case RelationRelationId:
4743 alvherre@alvh.no-ip. 4506 : 1103 : getRelationTypeDescription(&buffer, object->objectId,
2069 michael@paquier.xyz 4507 : 1103 : object->objectSubId,
4508 : : missing_ok);
4743 alvherre@alvh.no-ip. 4509 : 1103 : break;
4510 : :
719 peter@eisentraut.org 4511 : 158 : case ProcedureRelationId:
2069 michael@paquier.xyz 4512 : 158 : getProcedureTypeDescription(&buffer, object->objectId,
4513 : : missing_ok);
4743 alvherre@alvh.no-ip. 4514 : 158 : break;
4515 : :
719 peter@eisentraut.org 4516 : 770 : case TypeRelationId:
4518 rhaas@postgresql.org 4517 : 770 : appendStringInfoString(&buffer, "type");
4743 alvherre@alvh.no-ip. 4518 : 770 : break;
4519 : :
719 peter@eisentraut.org 4520 : 31 : case CastRelationId:
4518 rhaas@postgresql.org 4521 : 31 : appendStringInfoString(&buffer, "cast");
4743 alvherre@alvh.no-ip. 4522 : 31 : break;
4523 : :
719 peter@eisentraut.org 4524 : 27 : case CollationRelationId:
4518 rhaas@postgresql.org 4525 : 27 : appendStringInfoString(&buffer, "collation");
4743 alvherre@alvh.no-ip. 4526 : 27 : break;
4527 : :
719 peter@eisentraut.org 4528 : 312 : case ConstraintRelationId:
2069 michael@paquier.xyz 4529 : 312 : getConstraintTypeDescription(&buffer, object->objectId,
4530 : : missing_ok);
4743 alvherre@alvh.no-ip. 4531 : 312 : break;
4532 : :
719 peter@eisentraut.org 4533 : 28 : case ConversionRelationId:
4518 rhaas@postgresql.org 4534 : 28 : appendStringInfoString(&buffer, "conversion");
4743 alvherre@alvh.no-ip. 4535 : 28 : break;
4536 : :
719 peter@eisentraut.org 4537 : 242 : case AttrDefaultRelationId:
4518 rhaas@postgresql.org 4538 : 242 : appendStringInfoString(&buffer, "default value");
4743 alvherre@alvh.no-ip. 4539 : 242 : break;
4540 : :
719 peter@eisentraut.org 4541 : 27 : case LanguageRelationId:
4518 rhaas@postgresql.org 4542 : 27 : appendStringInfoString(&buffer, "language");
4743 alvherre@alvh.no-ip. 4543 : 27 : break;
4544 : :
719 peter@eisentraut.org 4545 : 6 : case LargeObjectRelationId:
4518 rhaas@postgresql.org 4546 : 6 : appendStringInfoString(&buffer, "large object");
4743 alvherre@alvh.no-ip. 4547 : 6 : break;
4548 : :
719 peter@eisentraut.org 4549 : 29 : case OperatorRelationId:
4518 rhaas@postgresql.org 4550 : 29 : appendStringInfoString(&buffer, "operator");
4743 alvherre@alvh.no-ip. 4551 : 29 : break;
4552 : :
719 peter@eisentraut.org 4553 : 31 : case OperatorClassRelationId:
4518 rhaas@postgresql.org 4554 : 31 : appendStringInfoString(&buffer, "operator class");
4743 alvherre@alvh.no-ip. 4555 : 31 : break;
4556 : :
719 peter@eisentraut.org 4557 : 32 : case OperatorFamilyRelationId:
4518 rhaas@postgresql.org 4558 : 32 : appendStringInfoString(&buffer, "operator family");
4743 alvherre@alvh.no-ip. 4559 : 32 : break;
4560 : :
719 peter@eisentraut.org 4561 : 27 : case AccessMethodRelationId:
3227 tgl@sss.pgh.pa.us 4562 : 27 : appendStringInfoString(&buffer, "access method");
4563 : 27 : break;
4564 : :
719 peter@eisentraut.org 4565 : 27 : case AccessMethodOperatorRelationId:
4518 rhaas@postgresql.org 4566 : 27 : appendStringInfoString(&buffer, "operator of access method");
4743 alvherre@alvh.no-ip. 4567 : 27 : break;
4568 : :
719 peter@eisentraut.org 4569 : 27 : case AccessMethodProcedureRelationId:
4518 rhaas@postgresql.org 4570 : 27 : appendStringInfoString(&buffer, "function of access method");
4743 alvherre@alvh.no-ip. 4571 : 27 : break;
4572 : :
719 peter@eisentraut.org 4573 : 47 : case RewriteRelationId:
4518 rhaas@postgresql.org 4574 : 47 : appendStringInfoString(&buffer, "rule");
4743 alvherre@alvh.no-ip. 4575 : 47 : break;
4576 : :
719 peter@eisentraut.org 4577 : 90 : case TriggerRelationId:
4518 rhaas@postgresql.org 4578 : 90 : appendStringInfoString(&buffer, "trigger");
4743 alvherre@alvh.no-ip. 4579 : 90 : break;
4580 : :
719 peter@eisentraut.org 4581 : 68 : case NamespaceRelationId:
4518 rhaas@postgresql.org 4582 : 68 : appendStringInfoString(&buffer, "schema");
4743 alvherre@alvh.no-ip. 4583 : 68 : break;
4584 : :
719 peter@eisentraut.org 4585 : 28 : case StatisticExtRelationId:
3227 tgl@sss.pgh.pa.us 4586 : 28 : appendStringInfoString(&buffer, "statistics object");
4587 : 28 : break;
4588 : :
719 peter@eisentraut.org 4589 : 27 : case TSParserRelationId:
4518 rhaas@postgresql.org 4590 : 27 : appendStringInfoString(&buffer, "text search parser");
4743 alvherre@alvh.no-ip. 4591 : 27 : break;
4592 : :
719 peter@eisentraut.org 4593 : 27 : case TSDictionaryRelationId:
4518 rhaas@postgresql.org 4594 : 27 : appendStringInfoString(&buffer, "text search dictionary");
4743 alvherre@alvh.no-ip. 4595 : 27 : break;
4596 : :
719 peter@eisentraut.org 4597 : 27 : case TSTemplateRelationId:
4518 rhaas@postgresql.org 4598 : 27 : appendStringInfoString(&buffer, "text search template");
4743 alvherre@alvh.no-ip. 4599 : 27 : break;
4600 : :
719 peter@eisentraut.org 4601 : 31 : case TSConfigRelationId:
4518 rhaas@postgresql.org 4602 : 31 : appendStringInfoString(&buffer, "text search configuration");
4743 alvherre@alvh.no-ip. 4603 : 31 : break;
4604 : :
719 peter@eisentraut.org 4605 : 27 : case AuthIdRelationId:
4518 rhaas@postgresql.org 4606 : 27 : appendStringInfoString(&buffer, "role");
4743 alvherre@alvh.no-ip. 4607 : 27 : break;
4608 : :
719 peter@eisentraut.org 4609 : 6 : case AuthMemRelationId:
1305 rhaas@postgresql.org 4610 : 6 : appendStringInfoString(&buffer, "role membership");
4611 : 6 : break;
4612 : :
719 peter@eisentraut.org 4613 : 6 : case DatabaseRelationId:
4518 rhaas@postgresql.org 4614 : 6 : appendStringInfoString(&buffer, "database");
4743 alvherre@alvh.no-ip. 4615 : 6 : break;
4616 : :
719 peter@eisentraut.org 4617 : 6 : case TableSpaceRelationId:
4518 rhaas@postgresql.org 4618 : 6 : appendStringInfoString(&buffer, "tablespace");
4743 alvherre@alvh.no-ip. 4619 : 6 : break;
4620 : :
719 peter@eisentraut.org 4621 : 30 : case ForeignDataWrapperRelationId:
4518 rhaas@postgresql.org 4622 : 30 : appendStringInfoString(&buffer, "foreign-data wrapper");
4743 alvherre@alvh.no-ip. 4623 : 30 : break;
4624 : :
719 peter@eisentraut.org 4625 : 30 : case ForeignServerRelationId:
4518 rhaas@postgresql.org 4626 : 30 : appendStringInfoString(&buffer, "server");
4743 alvherre@alvh.no-ip. 4627 : 30 : break;
4628 : :
719 peter@eisentraut.org 4629 : 30 : case UserMappingRelationId:
4518 rhaas@postgresql.org 4630 : 30 : appendStringInfoString(&buffer, "user mapping");
4743 alvherre@alvh.no-ip. 4631 : 30 : break;
4632 : :
719 peter@eisentraut.org 4633 : 51 : case DefaultAclRelationId:
4518 rhaas@postgresql.org 4634 : 51 : appendStringInfoString(&buffer, "default acl");
4743 alvherre@alvh.no-ip. 4635 : 51 : break;
4636 : :
719 peter@eisentraut.org 4637 : 18 : case ExtensionRelationId:
4518 rhaas@postgresql.org 4638 : 18 : appendStringInfoString(&buffer, "extension");
4743 alvherre@alvh.no-ip. 4639 : 18 : break;
4640 : :
719 peter@eisentraut.org 4641 : 24 : case EventTriggerRelationId:
4518 rhaas@postgresql.org 4642 : 24 : appendStringInfoString(&buffer, "event trigger");
4743 alvherre@alvh.no-ip. 4643 : 24 : break;
4644 : :
719 peter@eisentraut.org 4645 : 8 : case ParameterAclRelationId:
1439 tgl@sss.pgh.pa.us 4646 : 8 : appendStringInfoString(&buffer, "parameter ACL");
4647 : 8 : break;
4648 : :
719 peter@eisentraut.org 4649 : 48 : case PolicyRelationId:
4126 sfrost@snowman.net 4650 : 48 : appendStringInfoString(&buffer, "policy");
4651 : 48 : break;
4652 : :
719 peter@eisentraut.org 4653 : 27 : case PublicationRelationId:
3342 peter_e@gmx.net 4654 : 27 : appendStringInfoString(&buffer, "publication");
4655 : 27 : break;
4656 : :
719 peter@eisentraut.org 4657 : 27 : case PublicationNamespaceRelationId:
1600 akapila@postgresql.o 4658 : 27 : appendStringInfoString(&buffer, "publication namespace");
4659 : 27 : break;
4660 : :
719 peter@eisentraut.org 4661 : 27 : case PublicationRelRelationId:
3335 peter_e@gmx.net 4662 : 27 : appendStringInfoString(&buffer, "publication relation");
3342 4663 : 27 : break;
4664 : :
719 peter@eisentraut.org 4665 : 27 : case SubscriptionRelationId:
3342 peter_e@gmx.net 4666 : 27 : appendStringInfoString(&buffer, "subscription");
4667 : 27 : break;
4668 : :
719 peter@eisentraut.org 4669 : 29 : case TransformRelationId:
3227 tgl@sss.pgh.pa.us 4670 : 29 : appendStringInfoString(&buffer, "transform");
3278 alvherre@alvh.no-ip. 4671 : 29 : break;
4672 : :
719 peter@eisentraut.org 4673 :UBC 0 : default:
4674 [ # # ]: 0 : elog(ERROR, "unsupported object class: %u", object->classId);
4675 : : }
4676 : :
4677 : : /* the result can never be empty */
1737 michael@paquier.xyz 4678 [ - + ]:CBC 3643 : Assert(buffer.len > 0);
4679 : :
4743 alvherre@alvh.no-ip. 4680 : 3643 : return buffer.data;
4681 : : }
4682 : :
4683 : : /*
4684 : : * subroutine for getObjectTypeDescription: describe a relation type
4685 : : */
4686 : : static void
2069 michael@paquier.xyz 4687 : 1103 : getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId,
4688 : : bool missing_ok)
4689 : : {
4690 : : HeapTuple relTup;
4691 : : Form_pg_class relForm;
4692 : :
4743 alvherre@alvh.no-ip. 4693 : 1103 : relTup = SearchSysCache1(RELOID,
4694 : : ObjectIdGetDatum(relid));
4695 [ + + ]: 1103 : if (!HeapTupleIsValid(relTup))
4696 : : {
2069 michael@paquier.xyz 4697 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 4698 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for relation %u", relid);
4699 : :
4700 : : /* fallback to "relation" for an undefined object */
2069 michael@paquier.xyz 4701 :CBC 6 : appendStringInfoString(buffer, "relation");
4702 : 6 : return;
4703 : : }
4743 alvherre@alvh.no-ip. 4704 : 1097 : relForm = (Form_pg_class) GETSTRUCT(relTup);
4705 : :
4706 [ + + + + : 1097 : switch (relForm->relkind)
+ + + +
- ]
4707 : : {
4708 : 478 : case RELKIND_RELATION:
4709 : : case RELKIND_PARTITIONED_TABLE:
4518 rhaas@postgresql.org 4710 : 478 : appendStringInfoString(buffer, "table");
4743 alvherre@alvh.no-ip. 4711 : 478 : break;
4712 : 342 : case RELKIND_INDEX:
4713 : : case RELKIND_PARTITIONED_INDEX:
4518 rhaas@postgresql.org 4714 : 342 : appendStringInfoString(buffer, "index");
4743 alvherre@alvh.no-ip. 4715 : 342 : break;
4716 : 94 : case RELKIND_SEQUENCE:
4518 rhaas@postgresql.org 4717 : 94 : appendStringInfoString(buffer, "sequence");
4743 alvherre@alvh.no-ip. 4718 : 94 : break;
4719 : 51 : case RELKIND_TOASTVALUE:
4518 rhaas@postgresql.org 4720 : 51 : appendStringInfoString(buffer, "toast table");
4743 alvherre@alvh.no-ip. 4721 : 51 : break;
4722 : 56 : case RELKIND_VIEW:
4518 rhaas@postgresql.org 4723 : 56 : appendStringInfoString(buffer, "view");
4743 alvherre@alvh.no-ip. 4724 : 56 : break;
4725 : 30 : case RELKIND_MATVIEW:
4518 rhaas@postgresql.org 4726 : 30 : appendStringInfoString(buffer, "materialized view");
4743 alvherre@alvh.no-ip. 4727 : 30 : break;
4728 : 1 : case RELKIND_COMPOSITE_TYPE:
4518 rhaas@postgresql.org 4729 : 1 : appendStringInfoString(buffer, "composite type");
4743 alvherre@alvh.no-ip. 4730 : 1 : break;
4731 : 45 : case RELKIND_FOREIGN_TABLE:
4518 rhaas@postgresql.org 4732 : 45 : appendStringInfoString(buffer, "foreign table");
4743 alvherre@alvh.no-ip. 4733 : 45 : break;
4743 alvherre@alvh.no-ip. 4734 :UBC 0 : default:
4735 : : /* shouldn't get here */
4518 rhaas@postgresql.org 4736 : 0 : appendStringInfoString(buffer, "relation");
4743 alvherre@alvh.no-ip. 4737 : 0 : break;
4738 : : }
4739 : :
4743 alvherre@alvh.no-ip. 4740 [ + + ]:CBC 1097 : if (objectSubId != 0)
4518 rhaas@postgresql.org 4741 : 64 : appendStringInfoString(buffer, " column");
4742 : :
4743 alvherre@alvh.no-ip. 4743 : 1097 : ReleaseSysCache(relTup);
4744 : : }
4745 : :
4746 : : /*
4747 : : * subroutine for getObjectTypeDescription: describe a constraint type
4748 : : */
4749 : : static void
2069 michael@paquier.xyz 4750 : 312 : getConstraintTypeDescription(StringInfo buffer, Oid constroid, bool missing_ok)
4751 : : {
4752 : : Relation constrRel;
4753 : : HeapTuple constrTup;
4754 : : Form_pg_constraint constrForm;
4755 : :
2610 andres@anarazel.de 4756 : 312 : constrRel = table_open(ConstraintRelationId, AccessShareLock);
2672 4757 : 312 : constrTup = get_catalog_object_by_oid(constrRel, Anum_pg_constraint_oid,
4758 : : constroid);
4743 alvherre@alvh.no-ip. 4759 [ + + ]: 312 : if (!HeapTupleIsValid(constrTup))
4760 : : {
2069 michael@paquier.xyz 4761 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 4762 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for constraint %u", constroid);
4763 : :
2069 michael@paquier.xyz 4764 :CBC 6 : table_close(constrRel, AccessShareLock);
4765 : :
4766 : : /* fallback to "constraint" for an undefined object */
4767 : 6 : appendStringInfoString(buffer, "constraint");
4768 : 6 : return;
4769 : : }
4770 : :
4743 alvherre@alvh.no-ip. 4771 : 306 : constrForm = (Form_pg_constraint) GETSTRUCT(constrTup);
4772 : :
4773 [ + + ]: 306 : if (OidIsValid(constrForm->conrelid))
4774 : 267 : appendStringInfoString(buffer, "table constraint");
4775 [ + - ]: 39 : else if (OidIsValid(constrForm->contypid))
4776 : 39 : appendStringInfoString(buffer, "domain constraint");
4777 : : else
2672 andres@anarazel.de 4778 [ # # ]:UBC 0 : elog(ERROR, "invalid constraint %u", constrForm->oid);
4779 : :
2610 andres@anarazel.de 4780 :CBC 306 : table_close(constrRel, AccessShareLock);
4781 : : }
4782 : :
4783 : : /*
4784 : : * subroutine for getObjectTypeDescription: describe a procedure type
4785 : : */
4786 : : static void
2069 michael@paquier.xyz 4787 : 158 : getProcedureTypeDescription(StringInfo buffer, Oid procid,
4788 : : bool missing_ok)
4789 : : {
4790 : : HeapTuple procTup;
4791 : : Form_pg_proc procForm;
4792 : :
4743 alvherre@alvh.no-ip. 4793 : 158 : procTup = SearchSysCache1(PROCOID,
4794 : : ObjectIdGetDatum(procid));
4795 [ + + ]: 158 : if (!HeapTupleIsValid(procTup))
4796 : : {
2069 michael@paquier.xyz 4797 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 4798 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for procedure %u", procid);
4799 : :
4800 : : /* fallback to "procedure" for an undefined object */
2069 michael@paquier.xyz 4801 :CBC 6 : appendStringInfoString(buffer, "routine");
4802 : 6 : return;
4803 : : }
4743 alvherre@alvh.no-ip. 4804 : 152 : procForm = (Form_pg_proc) GETSTRUCT(procTup);
4805 : :
2935 peter_e@gmx.net 4806 [ + + ]: 152 : if (procForm->prokind == PROKIND_AGGREGATE)
4518 rhaas@postgresql.org 4807 : 30 : appendStringInfoString(buffer, "aggregate");
2935 peter_e@gmx.net 4808 [ + + ]: 122 : else if (procForm->prokind == PROKIND_PROCEDURE)
3027 4809 : 24 : appendStringInfoString(buffer, "procedure");
4810 : : else /* function or window function */
4518 rhaas@postgresql.org 4811 : 98 : appendStringInfoString(buffer, "function");
4812 : :
4743 alvherre@alvh.no-ip. 4813 : 152 : ReleaseSysCache(procTup);
4814 : : }
4815 : :
4816 : : /*
4817 : : * Obtain a given object's identity, as a palloc'ed string.
4818 : : *
4819 : : * This is for machine consumption, so it's not translated. All elements are
4820 : : * schema-qualified when appropriate. Returns NULL if the object could not
4821 : : * be found.
4822 : : */
4823 : : char *
2069 michael@paquier.xyz 4824 : 1389 : getObjectIdentity(const ObjectAddress *object, bool missing_ok)
4825 : : {
4826 : 1389 : return getObjectIdentityParts(object, NULL, NULL, missing_ok);
4827 : : }
4828 : :
4829 : : /*
4830 : : * As above, but more detailed.
4831 : : *
4832 : : * There are two sets of return values: the identity itself as a palloc'd
4833 : : * string is returned. objname and objargs, if not NULL, are output parameters
4834 : : * that receive lists of C-strings that are useful to give back to
4835 : : * get_object_address() to reconstruct the ObjectAddress. Returns NULL if
4836 : : * the object could not be found.
4837 : : */
4838 : : char *
4093 alvherre@alvh.no-ip. 4839 : 3921 : getObjectIdentityParts(const ObjectAddress *object,
4840 : : List **objname, List **objargs,
4841 : : bool missing_ok)
4842 : : {
4843 : : StringInfoData buffer;
4844 : :
4743 4845 : 3921 : initStringInfo(&buffer);
4846 : :
4847 : : /*
4848 : : * Make sure that both objname and objargs were passed, or none was; and
4849 : : * initialize them to empty lists. For objname this is useless because it
4850 : : * will be initialized in all cases inside the switch; but we do it anyway
4851 : : * so that we can test below that no branch leaves it unset.
4852 : : */
172 peter@eisentraut.org 4853 [ - + ]:GNC 3921 : Assert((objname != NULL) == (objargs != NULL));
4093 alvherre@alvh.no-ip. 4854 [ + + ]:CBC 3921 : if (objname)
4855 : : {
4856 : 2496 : *objname = NIL;
4857 : 2496 : *objargs = NIL;
4858 : : }
4859 : :
719 peter@eisentraut.org 4860 [ + + + + : 3921 : switch (object->classId)
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + - ]
4861 : : {
4862 : 1342 : case RelationRelationId:
4863 : : {
2069 michael@paquier.xyz 4864 : 1342 : char *attr = NULL;
4865 : :
4866 : : /*
4867 : : * Check for the attribute first, so as if it is missing we
4868 : : * can skip the entire relation description.
4869 : : */
4870 [ + + ]: 1342 : if (object->objectSubId != 0)
4871 : : {
4872 : 300 : attr = get_attname(object->objectId,
4873 : 300 : object->objectSubId,
4874 : : missing_ok);
4875 : :
4876 [ + + + + ]: 300 : if (missing_ok && attr == NULL)
4877 : 6 : break;
4878 : : }
4879 : :
4880 : 1336 : getRelationIdentity(&buffer, object->objectId, objname,
4881 : : missing_ok);
4882 [ + + + + ]: 1336 : if (objname && *objname == NIL)
4883 : 3 : break;
4884 : :
4885 [ + + ]: 1333 : if (attr)
4886 : : {
4887 : 294 : appendStringInfo(&buffer, ".%s",
4888 : : quote_identifier(attr));
4889 [ + + ]: 294 : if (objname)
4890 : 239 : *objname = lappend(*objname, attr);
4891 : : }
4892 : : }
4743 alvherre@alvh.no-ip. 4893 : 1333 : break;
4894 : :
719 peter@eisentraut.org 4895 : 158 : case ProcedureRelationId:
4896 : : {
2069 michael@paquier.xyz 4897 : 158 : bits16 flags = FORMAT_PROC_FORCE_QUALIFY | FORMAT_PROC_INVALID_AS_NULL;
4898 : 158 : char *proname = format_procedure_extended(object->objectId,
4899 : : flags);
4900 : :
4901 [ + + ]: 158 : if (proname == NULL)
4902 : 6 : break;
4903 : :
4904 : 152 : appendStringInfoString(&buffer, proname);
4905 [ + + ]: 152 : if (objname)
4906 : 68 : format_procedure_parts(object->objectId, objname, objargs,
4907 : : missing_ok);
4908 : 152 : break;
4909 : : }
4910 : :
719 peter@eisentraut.org 4911 : 809 : case TypeRelationId:
4912 : : {
2069 michael@paquier.xyz 4913 : 809 : bits16 flags = FORMAT_TYPE_INVALID_AS_NULL | FORMAT_TYPE_FORCE_QUALIFY;
4914 : : char *typeout;
4915 : :
4916 : 809 : typeout = format_type_extended(object->objectId, -1, flags);
4917 : :
4918 [ + + ]: 809 : if (typeout == NULL)
4919 : 6 : break;
4920 : :
4093 alvherre@alvh.no-ip. 4921 : 803 : appendStringInfoString(&buffer, typeout);
4922 [ + + ]: 803 : if (objname)
4923 : 695 : *objname = list_make1(typeout);
4924 : : }
4743 4925 : 803 : break;
4926 : :
719 peter@eisentraut.org 4927 : 31 : case CastRelationId:
4928 : : {
4929 : : Relation castRel;
4930 : : HeapTuple tup;
4931 : : Form_pg_cast castForm;
4932 : :
2610 andres@anarazel.de 4933 : 31 : castRel = table_open(CastRelationId, AccessShareLock);
4934 : :
2672 4935 : 31 : tup = get_catalog_object_by_oid(castRel, Anum_pg_cast_oid,
4936 : 31 : object->objectId);
4937 : :
4743 alvherre@alvh.no-ip. 4938 [ + + ]: 31 : if (!HeapTupleIsValid(tup))
4939 : : {
2069 michael@paquier.xyz 4940 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 4941 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for cast %u",
4942 : : object->objectId);
4943 : :
2069 michael@paquier.xyz 4944 :CBC 6 : table_close(castRel, AccessShareLock);
4945 : 6 : break;
4946 : : }
4947 : :
4743 alvherre@alvh.no-ip. 4948 : 25 : castForm = (Form_pg_cast) GETSTRUCT(tup);
4949 : :
4950 : 25 : appendStringInfo(&buffer, "(%s AS %s)",
4951 : : format_type_be_qualified(castForm->castsource),
4952 : : format_type_be_qualified(castForm->casttarget));
4953 : :
4093 4954 [ + + ]: 25 : if (objname)
4955 : : {
4956 : 3 : *objname = list_make1(format_type_be_qualified(castForm->castsource));
4957 : 3 : *objargs = list_make1(format_type_be_qualified(castForm->casttarget));
4958 : : }
4959 : :
2610 andres@anarazel.de 4960 : 25 : table_close(castRel, AccessShareLock);
4743 alvherre@alvh.no-ip. 4961 : 25 : break;
4962 : : }
4963 : :
719 peter@eisentraut.org 4964 : 27 : case CollationRelationId:
4965 : : {
4966 : : HeapTuple collTup;
4967 : : Form_pg_collation coll;
4968 : : char *schema;
4969 : :
4743 alvherre@alvh.no-ip. 4970 : 27 : collTup = SearchSysCache1(COLLOID,
4971 : 27 : ObjectIdGetDatum(object->objectId));
4972 [ + + ]: 27 : if (!HeapTupleIsValid(collTup))
4973 : : {
2069 michael@paquier.xyz 4974 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 4975 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for collation %u",
4976 : : object->objectId);
2069 michael@paquier.xyz 4977 :CBC 6 : break;
4978 : : }
4743 alvherre@alvh.no-ip. 4979 : 21 : coll = (Form_pg_collation) GETSTRUCT(collTup);
3996 4980 : 21 : schema = get_namespace_name_or_temp(coll->collnamespace);
4743 4981 : 21 : appendStringInfoString(&buffer,
4982 : 21 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 4983 : 21 : NameStr(coll->collname)));
4093 alvherre@alvh.no-ip. 4984 [ + + ]: 21 : if (objname)
4092 4985 : 3 : *objname = list_make2(schema,
4986 : : pstrdup(NameStr(coll->collname)));
4743 4987 : 21 : ReleaseSysCache(collTup);
4988 : 21 : break;
4989 : : }
4990 : :
719 peter@eisentraut.org 4991 : 312 : case ConstraintRelationId:
4992 : : {
4993 : : HeapTuple conTup;
4994 : : Form_pg_constraint con;
4995 : :
4743 alvherre@alvh.no-ip. 4996 : 312 : conTup = SearchSysCache1(CONSTROID,
4997 : 312 : ObjectIdGetDatum(object->objectId));
4998 [ + + ]: 312 : if (!HeapTupleIsValid(conTup))
4999 : : {
2069 michael@paquier.xyz 5000 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5001 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for constraint %u",
5002 : : object->objectId);
2069 michael@paquier.xyz 5003 :CBC 6 : break;
5004 : : }
4743 alvherre@alvh.no-ip. 5005 : 306 : con = (Form_pg_constraint) GETSTRUCT(conTup);
5006 : :
5007 [ + + ]: 306 : if (OidIsValid(con->conrelid))
5008 : : {
5009 : 267 : appendStringInfo(&buffer, "%s on ",
5010 : 267 : quote_identifier(NameStr(con->conname)));
2069 michael@paquier.xyz 5011 : 267 : getRelationIdentity(&buffer, con->conrelid, objname,
5012 : : false);
4093 alvherre@alvh.no-ip. 5013 [ + + ]: 267 : if (objname)
5014 : 249 : *objname = lappend(*objname, pstrdup(NameStr(con->conname)));
5015 : : }
5016 : : else
5017 : : {
5018 : : ObjectAddress domain;
5019 : :
5020 [ - + ]: 39 : Assert(OidIsValid(con->contypid));
4743 5021 : 39 : domain.classId = TypeRelationId;
5022 : 39 : domain.objectId = con->contypid;
5023 : 39 : domain.objectSubId = 0;
5024 : :
5025 : 78 : appendStringInfo(&buffer, "%s on %s",
5026 : 39 : quote_identifier(NameStr(con->conname)),
5027 : : getObjectIdentityParts(&domain, objname,
5028 : : objargs, false));
5029 : :
4093 5030 [ + + ]: 39 : if (objname)
5031 : 21 : *objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
5032 : : }
5033 : :
4743 5034 : 306 : ReleaseSysCache(conTup);
5035 : 306 : break;
5036 : : }
5037 : :
719 peter@eisentraut.org 5038 : 28 : case ConversionRelationId:
5039 : : {
5040 : : HeapTuple conTup;
5041 : : Form_pg_conversion conForm;
5042 : : char *schema;
5043 : :
4743 alvherre@alvh.no-ip. 5044 : 28 : conTup = SearchSysCache1(CONVOID,
5045 : 28 : ObjectIdGetDatum(object->objectId));
5046 [ + + ]: 28 : if (!HeapTupleIsValid(conTup))
5047 : : {
2069 michael@paquier.xyz 5048 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5049 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for conversion %u",
5050 : : object->objectId);
2069 michael@paquier.xyz 5051 :CBC 6 : break;
5052 : : }
4743 alvherre@alvh.no-ip. 5053 : 22 : conForm = (Form_pg_conversion) GETSTRUCT(conTup);
3996 5054 : 22 : schema = get_namespace_name_or_temp(conForm->connamespace);
4518 rhaas@postgresql.org 5055 : 22 : appendStringInfoString(&buffer,
3949 bruce@momjian.us 5056 : 22 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 5057 : 22 : NameStr(conForm->conname)));
4093 alvherre@alvh.no-ip. 5058 [ + + ]: 22 : if (objname)
3996 5059 : 3 : *objname = list_make2(schema,
5060 : : pstrdup(NameStr(conForm->conname)));
4743 5061 : 22 : ReleaseSysCache(conTup);
5062 : 22 : break;
5063 : : }
5064 : :
719 peter@eisentraut.org 5065 : 242 : case AttrDefaultRelationId:
5066 : : {
5067 : : ObjectAddress colobject;
5068 : :
1455 tgl@sss.pgh.pa.us 5069 : 242 : colobject = GetAttrDefaultColumnAddress(object->objectId);
5070 : :
5071 [ + + ]: 242 : if (!OidIsValid(colobject.objectId))
5072 : : {
2069 michael@paquier.xyz 5073 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5074 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for attrdef %u",
5075 : : object->objectId);
2069 michael@paquier.xyz 5076 :CBC 6 : break;
5077 : : }
5078 : :
4743 alvherre@alvh.no-ip. 5079 : 236 : appendStringInfo(&buffer, "for %s",
5080 : : getObjectIdentityParts(&colobject,
5081 : : objname, objargs,
5082 : : false));
5083 : 236 : break;
5084 : : }
5085 : :
719 peter@eisentraut.org 5086 : 27 : case LanguageRelationId:
5087 : : {
5088 : : HeapTuple langTup;
5089 : : Form_pg_language langForm;
5090 : :
4743 alvherre@alvh.no-ip. 5091 : 27 : langTup = SearchSysCache1(LANGOID,
5092 : 27 : ObjectIdGetDatum(object->objectId));
5093 [ + + ]: 27 : if (!HeapTupleIsValid(langTup))
5094 : : {
2069 michael@paquier.xyz 5095 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5096 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for language %u",
5097 : : object->objectId);
2069 michael@paquier.xyz 5098 :CBC 6 : break;
5099 : : }
4743 alvherre@alvh.no-ip. 5100 : 21 : langForm = (Form_pg_language) GETSTRUCT(langTup);
4518 rhaas@postgresql.org 5101 : 21 : appendStringInfoString(&buffer,
3189 tgl@sss.pgh.pa.us 5102 : 21 : quote_identifier(NameStr(langForm->lanname)));
4093 alvherre@alvh.no-ip. 5103 [ + + ]: 21 : if (objname)
5104 : 3 : *objname = list_make1(pstrdup(NameStr(langForm->lanname)));
4743 5105 : 21 : ReleaseSysCache(langTup);
5106 : 21 : break;
5107 : : }
5108 : :
719 peter@eisentraut.org 5109 : 6 : case LargeObjectRelationId:
2069 michael@paquier.xyz 5110 [ + - ]: 6 : if (!LargeObjectExists(object->objectId))
5111 : 6 : break;
4743 alvherre@alvh.no-ip. 5112 :UBC 0 : appendStringInfo(&buffer, "%u",
5113 : 0 : object->objectId);
4093 5114 [ # # ]: 0 : if (objname)
5115 : 0 : *objname = list_make1(psprintf("%u", object->objectId));
4743 5116 : 0 : break;
5117 : :
719 peter@eisentraut.org 5118 :CBC 29 : case OperatorRelationId:
5119 : : {
2069 michael@paquier.xyz 5120 : 29 : bits16 flags = FORMAT_OPERATOR_FORCE_QUALIFY | FORMAT_OPERATOR_INVALID_AS_NULL;
5121 : 29 : char *oprname = format_operator_extended(object->objectId,
5122 : : flags);
5123 : :
5124 [ + + ]: 29 : if (oprname == NULL)
5125 : 6 : break;
5126 : :
5127 : 23 : appendStringInfoString(&buffer, oprname);
5128 [ + + ]: 23 : if (objname)
5129 : 3 : format_operator_parts(object->objectId, objname, objargs, missing_ok);
5130 : 23 : break;
5131 : : }
5132 : :
719 peter@eisentraut.org 5133 : 31 : case OperatorClassRelationId:
5134 : : {
5135 : : HeapTuple opcTup;
5136 : : Form_pg_opclass opcForm;
5137 : : HeapTuple amTup;
5138 : : Form_pg_am amForm;
5139 : : char *schema;
5140 : :
4743 alvherre@alvh.no-ip. 5141 : 31 : opcTup = SearchSysCache1(CLAOID,
5142 : 31 : ObjectIdGetDatum(object->objectId));
5143 [ + + ]: 31 : if (!HeapTupleIsValid(opcTup))
5144 : : {
2069 michael@paquier.xyz 5145 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5146 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for opclass %u",
5147 : : object->objectId);
2069 michael@paquier.xyz 5148 :CBC 6 : break;
5149 : : }
4743 alvherre@alvh.no-ip. 5150 : 25 : opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
3996 5151 : 25 : schema = get_namespace_name_or_temp(opcForm->opcnamespace);
5152 : :
4743 5153 : 25 : amTup = SearchSysCache1(AMOID,
5154 : : ObjectIdGetDatum(opcForm->opcmethod));
5155 [ - + ]: 25 : if (!HeapTupleIsValid(amTup))
4743 alvherre@alvh.no-ip. 5156 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for access method %u",
5157 : : opcForm->opcmethod);
4743 alvherre@alvh.no-ip. 5158 :CBC 25 : amForm = (Form_pg_am) GETSTRUCT(amTup);
5159 : :
4017 5160 : 25 : appendStringInfo(&buffer, "%s USING %s",
5161 : : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 5162 : 25 : NameStr(opcForm->opcname)),
4743 alvherre@alvh.no-ip. 5163 : 25 : quote_identifier(NameStr(amForm->amname)));
4093 5164 [ + + ]: 25 : if (objname)
4017 5165 : 3 : *objname = list_make3(pstrdup(NameStr(amForm->amname)),
5166 : : schema,
5167 : : pstrdup(NameStr(opcForm->opcname)));
5168 : :
4743 5169 : 25 : ReleaseSysCache(amTup);
5170 : 25 : ReleaseSysCache(opcTup);
5171 : 25 : break;
5172 : : }
5173 : :
719 peter@eisentraut.org 5174 : 32 : case OperatorFamilyRelationId:
2069 michael@paquier.xyz 5175 : 32 : getOpFamilyIdentity(&buffer, object->objectId, objname,
5176 : : missing_ok);
4743 alvherre@alvh.no-ip. 5177 : 32 : break;
5178 : :
719 peter@eisentraut.org 5179 : 27 : case AccessMethodRelationId:
5180 : : {
5181 : : char *amname;
5182 : :
3227 tgl@sss.pgh.pa.us 5183 : 27 : amname = get_am_name(object->objectId);
5184 [ + + ]: 27 : if (!amname)
5185 : : {
2069 michael@paquier.xyz 5186 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5187 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for access method %u",
5188 : : object->objectId);
2069 michael@paquier.xyz 5189 :CBC 6 : break;
5190 : : }
3227 tgl@sss.pgh.pa.us 5191 : 21 : appendStringInfoString(&buffer, quote_identifier(amname));
5192 [ + + ]: 21 : if (objname)
5193 : 3 : *objname = list_make1(amname);
5194 : : }
5195 : 21 : break;
5196 : :
719 peter@eisentraut.org 5197 : 27 : case AccessMethodOperatorRelationId:
5198 : : {
5199 : : Relation amopDesc;
5200 : : HeapTuple tup;
5201 : : ScanKeyData skey[1];
5202 : : SysScanDesc amscan;
5203 : : Form_pg_amop amopForm;
5204 : : StringInfoData opfam;
5205 : : char *ltype;
5206 : : char *rtype;
5207 : :
2610 andres@anarazel.de 5208 : 27 : amopDesc = table_open(AccessMethodOperatorRelationId,
5209 : : AccessShareLock);
5210 : :
4743 alvherre@alvh.no-ip. 5211 : 27 : ScanKeyInit(&skey[0],
5212 : : Anum_pg_amop_oid,
5213 : : BTEqualStrategyNumber, F_OIDEQ,
5214 : 27 : ObjectIdGetDatum(object->objectId));
5215 : :
5216 : 27 : amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true,
5217 : : NULL, 1, skey);
5218 : :
5219 : 27 : tup = systable_getnext(amscan);
5220 : :
5221 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
5222 : : {
2069 michael@paquier.xyz 5223 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5224 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for amop entry %u",
5225 : : object->objectId);
5226 : :
2069 michael@paquier.xyz 5227 :CBC 6 : systable_endscan(amscan);
5228 : 6 : table_close(amopDesc, AccessShareLock);
5229 : 6 : break;
5230 : : }
5231 : :
4743 alvherre@alvh.no-ip. 5232 : 21 : amopForm = (Form_pg_amop) GETSTRUCT(tup);
5233 : :
5234 : 21 : initStringInfo(&opfam);
2069 michael@paquier.xyz 5235 : 21 : getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname,
5236 : : false);
5237 : :
4017 alvherre@alvh.no-ip. 5238 : 21 : ltype = format_type_be_qualified(amopForm->amoplefttype);
5239 : 21 : rtype = format_type_be_qualified(amopForm->amoprighttype);
5240 : :
5241 [ + + ]: 21 : if (objname)
5242 : : {
5243 : 3 : *objname = lappend(*objname,
3189 tgl@sss.pgh.pa.us 5244 : 3 : psprintf("%d", amopForm->amopstrategy));
4017 alvherre@alvh.no-ip. 5245 : 3 : *objargs = list_make2(ltype, rtype);
5246 : : }
5247 : :
4743 5248 : 21 : appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
5249 : 21 : amopForm->amopstrategy,
5250 : : ltype, rtype, opfam.data);
5251 : :
5252 : 21 : pfree(opfam.data);
5253 : :
5254 : 21 : systable_endscan(amscan);
2610 andres@anarazel.de 5255 : 21 : table_close(amopDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 5256 : 21 : break;
5257 : : }
5258 : :
719 peter@eisentraut.org 5259 : 27 : case AccessMethodProcedureRelationId:
5260 : : {
5261 : : Relation amprocDesc;
5262 : : ScanKeyData skey[1];
5263 : : SysScanDesc amscan;
5264 : : HeapTuple tup;
5265 : : Form_pg_amproc amprocForm;
5266 : : StringInfoData opfam;
5267 : : char *ltype;
5268 : : char *rtype;
5269 : :
2610 andres@anarazel.de 5270 : 27 : amprocDesc = table_open(AccessMethodProcedureRelationId,
5271 : : AccessShareLock);
5272 : :
4743 alvherre@alvh.no-ip. 5273 : 27 : ScanKeyInit(&skey[0],
5274 : : Anum_pg_amproc_oid,
5275 : : BTEqualStrategyNumber, F_OIDEQ,
5276 : 27 : ObjectIdGetDatum(object->objectId));
5277 : :
5278 : 27 : amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true,
5279 : : NULL, 1, skey);
5280 : :
5281 : 27 : tup = systable_getnext(amscan);
5282 : :
5283 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
5284 : : {
2069 michael@paquier.xyz 5285 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5286 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for amproc entry %u",
5287 : : object->objectId);
5288 : :
2069 michael@paquier.xyz 5289 :CBC 6 : systable_endscan(amscan);
5290 : 6 : table_close(amprocDesc, AccessShareLock);
5291 : 6 : break;
5292 : : }
5293 : :
4743 alvherre@alvh.no-ip. 5294 : 21 : amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
5295 : :
5296 : 21 : initStringInfo(&opfam);
2069 michael@paquier.xyz 5297 : 21 : getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname,
5298 : : false);
5299 : :
4017 alvherre@alvh.no-ip. 5300 : 21 : ltype = format_type_be_qualified(amprocForm->amproclefttype);
5301 : 21 : rtype = format_type_be_qualified(amprocForm->amprocrighttype);
5302 : :
5303 [ + + ]: 21 : if (objname)
5304 : : {
5305 : 3 : *objname = lappend(*objname,
5306 : 3 : psprintf("%d", amprocForm->amprocnum));
5307 : 3 : *objargs = list_make2(ltype, rtype);
5308 : : }
5309 : :
4743 5310 : 21 : appendStringInfo(&buffer, "function %d (%s, %s) of %s",
5311 : 21 : amprocForm->amprocnum,
5312 : : ltype, rtype, opfam.data);
5313 : :
5314 : 21 : pfree(opfam.data);
5315 : :
5316 : 21 : systable_endscan(amscan);
2610 andres@anarazel.de 5317 : 21 : table_close(amprocDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 5318 : 21 : break;
5319 : : }
5320 : :
719 peter@eisentraut.org 5321 : 47 : case RewriteRelationId:
5322 : : {
5323 : : Relation ruleDesc;
5324 : : HeapTuple tup;
5325 : : Form_pg_rewrite rule;
5326 : :
2610 andres@anarazel.de 5327 : 47 : ruleDesc = table_open(RewriteRelationId, AccessShareLock);
5328 : :
2672 5329 : 47 : tup = get_catalog_object_by_oid(ruleDesc, Anum_pg_rewrite_oid,
5330 : 47 : object->objectId);
5331 : :
4743 alvherre@alvh.no-ip. 5332 [ + + ]: 47 : if (!HeapTupleIsValid(tup))
5333 : : {
2069 michael@paquier.xyz 5334 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5335 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for rule %u",
5336 : : object->objectId);
5337 : :
2069 michael@paquier.xyz 5338 :CBC 6 : table_close(ruleDesc, AccessShareLock);
5339 : 6 : break;
5340 : : }
5341 : :
4743 alvherre@alvh.no-ip. 5342 : 41 : rule = (Form_pg_rewrite) GETSTRUCT(tup);
5343 : :
5344 : 41 : appendStringInfo(&buffer, "%s on ",
5345 : 41 : quote_identifier(NameStr(rule->rulename)));
2069 michael@paquier.xyz 5346 : 41 : getRelationIdentity(&buffer, rule->ev_class, objname, false);
4093 alvherre@alvh.no-ip. 5347 [ + + ]: 41 : if (objname)
4092 5348 : 18 : *objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
5349 : :
2610 andres@anarazel.de 5350 : 41 : table_close(ruleDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 5351 : 41 : break;
5352 : : }
5353 : :
719 peter@eisentraut.org 5354 : 90 : case TriggerRelationId:
5355 : : {
5356 : : Relation trigDesc;
5357 : : HeapTuple tup;
5358 : : Form_pg_trigger trig;
5359 : :
2610 andres@anarazel.de 5360 : 90 : trigDesc = table_open(TriggerRelationId, AccessShareLock);
5361 : :
2672 5362 : 90 : tup = get_catalog_object_by_oid(trigDesc, Anum_pg_trigger_oid,
5363 : 90 : object->objectId);
5364 : :
4743 alvherre@alvh.no-ip. 5365 [ + + ]: 90 : if (!HeapTupleIsValid(tup))
5366 : : {
2069 michael@paquier.xyz 5367 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5368 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for trigger %u",
5369 : : object->objectId);
5370 : :
2069 michael@paquier.xyz 5371 :CBC 6 : table_close(trigDesc, AccessShareLock);
5372 : 6 : break;
5373 : : }
5374 : :
4743 alvherre@alvh.no-ip. 5375 : 84 : trig = (Form_pg_trigger) GETSTRUCT(tup);
5376 : :
5377 : 84 : appendStringInfo(&buffer, "%s on ",
5378 : 84 : quote_identifier(NameStr(trig->tgname)));
2069 michael@paquier.xyz 5379 : 84 : getRelationIdentity(&buffer, trig->tgrelid, objname, false);
4093 alvherre@alvh.no-ip. 5380 [ + + ]: 84 : if (objname)
4092 5381 : 57 : *objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
5382 : :
2610 andres@anarazel.de 5383 : 84 : table_close(trigDesc, AccessShareLock);
4743 alvherre@alvh.no-ip. 5384 : 84 : break;
5385 : : }
5386 : :
719 peter@eisentraut.org 5387 : 68 : case NamespaceRelationId:
5388 : : {
5389 : : char *nspname;
5390 : :
3996 alvherre@alvh.no-ip. 5391 : 68 : nspname = get_namespace_name_or_temp(object->objectId);
4743 5392 [ + + ]: 68 : if (!nspname)
5393 : : {
2069 michael@paquier.xyz 5394 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5395 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for namespace %u",
5396 : : object->objectId);
2069 michael@paquier.xyz 5397 :CBC 6 : break;
5398 : : }
4518 rhaas@postgresql.org 5399 : 62 : appendStringInfoString(&buffer,
5400 : : quote_identifier(nspname));
4093 alvherre@alvh.no-ip. 5401 [ + + ]: 62 : if (objname)
5402 : 36 : *objname = list_make1(nspname);
4743 5403 : 62 : break;
5404 : : }
5405 : :
719 peter@eisentraut.org 5406 : 28 : case StatisticExtRelationId:
5407 : : {
5408 : : HeapTuple tup;
5409 : : Form_pg_statistic_ext formStatistic;
5410 : : char *schema;
5411 : :
3227 tgl@sss.pgh.pa.us 5412 : 28 : tup = SearchSysCache1(STATEXTOID,
5413 : 28 : ObjectIdGetDatum(object->objectId));
5414 [ + + ]: 28 : if (!HeapTupleIsValid(tup))
5415 : : {
2069 michael@paquier.xyz 5416 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5417 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for statistics object %u",
5418 : : object->objectId);
2069 michael@paquier.xyz 5419 :CBC 6 : break;
5420 : : }
3227 tgl@sss.pgh.pa.us 5421 : 22 : formStatistic = (Form_pg_statistic_ext) GETSTRUCT(tup);
5422 : 22 : schema = get_namespace_name_or_temp(formStatistic->stxnamespace);
5423 : 22 : appendStringInfoString(&buffer,
5424 : 22 : quote_qualified_identifier(schema,
3189 5425 : 22 : NameStr(formStatistic->stxname)));
3227 5426 [ + + ]: 22 : if (objname)
5427 : 3 : *objname = list_make2(schema,
5428 : : pstrdup(NameStr(formStatistic->stxname)));
5429 : 22 : ReleaseSysCache(tup);
5430 : : }
5431 : 22 : break;
5432 : :
719 peter@eisentraut.org 5433 : 27 : case TSParserRelationId:
5434 : : {
5435 : : HeapTuple tup;
5436 : : Form_pg_ts_parser formParser;
5437 : : char *schema;
5438 : :
4743 alvherre@alvh.no-ip. 5439 : 27 : tup = SearchSysCache1(TSPARSEROID,
5440 : 27 : ObjectIdGetDatum(object->objectId));
5441 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
5442 : : {
2069 michael@paquier.xyz 5443 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5444 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search parser %u",
5445 : : object->objectId);
2069 michael@paquier.xyz 5446 :CBC 6 : break;
5447 : : }
4743 alvherre@alvh.no-ip. 5448 : 21 : formParser = (Form_pg_ts_parser) GETSTRUCT(tup);
3996 5449 : 21 : schema = get_namespace_name_or_temp(formParser->prsnamespace);
4518 rhaas@postgresql.org 5450 : 21 : appendStringInfoString(&buffer,
4351 alvherre@alvh.no-ip. 5451 : 21 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 5452 : 21 : NameStr(formParser->prsname)));
4093 alvherre@alvh.no-ip. 5453 [ + + ]: 21 : if (objname)
5454 : 3 : *objname = list_make2(schema,
5455 : : pstrdup(NameStr(formParser->prsname)));
4743 5456 : 21 : ReleaseSysCache(tup);
5457 : 21 : break;
5458 : : }
5459 : :
719 peter@eisentraut.org 5460 : 27 : case TSDictionaryRelationId:
5461 : : {
5462 : : HeapTuple tup;
5463 : : Form_pg_ts_dict formDict;
5464 : : char *schema;
5465 : :
4743 alvherre@alvh.no-ip. 5466 : 27 : tup = SearchSysCache1(TSDICTOID,
5467 : 27 : ObjectIdGetDatum(object->objectId));
5468 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
5469 : : {
2069 michael@paquier.xyz 5470 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5471 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search dictionary %u",
5472 : : object->objectId);
2069 michael@paquier.xyz 5473 :CBC 6 : break;
5474 : : }
4743 alvherre@alvh.no-ip. 5475 : 21 : formDict = (Form_pg_ts_dict) GETSTRUCT(tup);
3996 5476 : 21 : schema = get_namespace_name_or_temp(formDict->dictnamespace);
4518 rhaas@postgresql.org 5477 : 21 : appendStringInfoString(&buffer,
4351 alvherre@alvh.no-ip. 5478 : 21 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 5479 : 21 : NameStr(formDict->dictname)));
4093 alvherre@alvh.no-ip. 5480 [ + + ]: 21 : if (objname)
5481 : 3 : *objname = list_make2(schema,
5482 : : pstrdup(NameStr(formDict->dictname)));
4743 5483 : 21 : ReleaseSysCache(tup);
5484 : 21 : break;
5485 : : }
5486 : :
719 peter@eisentraut.org 5487 : 27 : case TSTemplateRelationId:
5488 : : {
5489 : : HeapTuple tup;
5490 : : Form_pg_ts_template formTmpl;
5491 : : char *schema;
5492 : :
4743 alvherre@alvh.no-ip. 5493 : 27 : tup = SearchSysCache1(TSTEMPLATEOID,
5494 : 27 : ObjectIdGetDatum(object->objectId));
5495 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
5496 : : {
2069 michael@paquier.xyz 5497 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5498 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search template %u",
5499 : : object->objectId);
2069 michael@paquier.xyz 5500 :CBC 6 : break;
5501 : : }
4743 alvherre@alvh.no-ip. 5502 : 21 : formTmpl = (Form_pg_ts_template) GETSTRUCT(tup);
3996 5503 : 21 : schema = get_namespace_name_or_temp(formTmpl->tmplnamespace);
4518 rhaas@postgresql.org 5504 : 21 : appendStringInfoString(&buffer,
4351 alvherre@alvh.no-ip. 5505 : 21 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 5506 : 21 : NameStr(formTmpl->tmplname)));
4093 alvherre@alvh.no-ip. 5507 [ + + ]: 21 : if (objname)
5508 : 3 : *objname = list_make2(schema,
5509 : : pstrdup(NameStr(formTmpl->tmplname)));
4743 5510 : 21 : ReleaseSysCache(tup);
5511 : 21 : break;
5512 : : }
5513 : :
719 peter@eisentraut.org 5514 : 31 : case TSConfigRelationId:
5515 : : {
5516 : : HeapTuple tup;
5517 : : Form_pg_ts_config formCfg;
5518 : : char *schema;
5519 : :
4743 alvherre@alvh.no-ip. 5520 : 31 : tup = SearchSysCache1(TSCONFIGOID,
5521 : 31 : ObjectIdGetDatum(object->objectId));
5522 [ + + ]: 31 : if (!HeapTupleIsValid(tup))
5523 : : {
2069 michael@paquier.xyz 5524 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5525 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for text search configuration %u",
5526 : : object->objectId);
2069 michael@paquier.xyz 5527 :CBC 6 : break;
5528 : : }
4743 alvherre@alvh.no-ip. 5529 : 25 : formCfg = (Form_pg_ts_config) GETSTRUCT(tup);
3996 5530 : 25 : schema = get_namespace_name_or_temp(formCfg->cfgnamespace);
4518 rhaas@postgresql.org 5531 : 25 : appendStringInfoString(&buffer,
4351 alvherre@alvh.no-ip. 5532 : 25 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 5533 : 25 : NameStr(formCfg->cfgname)));
4093 alvherre@alvh.no-ip. 5534 [ + + ]: 25 : if (objname)
5535 : 3 : *objname = list_make2(schema,
5536 : : pstrdup(NameStr(formCfg->cfgname)));
4743 5537 : 25 : ReleaseSysCache(tup);
5538 : 25 : break;
5539 : : }
5540 : :
719 peter@eisentraut.org 5541 : 27 : case AuthIdRelationId:
5542 : : {
5543 : : char *username;
5544 : :
2069 michael@paquier.xyz 5545 : 27 : username = GetUserNameFromId(object->objectId, missing_ok);
5546 [ + + ]: 27 : if (!username)
5547 : 6 : break;
4093 alvherre@alvh.no-ip. 5548 [ + + ]: 21 : if (objname)
5549 : 3 : *objname = list_make1(username);
4518 rhaas@postgresql.org 5550 : 21 : appendStringInfoString(&buffer,
5551 : : quote_identifier(username));
4743 alvherre@alvh.no-ip. 5552 : 21 : break;
5553 : : }
5554 : :
719 peter@eisentraut.org 5555 : 6 : case AuthMemRelationId:
5556 : : {
5557 : : Relation authMemDesc;
5558 : : ScanKeyData skey[1];
5559 : : SysScanDesc amscan;
5560 : : HeapTuple tup;
5561 : : Form_pg_auth_members amForm;
5562 : :
1305 rhaas@postgresql.org 5563 : 6 : authMemDesc = table_open(AuthMemRelationId,
5564 : : AccessShareLock);
5565 : :
5566 : 6 : ScanKeyInit(&skey[0],
5567 : : Anum_pg_auth_members_oid,
5568 : : BTEqualStrategyNumber, F_OIDEQ,
5569 : 6 : ObjectIdGetDatum(object->objectId));
5570 : :
5571 : 6 : amscan = systable_beginscan(authMemDesc, AuthMemOidIndexId, true,
5572 : : NULL, 1, skey);
5573 : :
5574 : 6 : tup = systable_getnext(amscan);
5575 : :
5576 [ + - ]: 6 : if (!HeapTupleIsValid(tup))
5577 : : {
5578 [ - + ]: 6 : if (!missing_ok)
1305 rhaas@postgresql.org 5579 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for pg_auth_members entry %u",
5580 : : object->objectId);
5581 : :
1305 rhaas@postgresql.org 5582 :CBC 6 : systable_endscan(amscan);
5583 : 6 : table_close(authMemDesc, AccessShareLock);
5584 : 6 : break;
5585 : : }
5586 : :
1305 rhaas@postgresql.org 5587 :UBC 0 : amForm = (Form_pg_auth_members) GETSTRUCT(tup);
5588 : :
5589 : 0 : appendStringInfo(&buffer, _("membership of role %s in role %s"),
5590 : : GetUserNameFromId(amForm->member, false),
5591 : : GetUserNameFromId(amForm->roleid, false));
5592 : :
5593 : 0 : systable_endscan(amscan);
5594 : 0 : table_close(authMemDesc, AccessShareLock);
5595 : 0 : break;
5596 : : }
5597 : :
719 peter@eisentraut.org 5598 :CBC 6 : case DatabaseRelationId:
5599 : : {
5600 : : char *datname;
5601 : :
4743 alvherre@alvh.no-ip. 5602 : 6 : datname = get_database_name(object->objectId);
5603 [ + - ]: 6 : if (!datname)
5604 : : {
2069 michael@paquier.xyz 5605 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5606 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for database %u",
5607 : : object->objectId);
2069 michael@paquier.xyz 5608 :CBC 6 : break;
5609 : : }
4093 alvherre@alvh.no-ip. 5610 [ # # ]:UBC 0 : if (objname)
5611 : 0 : *objname = list_make1(datname);
4518 rhaas@postgresql.org 5612 : 0 : appendStringInfoString(&buffer,
5613 : : quote_identifier(datname));
4743 alvherre@alvh.no-ip. 5614 : 0 : break;
5615 : : }
5616 : :
719 peter@eisentraut.org 5617 :CBC 6 : case TableSpaceRelationId:
5618 : : {
5619 : : char *tblspace;
5620 : :
4743 alvherre@alvh.no-ip. 5621 : 6 : tblspace = get_tablespace_name(object->objectId);
5622 [ + - ]: 6 : if (!tblspace)
5623 : : {
2069 michael@paquier.xyz 5624 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5625 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for tablespace %u",
5626 : : object->objectId);
2069 michael@paquier.xyz 5627 :CBC 6 : break;
5628 : : }
4093 alvherre@alvh.no-ip. 5629 [ # # ]:UBC 0 : if (objname)
5630 : 0 : *objname = list_make1(tblspace);
4518 rhaas@postgresql.org 5631 : 0 : appendStringInfoString(&buffer,
5632 : : quote_identifier(tblspace));
4743 alvherre@alvh.no-ip. 5633 : 0 : break;
5634 : : }
5635 : :
719 peter@eisentraut.org 5636 :CBC 30 : case ForeignDataWrapperRelationId:
5637 : : {
5638 : : ForeignDataWrapper *fdw;
5639 : :
2069 michael@paquier.xyz 5640 : 30 : fdw = GetForeignDataWrapperExtended(object->objectId,
5641 : : missing_ok);
5642 [ + + ]: 30 : if (fdw)
5643 : : {
5644 : 24 : appendStringInfoString(&buffer, quote_identifier(fdw->fdwname));
5645 [ + + ]: 24 : if (objname)
5646 : 6 : *objname = list_make1(pstrdup(fdw->fdwname));
5647 : : }
4743 alvherre@alvh.no-ip. 5648 : 30 : break;
5649 : : }
5650 : :
719 peter@eisentraut.org 5651 : 30 : case ForeignServerRelationId:
5652 : : {
5653 : : ForeignServer *srv;
5654 : :
2069 michael@paquier.xyz 5655 : 30 : srv = GetForeignServerExtended(object->objectId,
5656 : : missing_ok);
5657 [ + + ]: 30 : if (srv)
5658 : : {
5659 : 24 : appendStringInfoString(&buffer,
5660 : 24 : quote_identifier(srv->servername));
5661 [ + + ]: 24 : if (objname)
5662 : 6 : *objname = list_make1(pstrdup(srv->servername));
5663 : : }
4743 alvherre@alvh.no-ip. 5664 : 30 : break;
5665 : : }
5666 : :
719 peter@eisentraut.org 5667 : 30 : case UserMappingRelationId:
5668 : : {
5669 : : HeapTuple tup;
5670 : : Oid useid;
5671 : : Form_pg_user_mapping umform;
5672 : : ForeignServer *srv;
5673 : : const char *usename;
5674 : :
4743 alvherre@alvh.no-ip. 5675 : 30 : tup = SearchSysCache1(USERMAPPINGOID,
5676 : 30 : ObjectIdGetDatum(object->objectId));
5677 [ + + ]: 30 : if (!HeapTupleIsValid(tup))
5678 : : {
2069 michael@paquier.xyz 5679 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5680 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for user mapping %u",
5681 : : object->objectId);
2069 michael@paquier.xyz 5682 :CBC 6 : break;
5683 : : }
4028 alvherre@alvh.no-ip. 5684 : 24 : umform = (Form_pg_user_mapping) GETSTRUCT(tup);
5685 : 24 : useid = umform->umuser;
5686 : 24 : srv = GetForeignServer(umform->umserver);
5687 : :
4743 5688 : 24 : ReleaseSysCache(tup);
5689 : :
5690 [ + - ]: 24 : if (OidIsValid(useid))
3963 andrew@dunslane.net 5691 : 24 : usename = GetUserNameFromId(useid, false);
5692 : : else
4743 alvherre@alvh.no-ip. 5693 :UBC 0 : usename = "public";
5694 : :
4028 alvherre@alvh.no-ip. 5695 [ + + ]:CBC 24 : if (objname)
5696 : : {
5697 : 6 : *objname = list_make1(pstrdup(usename));
5698 : 6 : *objargs = list_make1(pstrdup(srv->servername));
5699 : : }
5700 : :
4008 5701 : 24 : appendStringInfo(&buffer, "%s on server %s",
5702 : : quote_identifier(usename),
5703 : : srv->servername);
4743 5704 : 24 : break;
5705 : : }
5706 : :
719 peter@eisentraut.org 5707 : 51 : case DefaultAclRelationId:
5708 : : {
5709 : : Relation defaclrel;
5710 : : ScanKeyData skey[1];
5711 : : SysScanDesc rcscan;
5712 : : HeapTuple tup;
5713 : : Form_pg_default_acl defacl;
5714 : : char *schema;
5715 : : char *username;
5716 : :
2610 andres@anarazel.de 5717 : 51 : defaclrel = table_open(DefaultAclRelationId, AccessShareLock);
5718 : :
4743 alvherre@alvh.no-ip. 5719 : 51 : ScanKeyInit(&skey[0],
5720 : : Anum_pg_default_acl_oid,
5721 : : BTEqualStrategyNumber, F_OIDEQ,
5722 : 51 : ObjectIdGetDatum(object->objectId));
5723 : :
5724 : 51 : rcscan = systable_beginscan(defaclrel, DefaultAclOidIndexId,
5725 : : true, NULL, 1, skey);
5726 : :
5727 : 51 : tup = systable_getnext(rcscan);
5728 : :
5729 [ + + ]: 51 : if (!HeapTupleIsValid(tup))
5730 : : {
2069 michael@paquier.xyz 5731 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5732 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for default ACL %u",
5733 : : object->objectId);
5734 : :
2069 michael@paquier.xyz 5735 :CBC 6 : systable_endscan(rcscan);
5736 : 6 : table_close(defaclrel, AccessShareLock);
5737 : 6 : break;
5738 : : }
5739 : :
4743 alvherre@alvh.no-ip. 5740 : 45 : defacl = (Form_pg_default_acl) GETSTRUCT(tup);
5741 : :
3963 andrew@dunslane.net 5742 : 45 : username = GetUserNameFromId(defacl->defaclrole, false);
4743 alvherre@alvh.no-ip. 5743 : 45 : appendStringInfo(&buffer,
5744 : : "for role %s",
5745 : : quote_identifier(username));
5746 : :
5747 [ + + ]: 45 : if (OidIsValid(defacl->defaclnamespace))
5748 : : {
3996 5749 : 21 : schema = get_namespace_name_or_temp(defacl->defaclnamespace);
4743 5750 : 21 : appendStringInfo(&buffer,
5751 : : " in schema %s",
5752 : : quote_identifier(schema));
5753 : : }
5754 : : else
4022 5755 : 24 : schema = NULL;
5756 : :
4743 5757 [ + - - - : 45 : switch (defacl->defaclobjtype)
- - - ]
5758 : : {
5759 : 45 : case DEFACLOBJ_RELATION:
5760 : 45 : appendStringInfoString(&buffer,
5761 : : " on tables");
5762 : 45 : break;
4743 alvherre@alvh.no-ip. 5763 :UBC 0 : case DEFACLOBJ_SEQUENCE:
5764 : 0 : appendStringInfoString(&buffer,
5765 : : " on sequences");
5766 : 0 : break;
5767 : 0 : case DEFACLOBJ_FUNCTION:
5768 : 0 : appendStringInfoString(&buffer,
5769 : : " on functions");
5770 : 0 : break;
5771 : 0 : case DEFACLOBJ_TYPE:
5772 : 0 : appendStringInfoString(&buffer,
5773 : : " on types");
5774 : 0 : break;
3274 teodor@sigaev.ru 5775 : 0 : case DEFACLOBJ_NAMESPACE:
5776 : 0 : appendStringInfoString(&buffer,
5777 : : " on schemas");
5778 : 0 : break;
345 fujii@postgresql.org 5779 : 0 : case DEFACLOBJ_LARGEOBJECT:
5780 : 0 : appendStringInfoString(&buffer,
5781 : : " on large objects");
5782 : 0 : break;
5783 : : }
5784 : :
4022 alvherre@alvh.no-ip. 5785 [ + + ]:CBC 45 : if (objname)
5786 : : {
5787 : 9 : *objname = list_make1(username);
5788 [ + + ]: 9 : if (schema)
5789 : 3 : *objname = lappend(*objname, schema);
5790 : 9 : *objargs = list_make1(psprintf("%c", defacl->defaclobjtype));
5791 : : }
5792 : :
4743 5793 : 45 : systable_endscan(rcscan);
2610 andres@anarazel.de 5794 : 45 : table_close(defaclrel, AccessShareLock);
4743 alvherre@alvh.no-ip. 5795 : 45 : break;
5796 : : }
5797 : :
719 peter@eisentraut.org 5798 : 18 : case ExtensionRelationId:
5799 : : {
5800 : : char *extname;
5801 : :
4743 alvherre@alvh.no-ip. 5802 : 18 : extname = get_extension_name(object->objectId);
5803 [ + + ]: 18 : if (!extname)
5804 : : {
2069 michael@paquier.xyz 5805 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5806 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for extension %u",
5807 : : object->objectId);
2069 michael@paquier.xyz 5808 :CBC 6 : break;
5809 : : }
4518 rhaas@postgresql.org 5810 : 12 : appendStringInfoString(&buffer, quote_identifier(extname));
4093 alvherre@alvh.no-ip. 5811 [ - + ]: 12 : if (objname)
4093 alvherre@alvh.no-ip. 5812 :UBC 0 : *objname = list_make1(extname);
4743 alvherre@alvh.no-ip. 5813 :CBC 12 : break;
5814 : : }
5815 : :
719 peter@eisentraut.org 5816 : 24 : case EventTriggerRelationId:
5817 : : {
5818 : : HeapTuple tup;
5819 : : Form_pg_event_trigger trigForm;
5820 : : char *evtname;
5821 : :
4743 alvherre@alvh.no-ip. 5822 : 24 : tup = SearchSysCache1(EVENTTRIGGEROID,
5823 : 24 : ObjectIdGetDatum(object->objectId));
5824 [ + + ]: 24 : if (!HeapTupleIsValid(tup))
5825 : : {
2069 michael@paquier.xyz 5826 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5827 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for event trigger %u",
5828 : : object->objectId);
2069 michael@paquier.xyz 5829 :CBC 6 : break;
5830 : : }
4743 alvherre@alvh.no-ip. 5831 : 18 : trigForm = (Form_pg_event_trigger) GETSTRUCT(tup);
1782 michael@paquier.xyz 5832 : 18 : evtname = pstrdup(NameStr(trigForm->evtname));
5833 : 18 : appendStringInfoString(&buffer, quote_identifier(evtname));
5834 [ + + ]: 18 : if (objname)
5835 : 9 : *objname = list_make1(evtname);
4743 alvherre@alvh.no-ip. 5836 : 18 : ReleaseSysCache(tup);
5837 : 18 : break;
5838 : : }
5839 : :
719 peter@eisentraut.org 5840 : 8 : case ParameterAclRelationId:
5841 : : {
5842 : : HeapTuple tup;
5843 : : Datum nameDatum;
5844 : : char *parname;
5845 : :
1439 tgl@sss.pgh.pa.us 5846 : 8 : tup = SearchSysCache1(PARAMETERACLOID,
5847 : 8 : ObjectIdGetDatum(object->objectId));
5848 [ + + ]: 8 : if (!HeapTupleIsValid(tup))
5849 : : {
5850 [ - + ]: 6 : if (!missing_ok)
1439 tgl@sss.pgh.pa.us 5851 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for parameter ACL %u",
5852 : : object->objectId);
1439 tgl@sss.pgh.pa.us 5853 :CBC 6 : break;
5854 : : }
1086 dgustafsson@postgres 5855 : 2 : nameDatum = SysCacheGetAttrNotNull(PARAMETERACLOID, tup,
5856 : : Anum_pg_parameter_acl_parname);
1439 tgl@sss.pgh.pa.us 5857 : 2 : parname = TextDatumGetCString(nameDatum);
5858 : 2 : appendStringInfoString(&buffer, parname);
5859 [ + + ]: 2 : if (objname)
5860 : 1 : *objname = list_make1(parname);
5861 : 2 : ReleaseSysCache(tup);
5862 : 2 : break;
5863 : : }
5864 : :
719 peter@eisentraut.org 5865 : 48 : case PolicyRelationId:
5866 : : {
5867 : : Relation polDesc;
5868 : : HeapTuple tup;
5869 : : Form_pg_policy policy;
5870 : :
2610 andres@anarazel.de 5871 : 48 : polDesc = table_open(PolicyRelationId, AccessShareLock);
5872 : :
2672 5873 : 48 : tup = get_catalog_object_by_oid(polDesc, Anum_pg_policy_oid,
5874 : 48 : object->objectId);
5875 : :
3920 alvherre@alvh.no-ip. 5876 [ + + ]: 48 : if (!HeapTupleIsValid(tup))
5877 : : {
2069 michael@paquier.xyz 5878 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5879 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for policy %u",
5880 : : object->objectId);
5881 : :
2069 michael@paquier.xyz 5882 :CBC 6 : table_close(polDesc, AccessShareLock);
5883 : 6 : break;
5884 : : }
5885 : :
3227 tgl@sss.pgh.pa.us 5886 : 42 : policy = (Form_pg_policy) GETSTRUCT(tup);
5887 : :
5888 : 42 : appendStringInfo(&buffer, "%s on ",
5889 : 42 : quote_identifier(NameStr(policy->polname)));
2069 michael@paquier.xyz 5890 : 42 : getRelationIdentity(&buffer, policy->polrelid, objname, false);
3920 alvherre@alvh.no-ip. 5891 [ + + ]: 42 : if (objname)
3227 tgl@sss.pgh.pa.us 5892 : 18 : *objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
5893 : :
2610 andres@anarazel.de 5894 : 42 : table_close(polDesc, AccessShareLock);
3227 tgl@sss.pgh.pa.us 5895 : 42 : break;
5896 : : }
5897 : :
719 peter@eisentraut.org 5898 : 27 : case PublicationRelationId:
5899 : : {
5900 : : char *pubname;
5901 : :
2069 michael@paquier.xyz 5902 : 27 : pubname = get_publication_name(object->objectId, missing_ok);
5903 [ + + ]: 27 : if (pubname)
5904 : : {
5905 : 21 : appendStringInfoString(&buffer,
5906 : : quote_identifier(pubname));
5907 [ + + ]: 21 : if (objname)
5908 : 3 : *objname = list_make1(pubname);
5909 : : }
3342 peter_e@gmx.net 5910 : 27 : break;
5911 : : }
5912 : :
719 peter@eisentraut.org 5913 : 27 : case PublicationNamespaceRelationId:
5914 : : {
5915 : : char *pubname;
5916 : : char *nspname;
5917 : :
1600 akapila@postgresql.o 5918 [ + + ]: 27 : if (!getPublicationSchemaInfo(object, missing_ok, &pubname,
5919 : : &nspname))
5920 : 6 : break;
1438 tomas.vondra@postgre 5921 : 21 : appendStringInfo(&buffer, "%s in publication %s",
5922 : : nspname, pubname);
5923 : :
1600 akapila@postgresql.o 5924 [ + + ]: 21 : if (objargs)
5925 : 3 : *objargs = list_make1(pubname);
5926 : : else
5927 : 18 : pfree(pubname);
5928 : :
5929 [ + + ]: 21 : if (objname)
5930 : 3 : *objname = list_make1(nspname);
5931 : : else
5932 : 18 : pfree(nspname);
5933 : :
5934 : 21 : break;
5935 : : }
5936 : :
719 peter@eisentraut.org 5937 : 27 : case PublicationRelRelationId:
5938 : : {
5939 : : HeapTuple tup;
5940 : : char *pubname;
5941 : : Form_pg_publication_rel prform;
5942 : :
3342 peter_e@gmx.net 5943 : 27 : tup = SearchSysCache1(PUBLICATIONREL,
5944 : 27 : ObjectIdGetDatum(object->objectId));
5945 [ + + ]: 27 : if (!HeapTupleIsValid(tup))
5946 : : {
2069 michael@paquier.xyz 5947 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5948 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for publication table %u",
5949 : : object->objectId);
2069 michael@paquier.xyz 5950 :CBC 6 : break;
5951 : : }
5952 : :
3342 peter_e@gmx.net 5953 : 21 : prform = (Form_pg_publication_rel) GETSTRUCT(tup);
2735 michael@paquier.xyz 5954 : 21 : pubname = get_publication_name(prform->prpubid, false);
5955 : :
2069 5956 : 21 : getRelationIdentity(&buffer, prform->prrelid, objname, false);
2852 tgl@sss.pgh.pa.us 5957 : 21 : appendStringInfo(&buffer, " in publication %s", pubname);
5958 : :
5959 [ + + ]: 21 : if (objargs)
3342 peter_e@gmx.net 5960 : 3 : *objargs = list_make1(pubname);
5961 : :
5962 : 21 : ReleaseSysCache(tup);
5963 : 21 : break;
5964 : : }
5965 : :
719 peter@eisentraut.org 5966 : 27 : case SubscriptionRelationId:
5967 : : {
5968 : : char *subname;
5969 : :
2069 michael@paquier.xyz 5970 : 27 : subname = get_subscription_name(object->objectId, missing_ok);
5971 [ + + ]: 27 : if (subname)
5972 : : {
5973 : 21 : appendStringInfoString(&buffer,
5974 : : quote_identifier(subname));
5975 [ + + ]: 21 : if (objname)
5976 : 3 : *objname = list_make1(subname);
5977 : : }
3342 peter_e@gmx.net 5978 : 27 : break;
5979 : : }
5980 : :
719 peter@eisentraut.org 5981 : 29 : case TransformRelationId:
5982 : : {
5983 : : Relation transformDesc;
5984 : : HeapTuple tup;
5985 : : Form_pg_transform transform;
5986 : : char *transformLang;
5987 : : char *transformType;
5988 : :
2610 andres@anarazel.de 5989 : 29 : transformDesc = table_open(TransformRelationId, AccessShareLock);
5990 : :
2672 5991 : 29 : tup = get_catalog_object_by_oid(transformDesc,
5992 : : Anum_pg_transform_oid,
5993 : 29 : object->objectId);
5994 : :
3278 alvherre@alvh.no-ip. 5995 [ + + ]: 29 : if (!HeapTupleIsValid(tup))
5996 : : {
2069 michael@paquier.xyz 5997 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 5998 [ # # ]:UBC 0 : elog(ERROR, "could not find tuple for transform %u",
5999 : : object->objectId);
6000 : :
2069 michael@paquier.xyz 6001 :CBC 6 : table_close(transformDesc, AccessShareLock);
6002 : 6 : break;
6003 : : }
6004 : :
3227 tgl@sss.pgh.pa.us 6005 : 23 : transform = (Form_pg_transform) GETSTRUCT(tup);
6006 : :
6007 : 23 : transformType = format_type_be_qualified(transform->trftype);
6008 : 23 : transformLang = get_language_name(transform->trflang, false);
6009 : :
1126 alvherre@alvh.no-ip. 6010 : 23 : appendStringInfo(&buffer, "for %s language %s",
6011 : : transformType,
6012 : : transformLang);
3278 6013 [ + + ]: 23 : if (objname)
6014 : : {
3227 tgl@sss.pgh.pa.us 6015 : 4 : *objname = list_make1(transformType);
6016 : 4 : *objargs = list_make1(pstrdup(transformLang));
6017 : : }
6018 : :
2610 andres@anarazel.de 6019 : 23 : table_close(transformDesc, AccessShareLock);
6020 : : }
3278 alvherre@alvh.no-ip. 6021 : 23 : break;
6022 : :
719 peter@eisentraut.org 6023 :UBC 0 : default:
6024 [ # # ]: 0 : elog(ERROR, "unsupported object class: %u", object->classId);
6025 : : }
6026 : :
2069 michael@paquier.xyz 6027 [ + + ]:CBC 3921 : if (!missing_ok)
6028 : : {
6029 : : /*
6030 : : * If a get_object_address() representation was requested, make sure
6031 : : * we are providing one. We don't check objargs, because many of the
6032 : : * cases above leave it as NIL.
6033 : : */
6034 [ + + - + ]: 2246 : if (objname && *objname == NIL)
719 peter@eisentraut.org 6035 [ # # ]:UBC 0 : elog(ERROR, "requested object address for unsupported object class %u: text result \"%s\"",
6036 : : object->classId, buffer.data);
6037 : : }
6038 : : else
6039 : : {
6040 : : /* an empty buffer is equivalent to no object found */
2069 michael@paquier.xyz 6041 [ + + ]:CBC 1675 : if (buffer.len == 0)
6042 : : {
6043 [ + + + - : 255 : Assert((objname == NULL || *objname == NIL) &&
+ + - + ]
6044 : : (objargs == NULL || *objargs == NIL));
6045 : 255 : return NULL;
6046 : : }
6047 : : }
6048 : :
4743 alvherre@alvh.no-ip. 6049 : 3666 : return buffer.data;
6050 : : }
6051 : :
6052 : : static void
2069 michael@paquier.xyz 6053 : 74 : getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
6054 : : bool missing_ok)
6055 : : {
6056 : : HeapTuple opfTup;
6057 : : Form_pg_opfamily opfForm;
6058 : : HeapTuple amTup;
6059 : : Form_pg_am amForm;
6060 : : char *schema;
6061 : :
4743 alvherre@alvh.no-ip. 6062 : 74 : opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
6063 [ + + ]: 74 : if (!HeapTupleIsValid(opfTup))
6064 : : {
2069 michael@paquier.xyz 6065 [ - + ]: 6 : if (!missing_ok)
2069 michael@paquier.xyz 6066 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for opfamily %u", opfid);
2069 michael@paquier.xyz 6067 :CBC 6 : return;
6068 : : }
4743 alvherre@alvh.no-ip. 6069 : 68 : opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup);
6070 : :
6071 : 68 : amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod));
6072 [ - + ]: 68 : if (!HeapTupleIsValid(amTup))
4743 alvherre@alvh.no-ip. 6073 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for access method %u",
6074 : : opfForm->opfmethod);
4743 alvherre@alvh.no-ip. 6075 :CBC 68 : amForm = (Form_pg_am) GETSTRUCT(amTup);
6076 : :
3996 6077 : 68 : schema = get_namespace_name_or_temp(opfForm->opfnamespace);
4043 6078 : 68 : appendStringInfo(buffer, "%s USING %s",
6079 : : quote_qualified_identifier(schema,
4743 6080 : 68 : NameStr(opfForm->opfname)),
6081 : 68 : NameStr(amForm->amname));
6082 : :
3410 peter_e@gmx.net 6083 [ + + ]: 68 : if (object)
6084 : 9 : *object = list_make3(pstrdup(NameStr(amForm->amname)),
6085 : : pstrdup(schema),
6086 : : pstrdup(NameStr(opfForm->opfname)));
6087 : :
4743 alvherre@alvh.no-ip. 6088 : 68 : ReleaseSysCache(amTup);
6089 : 68 : ReleaseSysCache(opfTup);
6090 : : }
6091 : :
6092 : : /*
6093 : : * Append the relation identity (quoted qualified name) to the given
6094 : : * StringInfo.
6095 : : */
6096 : : static void
2069 michael@paquier.xyz 6097 : 1791 : getRelationIdentity(StringInfo buffer, Oid relid, List **object,
6098 : : bool missing_ok)
6099 : : {
6100 : : HeapTuple relTup;
6101 : : Form_pg_class relForm;
6102 : : char *schema;
6103 : :
4743 alvherre@alvh.no-ip. 6104 : 1791 : relTup = SearchSysCache1(RELOID,
6105 : : ObjectIdGetDatum(relid));
6106 [ + + ]: 1791 : if (!HeapTupleIsValid(relTup))
6107 : : {
2069 michael@paquier.xyz 6108 [ - + ]: 9 : if (!missing_ok)
2069 michael@paquier.xyz 6109 [ # # ]:UBC 0 : elog(ERROR, "cache lookup failed for relation %u", relid);
6110 : :
2069 michael@paquier.xyz 6111 [ + + ]:CBC 9 : if (object)
6112 : 3 : *object = NIL;
6113 : 9 : return;
6114 : : }
4743 alvherre@alvh.no-ip. 6115 : 1782 : relForm = (Form_pg_class) GETSTRUCT(relTup);
6116 : :
3996 6117 : 1782 : schema = get_namespace_name_or_temp(relForm->relnamespace);
4518 rhaas@postgresql.org 6118 : 1782 : appendStringInfoString(buffer,
4351 alvherre@alvh.no-ip. 6119 : 1782 : quote_qualified_identifier(schema,
3189 tgl@sss.pgh.pa.us 6120 : 1782 : NameStr(relForm->relname)));
3410 peter_e@gmx.net 6121 [ + + ]: 1782 : if (object)
6122 : 1234 : *object = list_make2(schema, pstrdup(NameStr(relForm->relname)));
6123 : :
4743 alvherre@alvh.no-ip. 6124 : 1782 : ReleaseSysCache(relTup);
6125 : : }
6126 : :
6127 : : /*
6128 : : * Auxiliary function to build a TEXT array out of a list of C-strings.
6129 : : */
6130 : : ArrayType *
4093 6131 : 898 : strlist_to_textarray(List *list)
6132 : : {
6133 : : ArrayType *arr;
6134 : : Datum *datums;
6135 : : bool *nulls;
3949 bruce@momjian.us 6136 : 898 : int j = 0;
6137 : : ListCell *cell;
6138 : : MemoryContext memcxt;
6139 : : MemoryContext oldcxt;
6140 : : int lb[1];
6141 : :
6142 : : /* Work in a temp context; easier than individually pfree'ing the Datums */
4093 alvherre@alvh.no-ip. 6143 : 898 : memcxt = AllocSetContextCreate(CurrentMemoryContext,
6144 : : "strlist to array",
6145 : : ALLOCSET_DEFAULT_SIZES);
6146 : 898 : oldcxt = MemoryContextSwitchTo(memcxt);
6147 : :
95 michael@paquier.xyz 6148 :GNC 898 : datums = palloc_array(Datum, list_length(list));
6149 : 898 : nulls = palloc_array(bool, list_length(list));
6150 : :
4093 alvherre@alvh.no-ip. 6151 [ + - + + :CBC 2438 : foreach(cell, list)
+ + ]
6152 : : {
3949 bruce@momjian.us 6153 : 1540 : char *name = lfirst(cell);
6154 : :
2580 alvherre@alvh.no-ip. 6155 [ + - ]: 1540 : if (name)
6156 : : {
6157 : 1540 : nulls[j] = false;
6158 : 1540 : datums[j++] = CStringGetTextDatum(name);
6159 : : }
6160 : : else
2580 alvherre@alvh.no-ip. 6161 :UBC 0 : nulls[j] = true;
6162 : : }
6163 : :
4093 alvherre@alvh.no-ip. 6164 :CBC 898 : MemoryContextSwitchTo(oldcxt);
6165 : :
2580 6166 : 898 : lb[0] = 1;
6167 : 898 : arr = construct_md_array(datums, nulls, 1, &j,
6168 : : lb, TEXTOID, -1, false, TYPALIGN_INT);
6169 : :
4093 6170 : 898 : MemoryContextDelete(memcxt);
6171 : :
6172 : 898 : return arr;
6173 : : }
6174 : :
6175 : : /*
6176 : : * get_relkind_objtype
6177 : : *
6178 : : * Return the object type for the relkind given by the caller.
6179 : : *
6180 : : * If an unexpected relkind is passed, we say OBJECT_TABLE rather than
6181 : : * failing. That's because this is mostly used for generating error messages
6182 : : * for failed ACL checks on relations, and we'd rather produce a generic
6183 : : * message saying "table" than fail entirely.
6184 : : */
6185 : : ObjectType
3025 peter_e@gmx.net 6186 : 807 : get_relkind_objtype(char relkind)
6187 : : {
6188 [ + + + + : 807 : switch (relkind)
+ + + - ]
6189 : : {
6190 : 763 : case RELKIND_RELATION:
6191 : : case RELKIND_PARTITIONED_TABLE:
6192 : 763 : return OBJECT_TABLE;
6193 : 13 : case RELKIND_INDEX:
6194 : : case RELKIND_PARTITIONED_INDEX:
6195 : 13 : return OBJECT_INDEX;
6196 : 3 : case RELKIND_SEQUENCE:
6197 : 3 : return OBJECT_SEQUENCE;
6198 : 18 : case RELKIND_VIEW:
6199 : 18 : return OBJECT_VIEW;
6200 : 3 : case RELKIND_MATVIEW:
6201 : 3 : return OBJECT_MATVIEW;
6202 : 1 : case RELKIND_FOREIGN_TABLE:
6203 : 1 : return OBJECT_FOREIGN_TABLE;
2322 tgl@sss.pgh.pa.us 6204 : 6 : case RELKIND_TOASTVALUE:
6205 : 6 : return OBJECT_TABLE;
3025 peter_e@gmx.net 6206 :UBC 0 : default:
6207 : : /* Per above, don't raise an error */
2322 tgl@sss.pgh.pa.us 6208 : 0 : return OBJECT_TABLE;
6209 : : }
6210 : : }
|