6666#include "utils/syscache.h"
6767#include "utils/tqual.h"
6868
69- static ObjectAddress get_object_address_unqualified (ObjectType objtype ,
70- List * qualname ,bool missing_ok );
71- static ObjectAddress get_relation_by_qualified_name (ObjectType objtype ,
72- List * objname ,Relation * relp ,
73- LOCKMODE lockmode ,bool missing_ok );
74- static ObjectAddress get_object_address_relobject (ObjectType objtype ,
75- List * objname ,Relation * relp ,bool missing_ok );
76- static ObjectAddress get_object_address_attribute (ObjectType objtype ,
77- List * objname ,Relation * relp ,
78- LOCKMODE lockmode ,bool missing_ok );
79- static ObjectAddress get_object_address_type (ObjectType objtype ,
80- List * objname ,bool missing_ok );
81- static ObjectAddress get_object_address_opcf (ObjectType objtype ,List * objname ,
82- List * objargs ,bool missing_ok );
83- static bool object_exists (ObjectAddress address );
84-
8569/*
8670 * ObjectProperty
8771 *
@@ -93,137 +77,180 @@ typedef struct
9377Oid class_oid ;/* oid of catalog */
9478Oid oid_index_oid ;/* oid of index on system oid column */
9579int oid_catcache_id ;/* id of catcache on system oid column */
80+ AttrNumber attnum_namespace ;/* attnum of namespace field */
9681}ObjectPropertyType ;
9782
9883static ObjectPropertyType ObjectProperty []=
9984{
10085{
10186CastRelationId ,
10287CastOidIndexId ,
103- -1
88+ -1 ,
89+ InvalidAttrNumber
10490},
10591{
10692CollationRelationId ,
10793CollationOidIndexId ,
108- COLLOID
94+ COLLOID ,
95+ Anum_pg_collation_collnamespace
10996},
11097{
11198ConstraintRelationId ,
11299ConstraintOidIndexId ,
113- CONSTROID
100+ CONSTROID ,
101+ Anum_pg_constraint_connamespace
114102},
115103{
116104ConversionRelationId ,
117105ConversionOidIndexId ,
118- CONVOID
106+ CONVOID ,
107+ Anum_pg_conversion_connamespace
119108},
120109{
121110DatabaseRelationId ,
122111DatabaseOidIndexId ,
123- DATABASEOID
112+ DATABASEOID ,
113+ InvalidAttrNumber
124114},
125115{
126116ExtensionRelationId ,
127117ExtensionOidIndexId ,
128- -1
118+ -1 ,
119+ Anum_pg_extension_extnamespace
129120},
130121{
131122ForeignDataWrapperRelationId ,
132123ForeignDataWrapperOidIndexId ,
133- FOREIGNDATAWRAPPEROID
124+ FOREIGNDATAWRAPPEROID ,
125+ InvalidAttrNumber
134126},
135127{
136128ForeignServerRelationId ,
137129ForeignServerOidIndexId ,
138- FOREIGNSERVEROID
130+ FOREIGNSERVEROID ,
131+ InvalidAttrNumber
139132},
140133{
141134ProcedureRelationId ,
142135ProcedureOidIndexId ,
143- PROCOID
136+ PROCOID ,
137+ Anum_pg_proc_pronamespace
144138},
145139{
146140LanguageRelationId ,
147141LanguageOidIndexId ,
148- LANGOID
142+ LANGOID ,
143+ InvalidAttrNumber ,
149144},
150145{
151146LargeObjectMetadataRelationId ,
152147LargeObjectMetadataOidIndexId ,
153- -1
148+ -1 ,
149+ InvalidAttrNumber
154150},
155151{
156152OperatorClassRelationId ,
157153OpclassOidIndexId ,
158- CLAOID
154+ CLAOID ,
155+ Anum_pg_opclass_opcnamespace ,
159156},
160157{
161158OperatorRelationId ,
162159OperatorOidIndexId ,
163- OPEROID
160+ OPEROID ,
161+ Anum_pg_operator_oprnamespace
164162},
165163{
166164OperatorFamilyRelationId ,
167165OpfamilyOidIndexId ,
168- OPFAMILYOID
166+ OPFAMILYOID ,
167+ Anum_pg_opfamily_opfnamespace
169168},
170169{
171170AuthIdRelationId ,
172171AuthIdOidIndexId ,
173- AUTHOID
172+ AUTHOID ,
173+ InvalidAttrNumber
174174},
175175{
176176RewriteRelationId ,
177177RewriteOidIndexId ,
178- -1
178+ -1 ,
179+ InvalidAttrNumber
179180},
180181{
181182NamespaceRelationId ,
182183NamespaceOidIndexId ,
183- NAMESPACEOID
184+ NAMESPACEOID ,
185+ InvalidAttrNumber
184186},
185187{
186188RelationRelationId ,
187189ClassOidIndexId ,
188- RELOID
190+ RELOID ,
191+ Anum_pg_class_relnamespace
189192},
190193{
191194TableSpaceRelationId ,
192195TablespaceOidIndexId ,
193196TABLESPACEOID ,
197+ InvalidAttrNumber
194198},
195199{
196200TriggerRelationId ,
197201TriggerOidIndexId ,
198- -1
202+ -1 ,
203+ InvalidAttrNumber
199204},
200205{
201206TSConfigRelationId ,
202207TSConfigOidIndexId ,
203- TSCONFIGOID
208+ TSCONFIGOID ,
209+ Anum_pg_ts_config_cfgnamespace
204210},
205211{
206212TSDictionaryRelationId ,
207213TSDictionaryOidIndexId ,
208- TSDICTOID
214+ TSDICTOID ,
215+ Anum_pg_ts_dict_dictnamespace
209216},
210217{
211218TSParserRelationId ,
212219TSParserOidIndexId ,
213- TSPARSEROID
220+ TSPARSEROID ,
221+ Anum_pg_ts_parser_prsnamespace
214222},
215223{
216224TSTemplateRelationId ,
217225TSTemplateOidIndexId ,
218- TSTEMPLATEOID
226+ TSTEMPLATEOID ,
227+ Anum_pg_ts_template_tmplnamespace ,
219228},
220229{
221230TypeRelationId ,
222231TypeOidIndexId ,
223- TYPEOID
232+ TYPEOID ,
233+ Anum_pg_type_typnamespace
224234}
225235};
226236
237+ static ObjectAddress get_object_address_unqualified (ObjectType objtype ,
238+ List * qualname ,bool missing_ok );
239+ static ObjectAddress get_relation_by_qualified_name (ObjectType objtype ,
240+ List * objname ,Relation * relp ,
241+ LOCKMODE lockmode ,bool missing_ok );
242+ static ObjectAddress get_object_address_relobject (ObjectType objtype ,
243+ List * objname ,Relation * relp ,bool missing_ok );
244+ static ObjectAddress get_object_address_attribute (ObjectType objtype ,
245+ List * objname ,Relation * relp ,
246+ LOCKMODE lockmode ,bool missing_ok );
247+ static ObjectAddress get_object_address_type (ObjectType objtype ,
248+ List * objname ,bool missing_ok );
249+ static ObjectAddress get_object_address_opcf (ObjectType objtype ,List * objname ,
250+ List * objargs ,bool missing_ok );
251+ static bool object_exists (ObjectAddress address );
252+ static ObjectPropertyType * get_object_property_data (Oid class_id );
253+
227254/*
228255 * Translate an object name and arguments (as passed by the parser) to an
229256 * ObjectAddress.
@@ -828,6 +855,7 @@ object_exists(ObjectAddress address)
828855ScanKeyData skey [1 ];
829856SysScanDesc sd ;
830857bool found ;
858+ ObjectPropertyType * property ;
831859
832860/* Sub-objects require special treatment. */
833861if (address .objectSubId != 0 )
@@ -847,35 +875,22 @@ object_exists(ObjectAddress address)
847875}
848876return found ;
849877}
850- else
851- {
852- int index ;
853878
854- /*
855- * Weird backward compatibility hack: ObjectAddress notation uses
856- * LargeObjectRelationId for large objects, but since PostgreSQL
857- * 9.0, the relevant catalog is actually LargeObjectMetadataRelationId.
858- */
859- if (address .classId == LargeObjectRelationId )
860- address .classId = LargeObjectMetadataRelationId ;
879+ /*
880+ * Weird backward compatibility hack: ObjectAddress notation uses
881+ * LargeObjectRelationId for large objects, but since PostgreSQL
882+ * 9.0, the relevant catalog is actually LargeObjectMetadataRelationId.
883+ */
884+ if (address .classId == LargeObjectRelationId )
885+ address .classId = LargeObjectMetadataRelationId ;
861886
862- /*
863- * For object types that have a relevant syscache, we use it; for
864- * everything else, we'll have to do an index-scan. Search the
865- * ObjectProperty array to find out which it is.
866- */
867- for (index = 0 ;index < lengthof (ObjectProperty );index ++ )
868- {
869- if (ObjectProperty [index ].class_oid == address .classId )
870- {
871- cache = ObjectProperty [index ].oid_catcache_id ;
872- indexoid = ObjectProperty [index ].oid_index_oid ;
873- break ;
874- }
875- }
876- if (index == lengthof (ObjectProperty ))
877- elog (ERROR ,"unrecognized classid: %u" ,address .classId );
878- }
887+ /*
888+ * For object types that have a relevant syscache, we use it; for
889+ * everything else, we'll have to do an index-scan.
890+ */
891+ property = get_object_property_data (address .classId );
892+ cache = property -> oid_catcache_id ;
893+ indexoid = property -> oid_index_oid ;
879894
880895/* Found a syscache? */
881896if (cache != -1 )
@@ -895,7 +910,6 @@ object_exists(ObjectAddress address)
895910return found ;
896911}
897912
898-
899913/*
900914 * Check ownership of an object previously identified by get_object_address.
901915 */
@@ -1060,3 +1074,58 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
10601074 (int )objtype );
10611075}
10621076}
1077+
1078+ /*
1079+ * get_object_namespace
1080+ *
1081+ * Find the schema containing the specified object. For non-schema objects,
1082+ * this function returns InvalidOid.
1083+ */
1084+ Oid
1085+ get_object_namespace (const ObjectAddress * address )
1086+ {
1087+ int cache ;
1088+ HeapTuple tuple ;
1089+ bool isnull ;
1090+ Oid oid ;
1091+ ObjectPropertyType * property ;
1092+
1093+ /* If not owned by a namespace, just return InvalidOid. */
1094+ property = get_object_property_data (address -> classId );
1095+ if (property -> attnum_namespace == InvalidAttrNumber )
1096+ return InvalidOid ;
1097+
1098+ /* Currently, we can only handle object types with system caches. */
1099+ cache = property -> oid_catcache_id ;
1100+ Assert (cache != -1 );
1101+
1102+ /* Fetch tuple from syscache and extract namespace attribute. */
1103+ tuple = SearchSysCache1 (cache ,ObjectIdGetDatum (address -> objectId ));
1104+ if (!HeapTupleIsValid (tuple ))
1105+ elog (ERROR ,"cache lookup failed for cache %d oid %u" ,
1106+ cache ,address -> objectId );
1107+ oid = DatumGetObjectId (SysCacheGetAttr (cache ,
1108+ tuple ,
1109+ property -> attnum_namespace ,
1110+ & isnull ));
1111+ Assert (!isnull );
1112+ ReleaseSysCache (tuple );
1113+
1114+ return oid ;
1115+ }
1116+
1117+ /*
1118+ * Find ObjectProperty structure by class_id.
1119+ */
1120+ static ObjectPropertyType *
1121+ get_object_property_data (Oid class_id )
1122+ {
1123+ int index ;
1124+
1125+ for (index = 0 ;index < lengthof (ObjectProperty );index ++ )
1126+ if (ObjectProperty [index ].class_oid == class_id )
1127+ return & ObjectProperty [index ];
1128+
1129+ elog (ERROR ,"unrecognized class id: %u" ,class_id );
1130+ return NULL ;/* not reached */
1131+ }