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