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