Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7ac5760

Browse files
committed
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it alreadywas, for most objects classes we were correctly complaining aboutexactly that ("object is already in schema"); but for some other objectclasses, such as functions, we were instead complaining of a namecollision ("object already exists in schema"). The latter is wrong andmisleading, per complaint from Robert Haas inCA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.comTo fix, refactor the way these checks are done. As a bonus, theresulting code is smaller and can also share some code with Renamecases.While at it, remove use of getObjectDescriptionOids() in error messages.These are normally disallowed because of translatability considerations,but this one had slipped through since 9.1. (Not sure that this isworth backpatching, though, as it would create some untranslatedmessages in back branches.)This is loosely based on a patch by KaiGai Kohei, heavily reworked byme.
1 parentffda059 commit7ac5760

File tree

7 files changed

+124
-186
lines changed

7 files changed

+124
-186
lines changed

‎src/backend/commands/alter.c

Lines changed: 85 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,16 @@
1919
#include"catalog/dependency.h"
2020
#include"catalog/indexing.h"
2121
#include"catalog/namespace.h"
22+
#include"catalog/pg_collation.h"
23+
#include"catalog/pg_conversion.h"
2224
#include"catalog/pg_largeobject.h"
2325
#include"catalog/pg_largeobject_metadata.h"
2426
#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"
2532
#include"commands/alter.h"
2633
#include"commands/collationcmds.h"
2734
#include"commands/conversioncmds.h"
@@ -46,6 +53,8 @@
4653
#include"utils/tqual.h"
4754

4855

56+
staticOidAlterObjectNamespace_internal(Relationrel,Oidobjid,OidnspOid);
57+
4958
/*
5059
* Executes an ALTER OBJECT / RENAME TO statement.Based on the object
5160
* type, the function appropriate to that type is executed.
@@ -146,40 +155,32 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
146155
{
147156
switch (stmt->objectType)
148157
{
149-
caseOBJECT_AGGREGATE:
150-
returnAlterFunctionNamespace(stmt->object,stmt->objarg, true,
151-
stmt->newschema);
152-
153-
caseOBJECT_COLLATION:
154-
returnAlterCollationNamespace(stmt->object,stmt->newschema);
155-
156158
caseOBJECT_EXTENSION:
157159
returnAlterExtensionNamespace(stmt->object,stmt->newschema);
158160

159-
caseOBJECT_FUNCTION:
160-
returnAlterFunctionNamespace(stmt->object,stmt->objarg, false,
161-
stmt->newschema);
162-
161+
caseOBJECT_FOREIGN_TABLE:
163162
caseOBJECT_SEQUENCE:
164163
caseOBJECT_TABLE:
165164
caseOBJECT_VIEW:
166-
caseOBJECT_FOREIGN_TABLE:
167165
returnAlterTableNamespace(stmt);
168166

169-
caseOBJECT_TYPE:
170167
caseOBJECT_DOMAIN:
168+
caseOBJECT_TYPE:
171169
returnAlterTypeNamespace(stmt->object,stmt->newschema,
172170
stmt->objectType);
173171

174172
/* generic code path */
173+
caseOBJECT_AGGREGATE:
174+
caseOBJECT_COLLATION:
175175
caseOBJECT_CONVERSION:
176+
caseOBJECT_FUNCTION:
176177
caseOBJECT_OPERATOR:
177178
caseOBJECT_OPCLASS:
178179
caseOBJECT_OPFAMILY:
179-
caseOBJECT_TSPARSER:
180+
caseOBJECT_TSCONFIGURATION:
180181
caseOBJECT_TSDICTIONARY:
182+
caseOBJECT_TSPARSER:
181183
caseOBJECT_TSTEMPLATE:
182-
caseOBJECT_TSCONFIGURATION:
183184
{
184185
Relationcatalog;
185186
Relationrelation;
@@ -253,22 +254,16 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
253254
break;
254255
}
255256

256-
caseOCLASS_PROC:
257-
oldNspOid=AlterFunctionNamespace_oid(objid,nspOid);
258-
break;
259-
260257
caseOCLASS_TYPE:
261258
oldNspOid=AlterTypeNamespace_oid(objid,nspOid,objsMoved);
262259
break;
263260

264261
caseOCLASS_COLLATION:
265-
oldNspOid=AlterCollationNamespace_oid(objid,nspOid);
266-
break;
267-
268262
caseOCLASS_CONVERSION:
269263
caseOCLASS_OPERATOR:
270264
caseOCLASS_OPCLASS:
271265
caseOCLASS_OPFAMILY:
266+
caseOCLASS_PROC:
272267
caseOCLASS_TSPARSER:
273268
caseOCLASS_TSDICT:
274269
caseOCLASS_TSTEMPLATE:
@@ -292,6 +287,43 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
292287
returnoldNspOid;
293288
}
294289

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+
staticvoid
295+
report_namespace_conflict(OidclassId,constchar*name,OidnspOid)
296+
{
297+
char*msgfmt;
298+
299+
Assert(OidIsValid(nspOid));
300+
switch (classId)
301+
{
302+
caseConversionRelationId:
303+
msgfmt=gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
304+
break;
305+
caseTSParserRelationId:
306+
msgfmt=gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
307+
break;
308+
caseTSDictionaryRelationId:
309+
msgfmt=gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
310+
break;
311+
caseTSTemplateRelationId:
312+
msgfmt=gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
313+
break;
314+
caseTSConfigRelationId:
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+
295327
/*
296328
* Generic function to change the namespace of a given object, for simple
297329
* 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,
303335
*
304336
* Returns the OID of the object's previous namespace.
305337
*/
306-
Oid
338+
staticOid
307339
AlterObjectNamespace_internal(Relationrel,Oidobjid,OidnspOid)
308340
{
309341
OidclassId=RelationGetRelid(rel);
@@ -373,13 +405,36 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
373405
* Since this is just a friendliness check, we can just skip it in cases
374406
* where there isn't a suitable syscache available.
375407
*/
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+
HeapTupletup;
411+
Form_pg_procproc;
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+
elseif (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+
elseif (nameCacheId >=0&&
433+
SearchSysCacheExists2(nameCacheId,name,
434+
ObjectIdGetDatum(nspOid)))
435+
report_namespace_conflict(classId,
436+
NameStr(*(DatumGetName(name))),
437+
nspOid);
383438

384439
/* Build modified tuple */
385440
values=palloc0(RelationGetNumberOfAttributes(rel)*sizeof(Datum));
@@ -406,7 +461,6 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
406461
returnoldNspOid;
407462
}
408463

409-
410464
/*
411465
* Executes an ALTER OBJECT / OWNER TO statement. Based on the object
412466
* type, the function appropriate to that type is executed.

‎src/backend/commands/collationcmds.c

Lines changed: 14 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -167,27 +167,7 @@ RenameCollation(List *name, const char *newname)
167167
namespaceOid= ((Form_pg_collation)GETSTRUCT(tup))->collnamespace;
168168

169169
/* make sure the new name doesn't exist */
170-
if (SearchSysCacheExists3(COLLNAMEENCNSP,
171-
CStringGetDatum(newname),
172-
Int32GetDatum(GetDatabaseEncoding()),
173-
ObjectIdGetDatum(namespaceOid)))
174-
ereport(ERROR,
175-
(errcode(ERRCODE_DUPLICATE_OBJECT),
176-
errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
177-
newname,
178-
GetDatabaseEncodingName(),
179-
get_namespace_name(namespaceOid))));
180-
181-
/* mustn't match an any-encoding entry, either */
182-
if (SearchSysCacheExists3(COLLNAMEENCNSP,
183-
CStringGetDatum(newname),
184-
Int32GetDatum(-1),
185-
ObjectIdGetDatum(namespaceOid)))
186-
ereport(ERROR,
187-
(errcode(ERRCODE_DUPLICATE_OBJECT),
188-
errmsg("collation \"%s\" already exists in schema \"%s\"",
189-
newname,
190-
get_namespace_name(namespaceOid))));
170+
IsThereCollationInNamespace(newname,namespaceOid);
191171

192172
/* must be owner */
193173
if (!pg_collation_ownercheck(collationOid,GetUserId()))
@@ -213,71 +193,32 @@ RenameCollation(List *name, const char *newname)
213193
}
214194

215195
/*
216-
* Execute ALTER COLLATION SET SCHEMA
217-
*/
218-
Oid
219-
AlterCollationNamespace(List*name,constchar*newschema)
220-
{
221-
OidcollOid,
222-
nspOid;
223-
224-
collOid=get_collation_oid(name, false);
225-
226-
nspOid=LookupCreationNamespace(newschema);
227-
228-
AlterCollationNamespace_oid(collOid,nspOid);
229-
230-
returncollOid;
231-
}
232-
233-
/*
234-
* Change collation schema, by oid
196+
* Subroutine for ALTER COLLATION SET SCHEMA and RENAME
197+
*
198+
* Is there a collation with the same name of the given collation already in
199+
* the given namespace? If so, raise an appropriate error message.
235200
*/
236-
Oid
237-
AlterCollationNamespace_oid(OidcollOid,OidnewNspOid)
201+
void
202+
IsThereCollationInNamespace(constchar*collname,OidnspOid)
238203
{
239-
OidoldNspOid;
240-
Relationrel;
241-
char*collation_name;
242-
243-
rel=heap_open(CollationRelationId,RowExclusiveLock);
244-
245-
/*
246-
* We have to check for name collision ourselves, because
247-
* AlterObjectNamespace_internal doesn't know how to deal with the encoding
248-
* considerations.
249-
*/
250-
collation_name=get_collation_name(collOid);
251-
if (!collation_name)
252-
elog(ERROR,"cache lookup failed for collation %u",collOid);
253-
254204
/* make sure the name doesn't already exist in new schema */
255205
if (SearchSysCacheExists3(COLLNAMEENCNSP,
256-
CStringGetDatum(collation_name),
206+
CStringGetDatum(collname),
257207
Int32GetDatum(GetDatabaseEncoding()),
258-
ObjectIdGetDatum(newNspOid)))
208+
ObjectIdGetDatum(nspOid)))
259209
ereport(ERROR,
260210
(errcode(ERRCODE_DUPLICATE_OBJECT),
261211
errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
262-
collation_name,
263-
GetDatabaseEncodingName(),
264-
get_namespace_name(newNspOid))));
212+
collname,GetDatabaseEncodingName(),
213+
get_namespace_name(nspOid))));
265214

266215
/* mustn't match an any-encoding entry, either */
267216
if (SearchSysCacheExists3(COLLNAMEENCNSP,
268-
CStringGetDatum(collation_name),
217+
CStringGetDatum(collname),
269218
Int32GetDatum(-1),
270-
ObjectIdGetDatum(newNspOid)))
219+
ObjectIdGetDatum(nspOid)))
271220
ereport(ERROR,
272221
(errcode(ERRCODE_DUPLICATE_OBJECT),
273222
errmsg("collation \"%s\" already exists in schema \"%s\"",
274-
collation_name,
275-
get_namespace_name(newNspOid))));
276-
277-
/* OK, do the work */
278-
oldNspOid=AlterObjectNamespace_internal(rel,collOid,newNspOid);
279-
280-
heap_close(rel,RowExclusiveLock);
281-
282-
returnoldNspOid;
223+
collname,get_namespace_name(nspOid))));
283224
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp