PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/backend/catalog/objectaddress.c

http://github.com/postgres/postgres
C | 5379 lines | 4271 code | 628 blank | 480 comment | 363 complexity | 8fb78006420387d04b00a103a56cd642 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*-------------------------------------------------------------------------
  2. *
  3. * objectaddress.c
  4. * functions for working with ObjectAddresses
  5. *
  6. * Portions Copyright (c) 1996-2020, 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. #include "postgres.h"
  16. #include "access/genam.h"
  17. #include "access/htup_details.h"
  18. #include "access/relation.h"
  19. #include "access/sysattr.h"
  20. #include "access/table.h"
  21. #include "catalog/catalog.h"
  22. #include "catalog/indexing.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_cast.h"
  30. #include "catalog/pg_collation.h"
  31. #include "catalog/pg_constraint.h"
  32. #include "catalog/pg_conversion.h"
  33. #include "catalog/pg_database.h"
  34. #include "catalog/pg_default_acl.h"
  35. #include "catalog/pg_enum.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_policy.h"
  48. #include "catalog/pg_proc.h"
  49. #include "catalog/pg_publication.h"
  50. #include "catalog/pg_publication_rel.h"
  51. #include "catalog/pg_rewrite.h"
  52. #include "catalog/pg_statistic_ext.h"
  53. #include "catalog/pg_subscription.h"
  54. #include "catalog/pg_tablespace.h"
  55. #include "catalog/pg_transform.h"
  56. #include "catalog/pg_trigger.h"
  57. #include "catalog/pg_ts_config.h"
  58. #include "catalog/pg_ts_dict.h"
  59. #include "catalog/pg_ts_parser.h"
  60. #include "catalog/pg_ts_template.h"
  61. #include "catalog/pg_type.h"
  62. #include "catalog/pg_user_mapping.h"
  63. #include "commands/dbcommands.h"
  64. #include "commands/defrem.h"
  65. #include "commands/event_trigger.h"
  66. #include "commands/extension.h"
  67. #include "commands/policy.h"
  68. #include "commands/proclang.h"
  69. #include "commands/tablespace.h"
  70. #include "commands/trigger.h"
  71. #include "foreign/foreign.h"
  72. #include "funcapi.h"
  73. #include "miscadmin.h"
  74. #include "nodes/makefuncs.h"
  75. #include "parser/parse_func.h"
  76. #include "parser/parse_oper.h"
  77. #include "parser/parse_type.h"
  78. #include "rewrite/rewriteSupport.h"
  79. #include "storage/large_object.h"
  80. #include "storage/lmgr.h"
  81. #include "storage/sinval.h"
  82. #include "utils/acl.h"
  83. #include "utils/builtins.h"
  84. #include "utils/fmgroids.h"
  85. #include "utils/lsyscache.h"
  86. #include "utils/memutils.h"
  87. #include "utils/regproc.h"
  88. #include "utils/syscache.h"
  89. /*
  90. * ObjectProperty
  91. *
  92. * This array provides a common part of system object structure; to help
  93. * consolidate routines to handle various kind of object classes.
  94. */
  95. typedef struct
  96. {
  97. Oid class_oid; /* oid of catalog */
  98. Oid oid_index_oid; /* oid of index on system oid column */
  99. int oid_catcache_id; /* id of catcache on system oid column */
  100. int name_catcache_id; /* id of catcache on (name,namespace), or
  101. * (name) if the object does not live in a
  102. * namespace */
  103. AttrNumber attnum_oid; /* attribute number of oid column */
  104. AttrNumber attnum_name; /* attnum of name field */
  105. AttrNumber attnum_namespace; /* attnum of namespace field */
  106. AttrNumber attnum_owner; /* attnum of owner field */
  107. AttrNumber attnum_acl; /* attnum of acl field */
  108. ObjectType objtype; /* OBJECT_* of this object type */
  109. bool is_nsp_name_unique; /* can the nsp/name combination (or name
  110. * alone, if there's no namespace) be
  111. * considered a unique identifier for an
  112. * object of this class? */
  113. } ObjectPropertyType;
  114. static const ObjectPropertyType ObjectProperty[] =
  115. {
  116. {
  117. AccessMethodRelationId,
  118. AmOidIndexId,
  119. AMOID,
  120. AMNAME,
  121. Anum_pg_am_oid,
  122. Anum_pg_am_amname,
  123. InvalidAttrNumber,
  124. InvalidAttrNumber,
  125. InvalidAttrNumber,
  126. -1,
  127. true
  128. },
  129. {
  130. CastRelationId,
  131. CastOidIndexId,
  132. -1,
  133. -1,
  134. Anum_pg_cast_oid,
  135. InvalidAttrNumber,
  136. InvalidAttrNumber,
  137. InvalidAttrNumber,
  138. InvalidAttrNumber,
  139. -1,
  140. false
  141. },
  142. {
  143. CollationRelationId,
  144. CollationOidIndexId,
  145. COLLOID,
  146. -1, /* COLLNAMEENCNSP also takes encoding */
  147. Anum_pg_collation_oid,
  148. Anum_pg_collation_collname,
  149. Anum_pg_collation_collnamespace,
  150. Anum_pg_collation_collowner,
  151. InvalidAttrNumber,
  152. OBJECT_COLLATION,
  153. true
  154. },
  155. {
  156. ConstraintRelationId,
  157. ConstraintOidIndexId,
  158. CONSTROID,
  159. -1,
  160. Anum_pg_constraint_oid,
  161. Anum_pg_constraint_conname,
  162. Anum_pg_constraint_connamespace,
  163. InvalidAttrNumber,
  164. InvalidAttrNumber,
  165. -1,
  166. false
  167. },
  168. {
  169. ConversionRelationId,
  170. ConversionOidIndexId,
  171. CONVOID,
  172. CONNAMENSP,
  173. Anum_pg_conversion_oid,
  174. Anum_pg_conversion_conname,
  175. Anum_pg_conversion_connamespace,
  176. Anum_pg_conversion_conowner,
  177. InvalidAttrNumber,
  178. OBJECT_CONVERSION,
  179. true
  180. },
  181. {
  182. DatabaseRelationId,
  183. DatabaseOidIndexId,
  184. DATABASEOID,
  185. -1,
  186. Anum_pg_database_oid,
  187. Anum_pg_database_datname,
  188. InvalidAttrNumber,
  189. Anum_pg_database_datdba,
  190. Anum_pg_database_datacl,
  191. OBJECT_DATABASE,
  192. true
  193. },
  194. {
  195. ExtensionRelationId,
  196. ExtensionOidIndexId,
  197. -1,
  198. -1,
  199. Anum_pg_extension_oid,
  200. Anum_pg_extension_extname,
  201. InvalidAttrNumber, /* extension doesn't belong to extnamespace */
  202. Anum_pg_extension_extowner,
  203. InvalidAttrNumber,
  204. OBJECT_EXTENSION,
  205. true
  206. },
  207. {
  208. ForeignDataWrapperRelationId,
  209. ForeignDataWrapperOidIndexId,
  210. FOREIGNDATAWRAPPEROID,
  211. FOREIGNDATAWRAPPERNAME,
  212. Anum_pg_foreign_data_wrapper_oid,
  213. Anum_pg_foreign_data_wrapper_fdwname,
  214. InvalidAttrNumber,
  215. Anum_pg_foreign_data_wrapper_fdwowner,
  216. Anum_pg_foreign_data_wrapper_fdwacl,
  217. OBJECT_FDW,
  218. true
  219. },
  220. {
  221. ForeignServerRelationId,
  222. ForeignServerOidIndexId,
  223. FOREIGNSERVEROID,
  224. FOREIGNSERVERNAME,
  225. Anum_pg_foreign_server_oid,
  226. Anum_pg_foreign_server_srvname,
  227. InvalidAttrNumber,
  228. Anum_pg_foreign_server_srvowner,
  229. Anum_pg_foreign_server_srvacl,
  230. OBJECT_FOREIGN_SERVER,
  231. true
  232. },
  233. {
  234. ProcedureRelationId,
  235. ProcedureOidIndexId,
  236. PROCOID,
  237. -1, /* PROCNAMEARGSNSP also takes argument types */
  238. Anum_pg_proc_oid,
  239. Anum_pg_proc_proname,
  240. Anum_pg_proc_pronamespace,
  241. Anum_pg_proc_proowner,
  242. Anum_pg_proc_proacl,
  243. OBJECT_FUNCTION,
  244. false
  245. },
  246. {
  247. LanguageRelationId,
  248. LanguageOidIndexId,
  249. LANGOID,
  250. LANGNAME,
  251. Anum_pg_language_oid,
  252. Anum_pg_language_lanname,
  253. InvalidAttrNumber,
  254. Anum_pg_language_lanowner,
  255. Anum_pg_language_lanacl,
  256. OBJECT_LANGUAGE,
  257. true
  258. },
  259. {
  260. LargeObjectMetadataRelationId,
  261. LargeObjectMetadataOidIndexId,
  262. -1,
  263. -1,
  264. Anum_pg_largeobject_metadata_oid,
  265. InvalidAttrNumber,
  266. InvalidAttrNumber,
  267. Anum_pg_largeobject_metadata_lomowner,
  268. Anum_pg_largeobject_metadata_lomacl,
  269. OBJECT_LARGEOBJECT,
  270. false
  271. },
  272. {
  273. OperatorClassRelationId,
  274. OpclassOidIndexId,
  275. CLAOID,
  276. -1, /* CLAAMNAMENSP also takes opcmethod */
  277. Anum_pg_opclass_oid,
  278. Anum_pg_opclass_opcname,
  279. Anum_pg_opclass_opcnamespace,
  280. Anum_pg_opclass_opcowner,
  281. InvalidAttrNumber,
  282. OBJECT_OPCLASS,
  283. true
  284. },
  285. {
  286. OperatorRelationId,
  287. OperatorOidIndexId,
  288. OPEROID,
  289. -1, /* OPERNAMENSP also takes left and right type */
  290. Anum_pg_operator_oid,
  291. Anum_pg_operator_oprname,
  292. Anum_pg_operator_oprnamespace,
  293. Anum_pg_operator_oprowner,
  294. InvalidAttrNumber,
  295. OBJECT_OPERATOR,
  296. false
  297. },
  298. {
  299. OperatorFamilyRelationId,
  300. OpfamilyOidIndexId,
  301. OPFAMILYOID,
  302. -1, /* OPFAMILYAMNAMENSP also takes opfmethod */
  303. Anum_pg_opfamily_oid,
  304. Anum_pg_opfamily_opfname,
  305. Anum_pg_opfamily_opfnamespace,
  306. Anum_pg_opfamily_opfowner,
  307. InvalidAttrNumber,
  308. OBJECT_OPFAMILY,
  309. true
  310. },
  311. {
  312. AuthIdRelationId,
  313. AuthIdOidIndexId,
  314. AUTHOID,
  315. AUTHNAME,
  316. Anum_pg_authid_oid,
  317. Anum_pg_authid_rolname,
  318. InvalidAttrNumber,
  319. InvalidAttrNumber,
  320. InvalidAttrNumber,
  321. -1,
  322. true
  323. },
  324. {
  325. RewriteRelationId,
  326. RewriteOidIndexId,
  327. -1,
  328. -1,
  329. Anum_pg_rewrite_oid,
  330. Anum_pg_rewrite_rulename,
  331. InvalidAttrNumber,
  332. InvalidAttrNumber,
  333. InvalidAttrNumber,
  334. -1,
  335. false
  336. },
  337. {
  338. NamespaceRelationId,
  339. NamespaceOidIndexId,
  340. NAMESPACEOID,
  341. NAMESPACENAME,
  342. Anum_pg_namespace_oid,
  343. Anum_pg_namespace_nspname,
  344. InvalidAttrNumber,
  345. Anum_pg_namespace_nspowner,
  346. Anum_pg_namespace_nspacl,
  347. OBJECT_SCHEMA,
  348. true
  349. },
  350. {
  351. RelationRelationId,
  352. ClassOidIndexId,
  353. RELOID,
  354. RELNAMENSP,
  355. Anum_pg_class_oid,
  356. Anum_pg_class_relname,
  357. Anum_pg_class_relnamespace,
  358. Anum_pg_class_relowner,
  359. Anum_pg_class_relacl,
  360. OBJECT_TABLE,
  361. true
  362. },
  363. {
  364. TableSpaceRelationId,
  365. TablespaceOidIndexId,
  366. TABLESPACEOID,
  367. -1,
  368. Anum_pg_tablespace_oid,
  369. Anum_pg_tablespace_spcname,
  370. InvalidAttrNumber,
  371. Anum_pg_tablespace_spcowner,
  372. Anum_pg_tablespace_spcacl,
  373. OBJECT_TABLESPACE,
  374. true
  375. },
  376. {
  377. TransformRelationId,
  378. TransformOidIndexId,
  379. TRFOID,
  380. InvalidAttrNumber,
  381. Anum_pg_transform_oid
  382. },
  383. {
  384. TriggerRelationId,
  385. TriggerOidIndexId,
  386. -1,
  387. -1,
  388. Anum_pg_trigger_oid,
  389. Anum_pg_trigger_tgname,
  390. InvalidAttrNumber,
  391. InvalidAttrNumber,
  392. InvalidAttrNumber,
  393. -1,
  394. false
  395. },
  396. {
  397. PolicyRelationId,
  398. PolicyOidIndexId,
  399. -1,
  400. -1,
  401. Anum_pg_policy_oid,
  402. Anum_pg_policy_polname,
  403. InvalidAttrNumber,
  404. InvalidAttrNumber,
  405. InvalidAttrNumber,
  406. -1,
  407. false
  408. },
  409. {
  410. EventTriggerRelationId,
  411. EventTriggerOidIndexId,
  412. EVENTTRIGGEROID,
  413. EVENTTRIGGERNAME,
  414. Anum_pg_event_trigger_oid,
  415. Anum_pg_event_trigger_evtname,
  416. InvalidAttrNumber,
  417. Anum_pg_event_trigger_evtowner,
  418. InvalidAttrNumber,
  419. OBJECT_EVENT_TRIGGER,
  420. true
  421. },
  422. {
  423. TSConfigRelationId,
  424. TSConfigOidIndexId,
  425. TSCONFIGOID,
  426. TSCONFIGNAMENSP,
  427. Anum_pg_ts_config_oid,
  428. Anum_pg_ts_config_cfgname,
  429. Anum_pg_ts_config_cfgnamespace,
  430. Anum_pg_ts_config_cfgowner,
  431. InvalidAttrNumber,
  432. OBJECT_TSCONFIGURATION,
  433. true
  434. },
  435. {
  436. TSDictionaryRelationId,
  437. TSDictionaryOidIndexId,
  438. TSDICTOID,
  439. TSDICTNAMENSP,
  440. Anum_pg_ts_dict_oid,
  441. Anum_pg_ts_dict_dictname,
  442. Anum_pg_ts_dict_dictnamespace,
  443. Anum_pg_ts_dict_dictowner,
  444. InvalidAttrNumber,
  445. OBJECT_TSDICTIONARY,
  446. true
  447. },
  448. {
  449. TSParserRelationId,
  450. TSParserOidIndexId,
  451. TSPARSEROID,
  452. TSPARSERNAMENSP,
  453. Anum_pg_ts_parser_oid,
  454. Anum_pg_ts_parser_prsname,
  455. Anum_pg_ts_parser_prsnamespace,
  456. InvalidAttrNumber,
  457. InvalidAttrNumber,
  458. -1,
  459. true
  460. },
  461. {
  462. TSTemplateRelationId,
  463. TSTemplateOidIndexId,
  464. TSTEMPLATEOID,
  465. TSTEMPLATENAMENSP,
  466. Anum_pg_ts_template_oid,
  467. Anum_pg_ts_template_tmplname,
  468. Anum_pg_ts_template_tmplnamespace,
  469. InvalidAttrNumber,
  470. InvalidAttrNumber,
  471. -1,
  472. true,
  473. },
  474. {
  475. TypeRelationId,
  476. TypeOidIndexId,
  477. TYPEOID,
  478. TYPENAMENSP,
  479. Anum_pg_type_oid,
  480. Anum_pg_type_typname,
  481. Anum_pg_type_typnamespace,
  482. Anum_pg_type_typowner,
  483. Anum_pg_type_typacl,
  484. OBJECT_TYPE,
  485. true
  486. },
  487. {
  488. PublicationRelationId,
  489. PublicationObjectIndexId,
  490. PUBLICATIONOID,
  491. PUBLICATIONNAME,
  492. Anum_pg_publication_oid,
  493. Anum_pg_publication_pubname,
  494. InvalidAttrNumber,
  495. Anum_pg_publication_pubowner,
  496. InvalidAttrNumber,
  497. OBJECT_PUBLICATION,
  498. true
  499. },
  500. {
  501. SubscriptionRelationId,
  502. SubscriptionObjectIndexId,
  503. SUBSCRIPTIONOID,
  504. SUBSCRIPTIONNAME,
  505. Anum_pg_subscription_oid,
  506. Anum_pg_subscription_subname,
  507. InvalidAttrNumber,
  508. Anum_pg_subscription_subowner,
  509. InvalidAttrNumber,
  510. OBJECT_SUBSCRIPTION,
  511. true
  512. },
  513. {
  514. StatisticExtRelationId,
  515. StatisticExtOidIndexId,
  516. STATEXTOID,
  517. STATEXTNAMENSP,
  518. Anum_pg_statistic_ext_oid,
  519. Anum_pg_statistic_ext_stxname,
  520. Anum_pg_statistic_ext_stxnamespace,
  521. Anum_pg_statistic_ext_stxowner,
  522. InvalidAttrNumber, /* no ACL (same as relation) */
  523. OBJECT_STATISTIC_EXT,
  524. true
  525. }
  526. };
  527. /*
  528. * This struct maps the string object types as returned by
  529. * getObjectTypeDescription into ObjectType enum values. Note that some enum
  530. * values can be obtained by different names, and that some string object types
  531. * do not have corresponding values in the output enum. The user of this map
  532. * must be careful to test for invalid values being returned.
  533. *
  534. * To ease maintenance, this follows the order of getObjectTypeDescription.
  535. */
  536. static const struct object_type_map
  537. {
  538. const char *tm_name;
  539. ObjectType tm_type;
  540. }
  541. ObjectTypeMap[] =
  542. {
  543. /* OCLASS_CLASS, all kinds of relations */
  544. {
  545. "table", OBJECT_TABLE
  546. },
  547. {
  548. "index", OBJECT_INDEX
  549. },
  550. {
  551. "sequence", OBJECT_SEQUENCE
  552. },
  553. {
  554. "toast table", -1
  555. }, /* unmapped */
  556. {
  557. "view", OBJECT_VIEW
  558. },
  559. {
  560. "materialized view", OBJECT_MATVIEW
  561. },
  562. {
  563. "composite type", -1
  564. }, /* unmapped */
  565. {
  566. "foreign table", OBJECT_FOREIGN_TABLE
  567. },
  568. {
  569. "table column", OBJECT_COLUMN
  570. },
  571. {
  572. "index column", -1
  573. }, /* unmapped */
  574. {
  575. "sequence column", -1
  576. }, /* unmapped */
  577. {
  578. "toast table column", -1
  579. }, /* unmapped */
  580. {
  581. "view column", -1
  582. }, /* unmapped */
  583. {
  584. "materialized view column", -1
  585. }, /* unmapped */
  586. {
  587. "composite type column", -1
  588. }, /* unmapped */
  589. {
  590. "foreign table column", OBJECT_COLUMN
  591. },
  592. /* OCLASS_PROC */
  593. {
  594. "aggregate", OBJECT_AGGREGATE
  595. },
  596. {
  597. "function", OBJECT_FUNCTION
  598. },
  599. {
  600. "procedure", OBJECT_PROCEDURE
  601. },
  602. /* OCLASS_TYPE */
  603. {
  604. "type", OBJECT_TYPE
  605. },
  606. /* OCLASS_CAST */
  607. {
  608. "cast", OBJECT_CAST
  609. },
  610. /* OCLASS_COLLATION */
  611. {
  612. "collation", OBJECT_COLLATION
  613. },
  614. /* OCLASS_CONSTRAINT */
  615. {
  616. "table constraint", OBJECT_TABCONSTRAINT
  617. },
  618. {
  619. "domain constraint", OBJECT_DOMCONSTRAINT
  620. },
  621. /* OCLASS_CONVERSION */
  622. {
  623. "conversion", OBJECT_CONVERSION
  624. },
  625. /* OCLASS_DEFAULT */
  626. {
  627. "default value", OBJECT_DEFAULT
  628. },
  629. /* OCLASS_LANGUAGE */
  630. {
  631. "language", OBJECT_LANGUAGE
  632. },
  633. /* OCLASS_LARGEOBJECT */
  634. {
  635. "large object", OBJECT_LARGEOBJECT
  636. },
  637. /* OCLASS_OPERATOR */
  638. {
  639. "operator", OBJECT_OPERATOR
  640. },
  641. /* OCLASS_OPCLASS */
  642. {
  643. "operator class", OBJECT_OPCLASS
  644. },
  645. /* OCLASS_OPFAMILY */
  646. {
  647. "operator family", OBJECT_OPFAMILY
  648. },
  649. /* OCLASS_AM */
  650. {
  651. "access method", OBJECT_ACCESS_METHOD
  652. },
  653. /* OCLASS_AMOP */
  654. {
  655. "operator of access method", OBJECT_AMOP
  656. },
  657. /* OCLASS_AMPROC */
  658. {
  659. "function of access method", OBJECT_AMPROC
  660. },
  661. /* OCLASS_REWRITE */
  662. {
  663. "rule", OBJECT_RULE
  664. },
  665. /* OCLASS_TRIGGER */
  666. {
  667. "trigger", OBJECT_TRIGGER
  668. },
  669. /* OCLASS_SCHEMA */
  670. {
  671. "schema", OBJECT_SCHEMA
  672. },
  673. /* OCLASS_TSPARSER */
  674. {
  675. "text search parser", OBJECT_TSPARSER
  676. },
  677. /* OCLASS_TSDICT */
  678. {
  679. "text search dictionary", OBJECT_TSDICTIONARY
  680. },
  681. /* OCLASS_TSTEMPLATE */
  682. {
  683. "text search template", OBJECT_TSTEMPLATE
  684. },
  685. /* OCLASS_TSCONFIG */
  686. {
  687. "text search configuration", OBJECT_TSCONFIGURATION
  688. },
  689. /* OCLASS_ROLE */
  690. {
  691. "role", OBJECT_ROLE
  692. },
  693. /* OCLASS_DATABASE */
  694. {
  695. "database", OBJECT_DATABASE
  696. },
  697. /* OCLASS_TBLSPACE */
  698. {
  699. "tablespace", OBJECT_TABLESPACE
  700. },
  701. /* OCLASS_FDW */
  702. {
  703. "foreign-data wrapper", OBJECT_FDW
  704. },
  705. /* OCLASS_FOREIGN_SERVER */
  706. {
  707. "server", OBJECT_FOREIGN_SERVER
  708. },
  709. /* OCLASS_USER_MAPPING */
  710. {
  711. "user mapping", OBJECT_USER_MAPPING
  712. },
  713. /* OCLASS_DEFACL */
  714. {
  715. "default acl", OBJECT_DEFACL
  716. },
  717. /* OCLASS_EXTENSION */
  718. {
  719. "extension", OBJECT_EXTENSION
  720. },
  721. /* OCLASS_EVENT_TRIGGER */
  722. {
  723. "event trigger", OBJECT_EVENT_TRIGGER
  724. },
  725. /* OCLASS_POLICY */
  726. {
  727. "policy", OBJECT_POLICY
  728. },
  729. /* OCLASS_PUBLICATION */
  730. {
  731. "publication", OBJECT_PUBLICATION
  732. },
  733. /* OCLASS_PUBLICATION_REL */
  734. {
  735. "publication relation", OBJECT_PUBLICATION_REL
  736. },
  737. /* OCLASS_SUBSCRIPTION */
  738. {
  739. "subscription", OBJECT_SUBSCRIPTION
  740. },
  741. /* OCLASS_TRANSFORM */
  742. {
  743. "transform", OBJECT_TRANSFORM
  744. },
  745. /* OCLASS_STATISTIC_EXT */
  746. {
  747. "statistics object", OBJECT_STATISTIC_EXT
  748. }
  749. };
  750. const ObjectAddress InvalidObjectAddress =
  751. {
  752. InvalidOid,
  753. InvalidOid,
  754. 0
  755. };
  756. static ObjectAddress get_object_address_unqualified(ObjectType objtype,
  757. Value *strval, bool missing_ok);
  758. static ObjectAddress get_relation_by_qualified_name(ObjectType objtype,
  759. List *object, Relation *relp,
  760. LOCKMODE lockmode, bool missing_ok);
  761. static ObjectAddress get_object_address_relobject(ObjectType objtype,
  762. List *object, Relation *relp, bool missing_ok);
  763. static ObjectAddress get_object_address_attribute(ObjectType objtype,
  764. List *object, Relation *relp,
  765. LOCKMODE lockmode, bool missing_ok);
  766. static ObjectAddress get_object_address_attrdef(ObjectType objtype,
  767. List *object, Relation *relp, LOCKMODE lockmode,
  768. bool missing_ok);
  769. static ObjectAddress get_object_address_type(ObjectType objtype,
  770. TypeName *typename, bool missing_ok);
  771. static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object,
  772. bool missing_ok);
  773. static ObjectAddress get_object_address_opf_member(ObjectType objtype,
  774. List *object, bool missing_ok);
  775. static ObjectAddress get_object_address_usermapping(List *object,
  776. bool missing_ok);
  777. static ObjectAddress get_object_address_publication_rel(List *object,
  778. Relation *relp,
  779. bool missing_ok);
  780. static ObjectAddress get_object_address_defacl(List *object,
  781. bool missing_ok);
  782. static const ObjectPropertyType *get_object_property_data(Oid class_id);
  783. static void getRelationDescription(StringInfo buffer, Oid relid);
  784. static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
  785. static void getRelationTypeDescription(StringInfo buffer, Oid relid,
  786. int32 objectSubId);
  787. static void getProcedureTypeDescription(StringInfo buffer, Oid procid);
  788. static void getConstraintTypeDescription(StringInfo buffer, Oid constroid);
  789. static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object);
  790. static void getRelationIdentity(StringInfo buffer, Oid relid, List **object);
  791. /*
  792. * Translate an object name and arguments (as passed by the parser) to an
  793. * ObjectAddress.
  794. *
  795. * The returned object will be locked using the specified lockmode. If a
  796. * sub-object is looked up, the parent object will be locked instead.
  797. *
  798. * If the object is a relation or a child object of a relation (e.g. an
  799. * attribute or constraint), the relation is also opened and *relp receives
  800. * the open relcache entry pointer; otherwise, *relp is set to NULL. This
  801. * is a bit grotty but it makes life simpler, since the caller will
  802. * typically need the relcache entry too. Caller must close the relcache
  803. * entry when done with it. The relation is locked with the specified lockmode
  804. * if the target object is the relation itself or an attribute, but for other
  805. * child objects, only AccessShareLock is acquired on the relation.
  806. *
  807. * If the object is not found, an error is thrown, unless missing_ok is
  808. * true. In this case, no lock is acquired, relp is set to NULL, and the
  809. * returned address has objectId set to InvalidOid.
  810. *
  811. * We don't currently provide a function to release the locks acquired here;
  812. * typically, the lock must be held until commit to guard against a concurrent
  813. * drop operation.
  814. *
  815. * Note: If the object is not found, we don't give any indication of the
  816. * reason. (It might have been a missing schema if the name was qualified, or
  817. * a nonexistent type name in case of a cast, function or operator; etc).
  818. * Currently there is only one caller that might be interested in such info, so
  819. * we don't spend much effort here. If more callers start to care, it might be
  820. * better to add some support for that in this function.
  821. */
  822. ObjectAddress
  823. get_object_address(ObjectType objtype, Node *object,
  824. Relation *relp, LOCKMODE lockmode, bool missing_ok)
  825. {
  826. ObjectAddress address;
  827. ObjectAddress old_address = {InvalidOid, InvalidOid, 0};
  828. Relation relation = NULL;
  829. uint64 inval_count;
  830. /* Some kind of lock must be taken. */
  831. Assert(lockmode != NoLock);
  832. for (;;)
  833. {
  834. /*
  835. * Remember this value, so that, after looking up the object name and
  836. * locking it, we can check whether any invalidation messages have
  837. * been processed that might require a do-over.
  838. */
  839. inval_count = SharedInvalidMessageCounter;
  840. /* Look up object address. */
  841. switch (objtype)
  842. {
  843. case OBJECT_INDEX:
  844. case OBJECT_SEQUENCE:
  845. case OBJECT_TABLE:
  846. case OBJECT_VIEW:
  847. case OBJECT_MATVIEW:
  848. case OBJECT_FOREIGN_TABLE:
  849. address =
  850. get_relation_by_qualified_name(objtype, castNode(List, object),
  851. &relation, lockmode,
  852. missing_ok);
  853. break;
  854. case OBJECT_COLUMN:
  855. address =
  856. get_object_address_attribute(objtype, castNode(List, object),
  857. &relation, lockmode,
  858. missing_ok);
  859. break;
  860. case OBJECT_DEFAULT:
  861. address =
  862. get_object_address_attrdef(objtype, castNode(List, object),
  863. &relation, lockmode,
  864. missing_ok);
  865. break;
  866. case OBJECT_RULE:
  867. case OBJECT_TRIGGER:
  868. case OBJECT_TABCONSTRAINT:
  869. case OBJECT_POLICY:
  870. address = get_object_address_relobject(objtype, castNode(List, object),
  871. &relation, missing_ok);
  872. break;
  873. case OBJECT_DOMCONSTRAINT:
  874. {
  875. List *objlist;
  876. ObjectAddress domaddr;
  877. char *constrname;
  878. objlist = castNode(List, object);
  879. domaddr = get_object_address_type(OBJECT_DOMAIN,
  880. linitial_node(TypeName, objlist),
  881. missing_ok);
  882. constrname = strVal(lsecond(objlist));
  883. address.classId = ConstraintRelationId;
  884. address.objectId = get_domain_constraint_oid(domaddr.objectId,
  885. constrname, missing_ok);
  886. address.objectSubId = 0;
  887. }
  888. break;
  889. case OBJECT_DATABASE:
  890. case OBJECT_EXTENSION:
  891. case OBJECT_TABLESPACE:
  892. case OBJECT_ROLE:
  893. case OBJECT_SCHEMA:
  894. case OBJECT_LANGUAGE:
  895. case OBJECT_FDW:
  896. case OBJECT_FOREIGN_SERVER:
  897. case OBJECT_EVENT_TRIGGER:
  898. case OBJECT_ACCESS_METHOD:
  899. case OBJECT_PUBLICATION:
  900. case OBJECT_SUBSCRIPTION:
  901. address = get_object_address_unqualified(objtype,
  902. (Value *) object, missing_ok);
  903. break;
  904. case OBJECT_TYPE:
  905. case OBJECT_DOMAIN:
  906. address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
  907. break;
  908. case OBJECT_AGGREGATE:
  909. case OBJECT_FUNCTION:
  910. case OBJECT_PROCEDURE:
  911. case OBJECT_ROUTINE:
  912. address.classId = ProcedureRelationId;
  913. address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
  914. address.objectSubId = 0;
  915. break;
  916. case OBJECT_OPERATOR:
  917. address.classId = OperatorRelationId;
  918. address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
  919. address.objectSubId = 0;
  920. break;
  921. case OBJECT_COLLATION:
  922. address.classId = CollationRelationId;
  923. address.objectId = get_collation_oid(castNode(List, object), missing_ok);
  924. address.objectSubId = 0;
  925. break;
  926. case OBJECT_CONVERSION:
  927. address.classId = ConversionRelationId;
  928. address.objectId = get_conversion_oid(castNode(List, object), missing_ok);
  929. address.objectSubId = 0;
  930. break;
  931. case OBJECT_OPCLASS:
  932. case OBJECT_OPFAMILY:
  933. address = get_object_address_opcf(objtype, castNode(List, object), missing_ok);
  934. break;
  935. case OBJECT_AMOP:
  936. case OBJECT_AMPROC:
  937. address = get_object_address_opf_member(objtype, castNode(List, object), missing_ok);
  938. break;
  939. case OBJECT_LARGEOBJECT:
  940. address.classId = LargeObjectRelationId;
  941. address.objectId = oidparse(object);
  942. address.objectSubId = 0;
  943. if (!LargeObjectExists(address.objectId))
  944. {
  945. if (!missing_ok)
  946. ereport(ERROR,
  947. (errcode(ERRCODE_UNDEFINED_OBJECT),
  948. errmsg("large object %u does not exist",
  949. address.objectId)));
  950. }
  951. break;
  952. case OBJECT_CAST:
  953. {
  954. TypeName *sourcetype = linitial_node(TypeName, castNode(List, object));
  955. TypeName *targettype = lsecond_node(TypeName, castNode(List, object));
  956. Oid sourcetypeid;
  957. Oid targettypeid;
  958. sourcetypeid = LookupTypeNameOid(NULL, sourcetype, missing_ok);
  959. targettypeid = LookupTypeNameOid(NULL, targettype, missing_ok);
  960. address.classId = CastRelationId;
  961. address.objectId =
  962. get_cast_oid(sourcetypeid, targettypeid, missing_ok);
  963. address.objectSubId = 0;
  964. }
  965. break;
  966. case OBJECT_TRANSFORM:
  967. {
  968. TypeName *typename = linitial_node(TypeName, castNode(List, object));
  969. char *langname = strVal(lsecond(castNode(List, object)));
  970. Oid type_id = LookupTypeNameOid(NULL, typename, missing_ok);
  971. Oid lang_id = get_language_oid(langname, missing_ok);
  972. address.classId = TransformRelationId;
  973. address.objectId =
  974. get_transform_oid(type_id, lang_id, missing_ok);
  975. address.objectSubId = 0;
  976. }
  977. break;
  978. case OBJECT_TSPARSER:
  979. address.classId = TSParserRelationId;
  980. address.objectId = get_ts_parser_oid(castNode(List, object), missing_ok);
  981. address.objectSubId = 0;
  982. break;
  983. case OBJECT_TSDICTIONARY:
  984. address.classId = TSDictionaryRelationId;
  985. address.objectId = get_ts_dict_oid(castNode(List, object), missing_ok);
  986. address.objectSubId = 0;
  987. break;
  988. case OBJECT_TSTEMPLATE:
  989. address.classId = TSTemplateRelationId;
  990. address.objectId = get_ts_template_oid(castNode(List, object), missing_ok);
  991. address.objectSubId = 0;
  992. break;
  993. case OBJECT_TSCONFIGURATION:
  994. address.classId = TSConfigRelationId;
  995. address.objectId = get_ts_config_oid(castNode(List, object), missing_ok);
  996. address.objectSubId = 0;
  997. break;
  998. case OBJECT_USER_MAPPING:
  999. address = get_object_address_usermapping(castNode(List, object),
  1000. missing_ok);
  1001. break;
  1002. case OBJECT_PUBLICATION_REL:
  1003. address = get_object_address_publication_rel(castNode(List, object),
  1004. &relation,
  1005. missing_ok);
  1006. break;
  1007. case OBJECT_DEFACL:
  1008. address = get_object_address_defacl(castNode(List, object),
  1009. missing_ok);
  1010. break;
  1011. case OBJECT_STATISTIC_EXT:
  1012. address.classId = StatisticExtRelationId;
  1013. address.objectId = get_statistics_object_oid(castNode(List, object),
  1014. missing_ok);
  1015. address.objectSubId = 0;
  1016. break;
  1017. default:
  1018. elog(ERROR, "unrecognized objtype: %d", (int) objtype);
  1019. /* placate compiler, in case it thinks elog might return */
  1020. address.classId = InvalidOid;
  1021. address.objectId = InvalidOid;
  1022. address.objectSubId = 0;
  1023. }
  1024. /*
  1025. * If we could not find the supplied object, return without locking.
  1026. */
  1027. if (!OidIsValid(address.objectId))
  1028. {
  1029. Assert(missing_ok);
  1030. return address;
  1031. }
  1032. /*
  1033. * If we're retrying, see if we got the same answer as last time. If
  1034. * so, we're done; if not, we locked the wrong thing, so give up our
  1035. * lock.
  1036. */
  1037. if (OidIsValid(old_address.classId))
  1038. {
  1039. if (old_address.classId == address.classId
  1040. && old_address.objectId == address.objectId
  1041. && old_address.objectSubId == address.objectSubId)
  1042. break;
  1043. if (old_address.classId != RelationRelationId)
  1044. {
  1045. if (IsSharedRelation(old_address.classId))
  1046. UnlockSharedObject(old_address.classId,
  1047. old_address.objectId,
  1048. 0, lockmode);
  1049. else
  1050. UnlockDatabaseObject(old_address.classId,
  1051. old_address.objectId,
  1052. 0, lockmode);
  1053. }
  1054. }
  1055. /*
  1056. * If we're dealing with a relation or attribute, then the relation is
  1057. * already locked. Otherwise, we lock it now.
  1058. */
  1059. if (address.classId != RelationRelationId)
  1060. {
  1061. if (IsSharedRelation(address.classId))
  1062. LockSharedObject(address.classId, address.objectId, 0,
  1063. lockmode);
  1064. else
  1065. LockDatabaseObject(address.classId, address.objectId, 0,
  1066. lockmode);
  1067. }
  1068. /*
  1069. * At this point, we've resolved the name to an OID and locked the
  1070. * corresponding database object. However, it's possible that by the
  1071. * time we acquire the lock on the object, concurrent DDL has modified
  1072. * the database in such a way that the name we originally looked up no
  1073. * longer resolves to that OID.
  1074. *
  1075. * We can be certain that this isn't an issue if (a) no shared
  1076. * invalidation messages have been processed or (b) we've locked a
  1077. * relation somewhere along the line. All the relation name lookups
  1078. * in this module ultimately use RangeVarGetRelid() to acquire a
  1079. * relation lock, and that function protects against the same kinds of
  1080. * races we're worried about here. Even when operating on a
  1081. * constraint, rule, or trigger, we still acquire AccessShareLock on
  1082. * the relation, which is enough to freeze out any concurrent DDL.
  1083. *
  1084. * In all other cases, however, it's possible that the name we looked
  1085. * up no longer refers to the object we locked, so we retry the lookup
  1086. * and see whether we get the same answer.
  1087. */
  1088. if (inval_count == SharedInvalidMessageCounter || relation != NULL)
  1089. break;
  1090. old_address = address;
  1091. }
  1092. /* Return the object address and the relation. */
  1093. *relp = relation;
  1094. return address;
  1095. }
  1096. /*
  1097. * Return an ObjectAddress based on a RangeVar and an object name. The
  1098. * name of the relation identified by the RangeVar is prepended to the
  1099. * (possibly empty) list passed in as object. This is useful to find
  1100. * the ObjectAddress of objects that depend on a relation. All other
  1101. * considerations are exactly as for get_object_address above.
  1102. */
  1103. ObjectAddress
  1104. get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object,
  1105. Relation *relp, LOCKMODE lockmode,
  1106. bool missing_ok)
  1107. {
  1108. if (rel)
  1109. {
  1110. object = lcons(makeString(rel->relname), object);
  1111. if (rel->schemaname)
  1112. object = lcons(makeString(rel->schemaname), object);
  1113. if (rel->catalogname)
  1114. object = lcons(makeString(rel->catalogname), object);
  1115. }
  1116. return get_object_address(objtype, (Node *) object,
  1117. relp, lockmode, missing_ok);
  1118. }
  1119. /*
  1120. * Find an ObjectAddress for a type of object that is identified by an
  1121. * unqualified name.
  1122. */
  1123. static ObjectAddress
  1124. get_object_address_unqualified(ObjectType objtype,
  1125. Value *strval, bool missing_ok)
  1126. {
  1127. const char *name;
  1128. ObjectAddress address;
  1129. name = strVal(strval);
  1130. /* Translate name to OID. */
  1131. switch (objtype)
  1132. {
  1133. case OBJECT_ACCESS_METHOD:
  1134. address.classId = AccessMethodRelationId;
  1135. address.objectId = get_am_oid(name, missing_ok);
  1136. address.objectSubId = 0;
  1137. break;
  1138. case OBJECT_DATABASE:
  1139. address.classId = DatabaseRelationId;
  1140. address.objectId = get_database_oid(name, missing_ok);
  1141. address.objectSubId = 0;
  1142. break;
  1143. case OBJECT_EXTENSION:
  1144. address.classId = ExtensionRelationId;
  1145. address.objectId = get_extension_oid(name, missing_ok);
  1146. address.objectSubId = 0;
  1147. break;
  1148. case OBJECT_TABLESPACE:
  1149. address.classId = TableSpaceRelationId;
  1150. address.objectId = get_tablespace_oid(name, missing_ok);
  1151. address.objectSubId = 0;
  1152. break;
  1153. case OBJECT_ROLE:
  1154. address.classId = AuthIdRelationId;
  1155. address.objectId = get_role_oid(name, missing_ok);
  1156. address.objectSubId = 0;
  1157. break;
  1158. case OBJECT_SCHEMA:
  1159. address.classId = NamespaceRelationId;
  1160. address.objectId = get_namespace_oid(name, missing_ok);
  1161. address.objectSubId = 0;
  1162. break;
  1163. case OBJECT_LANGUAGE:
  1164. address.classId = LanguageRelationId;
  1165. address.objectId = get_language_oid(name, missing_ok);
  1166. address.objectSubId = 0;
  1167. break;
  1168. case OBJECT_FDW:
  1169. address.classId = ForeignDataWrapperRelationId;
  1170. address.objectId = get_foreign_data_wrapper_oid(name, missing_ok);
  1171. address.objectSubId = 0;
  1172. break;
  1173. case OBJECT_FOREIGN_SERVER:
  1174. address.classId = ForeignServerRelationId;
  1175. address.objectId = get_foreign_server_oid(name, missing_ok);
  1176. address.objectSubId = 0;
  1177. break;
  1178. case OBJECT_EVENT_TRIGGER:
  1179. address.classId = EventTriggerRelationId;
  1180. address.objectId = get_event_trigger_oid(name, missing_ok);
  1181. address.objectSubId = 0;
  1182. break;
  1183. case OBJECT_PUBLICATION:
  1184. address.classId = PublicationRelationId;
  1185. address.objectId = get_publication_oid(name, missing_ok);
  1186. address.objectSubId = 0;
  1187. break;
  1188. case OBJECT_SUBSCRIPTION:
  1189. address.classId = SubscriptionRelationId;
  1190. address.objectId = get_subscription_oid(name, missing_ok);
  1191. address.objectSubId = 0;
  1192. break;
  1193. default:
  1194. elog(ERROR, "unrecognized objtype: %d", (int) objtype);
  1195. /* placate compiler, which doesn't know elog won't return */
  1196. address.classId = InvalidOid;
  1197. address.objectId = InvalidOid;
  1198. address.objectSubId = 0;
  1199. }
  1200. return address;
  1201. }
  1202. /*
  1203. * Locate a relation by qualified name.
  1204. */
  1205. static ObjectAddress
  1206. get_relation_by_qualified_name(ObjectType objtype, List *object,
  1207. Relation *relp, LOCKMODE lockmode,
  1208. bool missing_ok)
  1209. {
  1210. Relation relation;
  1211. ObjectAddress address;
  1212. address.classId = RelationRelationId;
  1213. address.objectId = InvalidOid;
  1214. address.objectSubId = 0;
  1215. relation = relation_openrv_extended(makeRangeVarFromNameList(object),
  1216. lockmode, missing_ok);
  1217. if (!relation)
  1218. return address;
  1219. switch (objtype)
  1220. {
  1221. case OBJECT_INDEX:
  1222. if (relation->rd_rel->relkind != RELKIND_INDEX &&
  1223. relation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
  1224. ereport(ERROR,
  1225. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1226. errmsg("\"%s\" is not an index",
  1227. RelationGetRelationName(relation))));
  1228. break;
  1229. case OBJECT_SEQUENCE:
  1230. if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
  1231. ereport(ERROR,
  1232. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1233. errmsg("\"%s\" is not a sequence",
  1234. RelationGetRelationName(relation))));
  1235. break;
  1236. case OBJECT_TABLE:
  1237. if (relation->rd_rel->relkind != RELKIND_RELATION &&
  1238. relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
  1239. ereport(ERROR,
  1240. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1241. errmsg("\"%s\" is not a table",
  1242. RelationGetRelationName(relation))));
  1243. break;
  1244. case OBJECT_VIEW:
  1245. if (relation->rd_rel->relkind != RELKIND_VIEW)
  1246. ereport(ERROR,
  1247. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1248. errmsg("\"%s\" is not a view",
  1249. RelationGetRelationName(relation))));
  1250. break;
  1251. case OBJECT_MATVIEW:
  1252. if (relation->rd_rel->relkind != RELKIND_MATVIEW)
  1253. ereport(ERROR,
  1254. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1255. errmsg("\"%s\" is not a materialized view",
  1256. RelationGetRelationName(relation))));
  1257. break;
  1258. case OBJECT_FOREIGN_TABLE:
  1259. if (relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
  1260. ereport(ERROR,
  1261. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1262. errmsg("\"%s\" is not a foreign table",
  1263. RelationGetRelationName(relation))));
  1264. break;
  1265. default:
  1266. elog(ERROR, "unrecognized objtype: %d", (int) objtype);
  1267. break;
  1268. }
  1269. /* Done. */
  1270. address.objectId = RelationGetRelid(relation);
  1271. *relp = relation;
  1272. return address;
  1273. }
  1274. /*
  1275. * Find object address for an object that is attached to a relation.
  1276. *
  1277. * Note that we take only an AccessShareLock on the relation. We need not
  1278. * pass down the LOCKMODE from get_object_address(), because that is the lock
  1279. * mode for the object itself, not the relation to which it is attached.
  1280. */
  1281. static ObjectAddress
  1282. get_object_address_relobject(ObjectType objtype, List *object,
  1283. Relation *relp, bool missing_ok)
  1284. {
  1285. ObjectAddress address;
  1286. Relation relation = NULL;
  1287. int nnames;
  1288. const char *depname;
  1289. List *relname;
  1290. Oid reloid;
  1291. /* Extract name of dependent object. */
  1292. depname = strVal(llast(object));
  1293. /* Separate relation name from dependent object name. */
  1294. nnames = list_length(object);
  1295. if (nnames < 2)
  1296. ereport(ERROR,
  1297. (errcode(ERRCODE_SYNTAX_ERROR),
  1298. errmsg("must specify relation and object name")));
  1299. /* Extract relation name and open relation. */
  1300. relname = list_truncate(list_copy(object), nnames - 1);
  1301. relation = table_openrv_extended(makeRangeVarFromNameList(relname),
  1302. AccessShareLock,
  1303. missing_ok);
  1304. reloid = relation ? RelationGetRelid(relation) : InvalidOid;
  1305. switch (objtype)
  1306. {
  1307. case OBJECT_RULE:
  1308. address.classId = RewriteRelationId;
  1309. address.objectId = relation ?
  1310. get_rewrite_oid(reloid, depname, missing_ok) : InvalidOid;
  1311. address.objectSubId = 0;
  1312. break;
  1313. case OBJECT_TRIGGER:
  1314. address.classId = TriggerRelationId;
  1315. address.objectId = relation ?
  1316. get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
  1317. address.objectSubId = 0;
  1318. break;
  1319. case OBJECT_TABCONSTRAINT:
  1320. address.classId = ConstraintRelationId;
  1321. address.objectId = relation ?
  1322. get_relation_constraint_oid(reloid, depname, missing_ok) :
  1323. InvalidOid;
  1324. address.objectSubId = 0;
  1325. break;
  1326. case OBJECT_POLICY:
  1327. address.classId = PolicyRelationId;
  1328. address.objectId = relation ?
  1329. get_relation_policy_oid(reloid, depname, missing_ok) :
  1330. InvalidOid;
  1331. address.objectSubId = 0;
  1332. break;
  1333. default:
  1334. elog(ERROR, "unrecognized objtype: %d", (int) objtype);
  1335. }
  1336. /* Avoid relcache leak when object not found. */
  1337. if (!OidIsValid(address.objectId))
  1338. {
  1339. if (relation != NULL)
  1340. table_close(relation, AccessShareLock);
  1341. relation = NULL; /* department of accident prevention */
  1342. return address;
  1343. }
  1344. /* Done. */
  1345. *relp = relation;
  1346. return address;
  1347. }
  1348. /*
  1349. * Find the ObjectAddress for an attribute.
  1350. */
  1351. static ObjectAddress
  1352. get_object_address_attribute(ObjectType objtype, List *object,
  1353. Relation *relp, LOCKMODE lockmode,
  1354. bool missing_ok)
  1355. {
  1356. ObjectAddress address;
  1357. List *relname;
  1358. Oid reloid;
  1359. Relation relation;
  1360. const char *attname;
  1361. AttrNumber attnum;
  1362. /* Extract relation name and open relation. */
  1363. if (list_length(object) < 2)
  1364. ereport(ERROR,
  1365. (errcode(ERRCODE_SYNTAX_ERROR),
  1366. errmsg("column name must be qualified")));
  1367. attname = strVal(lfirst(list_tail(object)));
  1368. relname = list_truncate(list_copy(object), list_length(object) - 1);
  1369. /* XXX no missing_ok support here */
  1370. relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
  1371. reloid = RelationGetRelid(relation);
  1372. /* Look up attribute and construct return value. */
  1373. attnum = get_attnum(reloid, attname);
  1374. if (attnum == InvalidAttrNumber)
  1375. {
  1376. if (!missing_ok)
  1377. ereport(ERROR,
  1378. (errcode(ERRCODE_UNDEFINED_COLUMN),
  1379. errmsg("column \"%s\" of relation \"%s\" does not exist",
  1380. attname, NameListToString(relname))));
  1381. address.classId = RelationRelationId;
  1382. address.objectId = InvalidOid;
  1383. address.objectSubId = InvalidAttrNumber;
  1384. relation_close(relation, lockmode);
  1385. return address;
  1386. }
  1387. address.classId = RelationRelationId;
  1388. address.objectId = reloid;
  1389. address.objectSubId = attnum;
  1390. *relp = relation;
  1391. return address;
  1392. }
  1393. /*
  1394. * Find the ObjectAddress for an attribute's default value.
  1395. */
  1396. static ObjectAddress
  1397. get_object_address_attrdef(ObjectType objtype, List *object,
  1398. Relation *relp, LOCKMODE lockmode,
  1399. bool missing_ok)
  1400. {
  1401. ObjectAddress address;
  1402. List *relname;
  1403. Oid reloid;
  1404. Relation relation;
  1405. const char *attname;
  1406. AttrNumber attnum;
  1407. TupleDesc tupdesc;
  1408. Oid defoid;
  1409. /* Extract relation name and open relation. */
  1410. if (list_length(object) < 2)
  1411. ereport(ERROR,
  1412. (errcode(ERRCODE_SYNTAX_ERROR),
  1413. errmsg("column name must be qualified")));
  1414. attname = strVal(llast(object));
  1415. relname = list_truncate(list_copy(object), list_length(object) - 1);
  1416. /* XXX no missing_ok support here */
  1417. relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode);
  1418. reloid = RelationGetRelid(relation);
  1419. tupdesc = RelationGetDescr(relation);
  1420. /* Look up attribute number and scan pg_attrdef to find its tuple */
  1421. attnum = get_attnum(reloid, attname);
  1422. defoid = InvalidOid;
  1423. if (attnum != InvalidAttrNumber && tupdesc->constr != NULL)
  1424. {
  1425. Relation attrdef;
  1426. ScanKeyData keys[2];
  1427. SysScanDesc scan;
  1428. HeapTuple tup;
  1429. attrdef = relation_open(AttrDefaultRelationId, AccessShareLock);
  1430. ScanKeyInit(&keys[0],
  1431. Anum_pg_attrdef_adrelid,
  1432. BTEqualStrategyNumber,
  1433. F_OIDEQ,
  1434. ObjectIdGetDatum(reloid));
  1435. ScanKeyInit(&keys[1],
  1436. Anum_pg_attrdef_adnum,
  1437. BTEqualStrategyNumber,
  1438. F_INT2EQ,
  1439. Int16GetDatum(attnum));
  1440. scan = systable_beginscan(attrdef, AttrDefaultIndexId, true,
  1441. NULL, 2, keys);
  1442. if (HeapTupleIsValid(tup = systable_getnext(scan)))
  1443. {
  1444. Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup);
  1445. defoid = atdform->oid;
  1446. }
  1447. systable_endscan(scan);
  1448. relation_close(attrdef, AccessShareLock);
  1449. }
  1450. if (!OidIsValid(defoid))
  1451. {
  1452. if (!missing_ok)
  1453. ereport(ERROR,
  1454. (errcode(ERRCODE_UNDEFINED_COLUMN),
  1455. errmsg("default value for column \"%s\" of relation \"%s\" does not exist",
  1456. attname, NameListToString(relname))));
  1457. address.classId = AttrDefaultRelationId;
  1458. address.objectId = InvalidOid;
  1459. address.objectSubId = InvalidAttrNumber;
  1460. relation_close(relation, lockmode);
  1461. return address;
  1462. }
  1463. address.classId = AttrDefaultRelationId;
  1464. address.objectId = defoid;
  1465. address.objectSubId = 0;
  1466. *relp = relation;
  1467. return address;
  1468. }
  1469. /*
  1470. * Find the ObjectAddress for a type or domain
  1471. */
  1472. static ObjectAddress
  1473. get_object_address_type(ObjectType objtype, TypeName *typename, bool missing_ok)
  1474. {
  1475. ObjectAddress address;
  1476. Type tup;
  1477. address.classId = TypeRelationId;
  1478. address.objectId = InvalidOid;
  1479. address.objectSubId = 0;
  1480. tup = LookupTypeName(NULL, typename, NULL, missing_ok);
  1481. if (!HeapTupleIsValid(tup))
  1482. {
  1483. if (!missing_ok)
  1484. ereport(ERROR,
  1485. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1486. errmsg("type \"%s\" does not exist",
  1487. TypeNameToString(typename))));
  1488. return address;
  1489. }
  1490. address.objectId = typeTypeId(tup);
  1491. if (objtype == OBJECT_DOMAIN)
  1492. {
  1493. if (((Form_pg_type) GETSTRUCT(tup))->typtype != TYPTYPE_DOMAIN)
  1494. ereport(ERROR,
  1495. (errcode(ERRCODE_WRONG_OBJECT_TYPE),
  1496. errmsg("\"%s\" is not a domain",
  1497. TypeNameToString(typename))));
  1498. }
  1499. ReleaseSysCache(tup);
  1500. return address;
  1501. }
  1502. /*
  1503. * Find the ObjectAddress for an opclass or opfamily.
  1504. */
  1505. static ObjectAddress
  1506. get_object_address_opcf(ObjectType objtype, List *object, bool missing_ok)
  1507. {
  1508. Oid amoid;
  1509. ObjectAddress address;
  1510. /* XXX no missing_ok support here */
  1511. amoid = get_index_am_oid(strVal(linitial(object)), false);
  1512. object = list_copy_tail(object, 1);
  1513. switch (objtype)
  1514. {
  1515. case OBJECT_OPCLASS:
  1516. address.classId = OperatorClassRelationId;
  1517. address.objectId = get_opclass_oid(amoid, object, missing_ok);
  1518. address.objectSubId = 0;
  1519. break;
  1520. case OBJECT_OPFAMILY:
  1521. address.classId = OperatorFamilyRelationId;
  1522. address.objectId = get_opfamily_oid(amoid, object, missing_ok);
  1523. address.objectSubId = 0;
  1524. break;
  1525. default:
  1526. elog(ERROR, "unrecognized objtype: %d", (int) objtype);
  1527. /* placate compiler, which doesn't know elog won't return */
  1528. address.classId = InvalidOid;
  1529. address.objectId = InvalidOid;
  1530. address.objectSubId = 0;
  1531. }
  1532. return address;
  1533. }
  1534. /*
  1535. * Find the ObjectAddress for an opclass/opfamily member.
  1536. *
  1537. * (The returned address corresponds to a pg_amop/pg_amproc object).
  1538. */
  1539. static ObjectAddress
  1540. get_object_address_opf_member(ObjectType objtype,
  1541. List *object, bool missing_ok)
  1542. {
  1543. ObjectAddress famaddr;
  1544. ObjectAddress address;
  1545. ListCell *cell;
  1546. List *copy;
  1547. TypeName *typenames[2];
  1548. Oid typeoids[2];
  1549. int membernum;
  1550. int i;
  1551. /*
  1552. * The last element of the object list contains the strategy or procedure
  1553. * number. We need to strip that out before getting the opclass/family
  1554. * address. The rest can be used directly by get_object_address_opcf().
  1555. */
  1556. membernum = atoi(strVal(llast(linitial(object))));
  1557. copy = list_truncate(list_copy(linitial(object)), list_length(linitial(object)) - 1);
  1558. /* no missing_ok support here */
  1559. famaddr = get_object_address_opcf(OBJECT_OPFAMILY, copy, false);
  1560. /* find out left/right type names and OIDs */
  1561. typenames[0] = typenames[1] = NULL;
  1562. typeoids[0] = typeoids[1] = InvalidOid;
  1563. i = 0;
  1564. foreach(cell, lsecond(object))
  1565. {
  1566. ObjectAddress typaddr;
  1567. typenames[i] = lfirst_node(TypeName, cell);
  1568. typaddr = get_object_address_type(OBJECT_TYPE, typenames[i], missing_ok);
  1569. typeoids[i] = typaddr.objectId;
  1570. if (++i >= 2)
  1571. break;
  1572. }
  1573. switch (objtype)
  1574. {
  1575. case OBJECT_AMOP:
  1576. {
  1577. HeapTuple tp;
  1578. ObjectAddressSet(address, AccessMethodOperatorRelationId,
  1579. InvalidOid);
  1580. tp = SearchSysCache4(AMOPSTRATEGY,
  1581. ObjectIdGetDatum(famaddr.objectId),
  1582. ObjectIdGetDatum(typeoids[0]),
  1583. ObjectIdGetDatum(typeoids[1]),
  1584. Int16GetDatum(membernum));
  1585. if (!HeapTupleIsValid(tp))
  1586. {
  1587. if (!missing_ok)
  1588. ereport(ERROR,
  1589. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1590. errmsg("operator %d (%s, %s) of %s does not exist",
  1591. membernum,
  1592. TypeNameToString(typenames[0]),
  1593. TypeNameToString(typenames[1]),
  1594. getObjectDescription(&famaddr))));
  1595. }
  1596. else
  1597. {
  1598. address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid;
  1599. ReleaseSysCache(tp);
  1600. }
  1601. }
  1602. break;
  1603. case OBJECT_AMPROC:
  1604. {
  1605. HeapTuple tp;
  1606. ObjectAddressSet(address, AccessMethodProcedureRelationId,
  1607. InvalidOid);
  1608. tp = SearchSysCache4(AMPROCNUM,
  1609. ObjectIdGetDatum(famaddr.objectId),
  1610. ObjectIdGetDatum(typeoids[0]),
  1611. ObjectIdGetDatum(typeoids[1]),
  1612. Int16GetDatum(membernum));
  1613. if (!HeapTupleIsValid(tp))
  1614. {
  1615. if (!missing_ok)
  1616. ereport(ERROR,
  1617. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1618. errmsg("function %d (%s, %s) of %s does not exist",
  1619. membernum,
  1620. TypeNameToString(typenames[0]),
  1621. TypeNameToString(typenames[1]),
  1622. getObjectDescription(&famaddr))));
  1623. }
  1624. else
  1625. {
  1626. address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid;
  1627. ReleaseSysCache(tp);
  1628. }
  1629. }
  1630. break;
  1631. default:
  1632. elog(ERROR, "unrecognized objtype: %d", (int) objtype);
  1633. }
  1634. return address;
  1635. }
  1636. /*
  1637. * Find the ObjectAddress for a user mapping.
  1638. */
  1639. static ObjectAddress
  1640. get_object_address_usermapping(List *object, bool missing_ok)
  1641. {
  1642. ObjectAddress address;
  1643. Oid userid;
  1644. char *username;
  1645. char *servername;
  1646. ForeignServer *server;
  1647. HeapTuple tp;
  1648. ObjectAddressSet(address, UserMappingRelationId, InvalidOid);
  1649. /* fetch string names from input lists, for error messages */
  1650. username = strVal(linitial(object));
  1651. servername = strVal(lsecond(object));
  1652. /* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
  1653. if (strcmp(username, "public") == 0)
  1654. userid = InvalidOid;
  1655. else
  1656. {
  1657. tp = SearchSysCache1(AUTHNAME,
  1658. CStringGetDatum(username));
  1659. if (!HeapTupleIsValid(tp))
  1660. {
  1661. if (!missing_ok)
  1662. ereport(ERROR,
  1663. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1664. errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
  1665. username, servername)));
  1666. return address;
  1667. }
  1668. userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
  1669. ReleaseSysCache(tp);
  1670. }
  1671. /* Now look up the pg_user_mapping tuple */
  1672. server = GetForeignServerByName(servername, true);
  1673. if (!server)
  1674. {
  1675. if (!missing_ok)
  1676. ereport(ERROR,
  1677. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1678. errmsg("server \"%s\" does not exist", servername)));
  1679. return address;
  1680. }
  1681. tp = SearchSysCache2(USERMAPPINGUSERSERVER,
  1682. ObjectIdGetDatum(userid),
  1683. ObjectIdGetDatum(server->serverid));
  1684. if (!HeapTupleIsValid(tp))
  1685. {
  1686. if (!missing_ok)
  1687. ereport(ERROR,
  1688. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1689. errmsg("user mapping for user \"%s\" on server \"%s\" does not exist",
  1690. username, servername)));
  1691. return address;
  1692. }
  1693. address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
  1694. ReleaseSysCache(tp);
  1695. return address;
  1696. }
  1697. /*
  1698. * Find the ObjectAddress for a publication relation. The first element of
  1699. * the object parameter is the relation name, the second is the
  1700. * publication name.
  1701. */
  1702. static ObjectAddress
  1703. get_object_address_publication_rel(List *object,
  1704. Relation *relp, bool missing_ok)
  1705. {
  1706. ObjectAddress address;
  1707. Relation relation;
  1708. List *relname;
  1709. char *pubname;
  1710. Publication *pub;
  1711. ObjectAddressSet(address, PublicationRelRelationId, InvalidOid);
  1712. relname = linitial(object);
  1713. relation = relation_openrv_extended(makeRangeVarFromNameList(relname),
  1714. AccessShareLock, missing_ok);
  1715. if (!relation)
  1716. return address;
  1717. /* fetch publication name from input list */
  1718. pubname = strVal(lsecond(object));
  1719. /* Now look up the pg_publication tuple */
  1720. pub = GetPublicationByName(pubname, missing_ok);
  1721. if (!pub)
  1722. {
  1723. relation_close(relation, AccessShareLock);
  1724. return address;
  1725. }
  1726. /* Find the publication relation mapping in syscache. */
  1727. address.objectId =
  1728. GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid,
  1729. ObjectIdGetDatum(RelationGetRelid(relation)),
  1730. ObjectIdGetDatum(pub->oid));
  1731. if (!OidIsValid(address.objectId))
  1732. {
  1733. if (!missing_ok)
  1734. ereport(ERROR,
  1735. (errcode(ERRCODE_UNDEFINED_OBJECT),
  1736. errmsg("publication relation \"%s\" in publication \"%s\" does not exist",
  1737. RelationGetRelationName(relation), pubname)));
  1738. relation_close(relation, AccessShareLock);
  1739. return address;
  1740. }
  1741. *relp = relation;
  1742. return address;
  1743. }
  1744. /*
  1745. * Find the ObjectAddress for a default ACL.
  1746. */
  1747. static ObjectAddress
  1748. get_object_address_defacl(List *object, bool missing_ok)
  1749. {
  1750. HeapTuple tp;
  1751. Oid userid;
  1752. Oid schemaid;
  1753. char *username;
  1754. char *schema;
  1755. char objtype;
  1756. char *objtype_str;
  1757. ObjectAddress address;
  1758. ObjectAddressSet(address, DefaultAclRelationId, InvalidOid);
  1759. /*
  1760. * First figure out the textual attributes so that they can be used for
  1761. * error reporting.
  1762. */
  1763. username = strVal(lsecond(object));
  1764. if (list_length(object) >= 3)
  1765. schema = (char *) strVal(lthird(object));
  1766. else
  1767. schema = NULL;
  1768. /*
  1769. * Decode defaclobjtype. Only first char is considered; the rest of the
  1770. * string, if any, is blissfully ignored.
  1771. */
  1772. objtype = ((char *) strVal(linitial(object)))[0];
  1773. switch (objtype)
  1774. {
  1775. case DEFACLOBJ_RELATION:
  1776. objtype_str = "tables";
  1777. break;
  1778. case DEFACLOBJ_SEQUENCE:
  1779. objtype_str = "sequences";
  1780. break;
  1781. case DEFACLOBJ_FUNCTION:
  1782. objtype_str = "functions";
  1783. break;
  1784. case DEFACLOBJ_TYPE:
  1785. objtype_str = "types";
  1786. break;
  1787. case DEFACLOBJ_NAMESPACE:
  1788. objtype_str = "schemas";
  1789. break;
  1790. default:
  1791. ereport(ERROR,
  1792. (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  1793. errmsg("unrecognized default ACL object type \"%c\"", objtype),
  1794. errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".",
  1795. DEFACLOBJ_RELATION,
  1796. DEFACLOBJ_SEQUENCE,
  1797. DEFACLOBJ_FUNCTION,
  1798. DEFACLOBJ_TYPE,
  1799. DEFACLOBJ_NAMESPACE)));
  1800. }
  1801. /*
  1802. * Look up user ID. Behave as "default ACL not found" if the user doesn't
  1803. * exist.
  1804. */
  1805. tp = SearchSysCache1(AUTHNAME,
  1806. CStringGetDatum(username));
  1807. if (!HeapTupleIsValid(tp))

Large files files are truncated, but you can click here to view the full file