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