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