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