19
19
#include "catalog/dependency.h"
20
20
#include "catalog/indexing.h"
21
21
#include "catalog/namespace.h"
22
+ #include "catalog/pg_collation.h"
23
+ #include "catalog/pg_conversion.h"
22
24
#include "catalog/pg_largeobject.h"
23
25
#include "catalog/pg_largeobject_metadata.h"
24
26
#include "catalog/pg_namespace.h"
27
+ #include "catalog/pg_proc.h"
28
+ #include "catalog/pg_ts_config.h"
29
+ #include "catalog/pg_ts_dict.h"
30
+ #include "catalog/pg_ts_parser.h"
31
+ #include "catalog/pg_ts_template.h"
25
32
#include "commands/alter.h"
26
33
#include "commands/collationcmds.h"
27
34
#include "commands/conversioncmds.h"
46
53
#include "utils/tqual.h"
47
54
48
55
56
+ static Oid AlterObjectNamespace_internal (Relation rel , Oid objid , Oid nspOid );
57
+
49
58
/*
50
59
* Executes an ALTER OBJECT / RENAME TO statement. Based on the object
51
60
* type, the function appropriate to that type is executed.
@@ -146,40 +155,32 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
146
155
{
147
156
switch (stmt -> objectType )
148
157
{
149
- case OBJECT_AGGREGATE :
150
- return AlterFunctionNamespace (stmt -> object , stmt -> objarg , true,
151
- stmt -> newschema );
152
-
153
- case OBJECT_COLLATION :
154
- return AlterCollationNamespace (stmt -> object , stmt -> newschema );
155
-
156
158
case OBJECT_EXTENSION :
157
159
return AlterExtensionNamespace (stmt -> object , stmt -> newschema );
158
160
159
- case OBJECT_FUNCTION :
160
- return AlterFunctionNamespace (stmt -> object , stmt -> objarg , false,
161
- stmt -> newschema );
162
-
161
+ case OBJECT_FOREIGN_TABLE :
163
162
case OBJECT_SEQUENCE :
164
163
case OBJECT_TABLE :
165
164
case OBJECT_VIEW :
166
- case OBJECT_FOREIGN_TABLE :
167
165
return AlterTableNamespace (stmt );
168
166
169
- case OBJECT_TYPE :
170
167
case OBJECT_DOMAIN :
168
+ case OBJECT_TYPE :
171
169
return AlterTypeNamespace (stmt -> object , stmt -> newschema ,
172
170
stmt -> objectType );
173
171
174
172
/* generic code path */
173
+ case OBJECT_AGGREGATE :
174
+ case OBJECT_COLLATION :
175
175
case OBJECT_CONVERSION :
176
+ case OBJECT_FUNCTION :
176
177
case OBJECT_OPERATOR :
177
178
case OBJECT_OPCLASS :
178
179
case OBJECT_OPFAMILY :
179
- case OBJECT_TSPARSER :
180
+ case OBJECT_TSCONFIGURATION :
180
181
case OBJECT_TSDICTIONARY :
182
+ case OBJECT_TSPARSER :
181
183
case OBJECT_TSTEMPLATE :
182
- case OBJECT_TSCONFIGURATION :
183
184
{
184
185
Relation catalog ;
185
186
Relation relation ;
@@ -253,22 +254,16 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
253
254
break ;
254
255
}
255
256
256
- case OCLASS_PROC :
257
- oldNspOid = AlterFunctionNamespace_oid (objid , nspOid );
258
- break ;
259
-
260
257
case OCLASS_TYPE :
261
258
oldNspOid = AlterTypeNamespace_oid (objid , nspOid , objsMoved );
262
259
break ;
263
260
264
261
case OCLASS_COLLATION :
265
- oldNspOid = AlterCollationNamespace_oid (objid , nspOid );
266
- break ;
267
-
268
262
case OCLASS_CONVERSION :
269
263
case OCLASS_OPERATOR :
270
264
case OCLASS_OPCLASS :
271
265
case OCLASS_OPFAMILY :
266
+ case OCLASS_PROC :
272
267
case OCLASS_TSPARSER :
273
268
case OCLASS_TSDICT :
274
269
case OCLASS_TSTEMPLATE :
@@ -292,6 +287,43 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
292
287
return oldNspOid ;
293
288
}
294
289
290
+ /*
291
+ * Raise an error to the effect that an object of the given name is already
292
+ * present in the given namespace.
293
+ */
294
+ static void
295
+ report_namespace_conflict (Oid classId , const char * name , Oid nspOid )
296
+ {
297
+ char * msgfmt ;
298
+
299
+ Assert (OidIsValid (nspOid ));
300
+ switch (classId )
301
+ {
302
+ case ConversionRelationId :
303
+ msgfmt = gettext_noop ("conversion \"%s\" already exists in schema \"%s\"" );
304
+ break ;
305
+ case TSParserRelationId :
306
+ msgfmt = gettext_noop ("text search parser \"%s\" already exists in schema \"%s\"" );
307
+ break ;
308
+ case TSDictionaryRelationId :
309
+ msgfmt = gettext_noop ("text search dictionary \"%s\" already exists in schema \"%s\"" );
310
+ break ;
311
+ case TSTemplateRelationId :
312
+ msgfmt = gettext_noop ("text search template \"%s\" already exists in schema \"%s\"" );
313
+ break ;
314
+ case TSConfigRelationId :
315
+ msgfmt = gettext_noop ("text search configuration \"%s\" already exists in schema \"%s\"" );
316
+ break ;
317
+ default :
318
+ elog (ERROR , "unsupported object class %u" , classId );
319
+ break ;
320
+ }
321
+
322
+ ereport (ERROR ,
323
+ (errcode (ERRCODE_DUPLICATE_OBJECT ),
324
+ errmsg (msgfmt , name , get_namespace_name (nspOid ))));
325
+ }
326
+
295
327
/*
296
328
* Generic function to change the namespace of a given object, for simple
297
329
* cases (won't work for tables, nor other cases where we need to do more
@@ -303,7 +335,7 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
303
335
*
304
336
* Returns the OID of the object's previous namespace.
305
337
*/
306
- Oid
338
+ static Oid
307
339
AlterObjectNamespace_internal (Relation rel , Oid objid , Oid nspOid )
308
340
{
309
341
Oid classId = RelationGetRelid (rel );
@@ -373,13 +405,36 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
373
405
* Since this is just a friendliness check, we can just skip it in cases
374
406
* where there isn't a suitable syscache available.
375
407
*/
376
- if (nameCacheId >= 0 &&
377
- SearchSysCacheExists2 (nameCacheId , name , ObjectIdGetDatum (nspOid )))
378
- ereport (ERROR ,
379
- (errcode (ERRCODE_DUPLICATE_OBJECT ),
380
- errmsg ("%s already exists in schema \"%s\"" ,
381
- getObjectDescriptionOids (classId , objid ),
382
- get_namespace_name (nspOid ))));
408
+ if (classId == ProcedureRelationId )
409
+ {
410
+ HeapTuple tup ;
411
+ Form_pg_proc proc ;
412
+
413
+ tup = SearchSysCacheCopy1 (PROCOID , ObjectIdGetDatum (objid ));
414
+ if (!HeapTupleIsValid (tup ))
415
+ elog (ERROR , "cache lookup failed for function %u" , objid );
416
+ proc = (Form_pg_proc ) GETSTRUCT (tup );
417
+
418
+ IsThereFunctionInNamespace (NameStr (proc -> proname ), proc -> pronargs ,
419
+ proc -> proargtypes , nspOid );
420
+ heap_freetuple (tup );
421
+ }
422
+ else if (classId == CollationRelationId )
423
+ {
424
+ char * collname ;
425
+
426
+ collname = get_collation_name (objid );
427
+ if (!collname )
428
+ elog (ERROR , "cache lookup failed for collation %u" , objid );
429
+ IsThereCollationInNamespace (collname , nspOid );
430
+ pfree (collname );
431
+ }
432
+ else if (nameCacheId >= 0 &&
433
+ SearchSysCacheExists2 (nameCacheId , name ,
434
+ ObjectIdGetDatum (nspOid )))
435
+ report_namespace_conflict (classId ,
436
+ NameStr (* (DatumGetName (name ))),
437
+ nspOid );
383
438
384
439
/* Build modified tuple */
385
440
values = palloc0 (RelationGetNumberOfAttributes (rel ) * sizeof (Datum ));
@@ -406,7 +461,6 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
406
461
return oldNspOid ;
407
462
}
408
463
409
-
410
464
/*
411
465
* Executes an ALTER OBJECT / OWNER TO statement. Based on the object
412
466
* type, the function appropriate to that type is executed.
0 commit comments