66
66
#include "utils/syscache.h"
67
67
#include "utils/tqual.h"
68
68
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
-
85
69
/*
86
70
* ObjectProperty
87
71
*
@@ -93,137 +77,180 @@ typedef struct
93
77
Oid class_oid ; /* oid of catalog */
94
78
Oid oid_index_oid ; /* oid of index on system oid column */
95
79
int oid_catcache_id ; /* id of catcache on system oid column */
80
+ AttrNumber attnum_namespace ; /* attnum of namespace field */
96
81
} ObjectPropertyType ;
97
82
98
83
static ObjectPropertyType ObjectProperty [] =
99
84
{
100
85
{
101
86
CastRelationId ,
102
87
CastOidIndexId ,
103
- -1
88
+ -1 ,
89
+ InvalidAttrNumber
104
90
},
105
91
{
106
92
CollationRelationId ,
107
93
CollationOidIndexId ,
108
- COLLOID
94
+ COLLOID ,
95
+ Anum_pg_collation_collnamespace
109
96
},
110
97
{
111
98
ConstraintRelationId ,
112
99
ConstraintOidIndexId ,
113
- CONSTROID
100
+ CONSTROID ,
101
+ Anum_pg_constraint_connamespace
114
102
},
115
103
{
116
104
ConversionRelationId ,
117
105
ConversionOidIndexId ,
118
- CONVOID
106
+ CONVOID ,
107
+ Anum_pg_conversion_connamespace
119
108
},
120
109
{
121
110
DatabaseRelationId ,
122
111
DatabaseOidIndexId ,
123
- DATABASEOID
112
+ DATABASEOID ,
113
+ InvalidAttrNumber
124
114
},
125
115
{
126
116
ExtensionRelationId ,
127
117
ExtensionOidIndexId ,
128
- -1
118
+ -1 ,
119
+ Anum_pg_extension_extnamespace
129
120
},
130
121
{
131
122
ForeignDataWrapperRelationId ,
132
123
ForeignDataWrapperOidIndexId ,
133
- FOREIGNDATAWRAPPEROID
124
+ FOREIGNDATAWRAPPEROID ,
125
+ InvalidAttrNumber
134
126
},
135
127
{
136
128
ForeignServerRelationId ,
137
129
ForeignServerOidIndexId ,
138
- FOREIGNSERVEROID
130
+ FOREIGNSERVEROID ,
131
+ InvalidAttrNumber
139
132
},
140
133
{
141
134
ProcedureRelationId ,
142
135
ProcedureOidIndexId ,
143
- PROCOID
136
+ PROCOID ,
137
+ Anum_pg_proc_pronamespace
144
138
},
145
139
{
146
140
LanguageRelationId ,
147
141
LanguageOidIndexId ,
148
- LANGOID
142
+ LANGOID ,
143
+ InvalidAttrNumber ,
149
144
},
150
145
{
151
146
LargeObjectMetadataRelationId ,
152
147
LargeObjectMetadataOidIndexId ,
153
- -1
148
+ -1 ,
149
+ InvalidAttrNumber
154
150
},
155
151
{
156
152
OperatorClassRelationId ,
157
153
OpclassOidIndexId ,
158
- CLAOID
154
+ CLAOID ,
155
+ Anum_pg_opclass_opcnamespace ,
159
156
},
160
157
{
161
158
OperatorRelationId ,
162
159
OperatorOidIndexId ,
163
- OPEROID
160
+ OPEROID ,
161
+ Anum_pg_operator_oprnamespace
164
162
},
165
163
{
166
164
OperatorFamilyRelationId ,
167
165
OpfamilyOidIndexId ,
168
- OPFAMILYOID
166
+ OPFAMILYOID ,
167
+ Anum_pg_opfamily_opfnamespace
169
168
},
170
169
{
171
170
AuthIdRelationId ,
172
171
AuthIdOidIndexId ,
173
- AUTHOID
172
+ AUTHOID ,
173
+ InvalidAttrNumber
174
174
},
175
175
{
176
176
RewriteRelationId ,
177
177
RewriteOidIndexId ,
178
- -1
178
+ -1 ,
179
+ InvalidAttrNumber
179
180
},
180
181
{
181
182
NamespaceRelationId ,
182
183
NamespaceOidIndexId ,
183
- NAMESPACEOID
184
+ NAMESPACEOID ,
185
+ InvalidAttrNumber
184
186
},
185
187
{
186
188
RelationRelationId ,
187
189
ClassOidIndexId ,
188
- RELOID
190
+ RELOID ,
191
+ Anum_pg_class_relnamespace
189
192
},
190
193
{
191
194
TableSpaceRelationId ,
192
195
TablespaceOidIndexId ,
193
196
TABLESPACEOID ,
197
+ InvalidAttrNumber
194
198
},
195
199
{
196
200
TriggerRelationId ,
197
201
TriggerOidIndexId ,
198
- -1
202
+ -1 ,
203
+ InvalidAttrNumber
199
204
},
200
205
{
201
206
TSConfigRelationId ,
202
207
TSConfigOidIndexId ,
203
- TSCONFIGOID
208
+ TSCONFIGOID ,
209
+ Anum_pg_ts_config_cfgnamespace
204
210
},
205
211
{
206
212
TSDictionaryRelationId ,
207
213
TSDictionaryOidIndexId ,
208
- TSDICTOID
214
+ TSDICTOID ,
215
+ Anum_pg_ts_dict_dictnamespace
209
216
},
210
217
{
211
218
TSParserRelationId ,
212
219
TSParserOidIndexId ,
213
- TSPARSEROID
220
+ TSPARSEROID ,
221
+ Anum_pg_ts_parser_prsnamespace
214
222
},
215
223
{
216
224
TSTemplateRelationId ,
217
225
TSTemplateOidIndexId ,
218
- TSTEMPLATEOID
226
+ TSTEMPLATEOID ,
227
+ Anum_pg_ts_template_tmplnamespace ,
219
228
},
220
229
{
221
230
TypeRelationId ,
222
231
TypeOidIndexId ,
223
- TYPEOID
232
+ TYPEOID ,
233
+ Anum_pg_type_typnamespace
224
234
}
225
235
};
226
236
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
+
227
254
/*
228
255
* Translate an object name and arguments (as passed by the parser) to an
229
256
* ObjectAddress.
@@ -828,6 +855,7 @@ object_exists(ObjectAddress address)
828
855
ScanKeyData skey [1 ];
829
856
SysScanDesc sd ;
830
857
bool found ;
858
+ ObjectPropertyType * property ;
831
859
832
860
/* Sub-objects require special treatment. */
833
861
if (address .objectSubId != 0 )
@@ -847,35 +875,22 @@ object_exists(ObjectAddress address)
847
875
}
848
876
return found ;
849
877
}
850
- else
851
- {
852
- int index ;
853
878
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 ;
861
886
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 ;
879
894
880
895
/* Found a syscache? */
881
896
if (cache != -1 )
@@ -895,7 +910,6 @@ object_exists(ObjectAddress address)
895
910
return found ;
896
911
}
897
912
898
-
899
913
/*
900
914
* Check ownership of an object previously identified by get_object_address.
901
915
*/
@@ -1060,3 +1074,58 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
1060
1074
(int ) objtype );
1061
1075
}
1062
1076
}
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
+ }
0 commit comments