Skip to content

Commit 0345f58

Browse files
committed
Implement DROP CONVERSION
Add regression test
1 parent 8d600a7 commit 0345f58

File tree

16 files changed

+852
-104
lines changed

16 files changed

+852
-104
lines changed

src/backend/catalog/dependency.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.5 2002/07/18 23:11:27 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.6 2002/07/25 10:07:10 ishii Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -23,6 +23,7 @@
2323
#include "catalog/indexing.h"
2424
#include "catalog/pg_attrdef.h"
2525
#include "catalog/pg_constraint.h"
26+
#include "catalog/pg_conversion.h"
2627
#include "catalog/pg_depend.h"
2728
#include "catalog/pg_language.h"
2829
#include "catalog/pg_namespace.h"
@@ -52,6 +53,7 @@ typedef enum ObjectClasses
5253
OCLASS_PROC, /* pg_proc */
5354
OCLASS_TYPE, /* pg_type */
5455
OCLASS_CONSTRAINT, /* pg_constraint */
56+
OCLASS_CONVERSION, /* pg_conversion */
5557
OCLASS_DEFAULT, /* pg_attrdef */
5658
OCLASS_LANGUAGE, /* pg_language */
5759
OCLASS_OPERATOR, /* pg_operator */
@@ -581,6 +583,10 @@ doDeletion(const ObjectAddress *object)
581583
RemoveConstraintById(object->objectId);
582584
break;
583585

586+
case OCLASS_CONVERSION:
587+
RemoveConversionById(object->objectId);
588+
break;
589+
584590
case OCLASS_DEFAULT:
585591
RemoveAttrDefaultById(object->objectId);
586592
break;
@@ -989,6 +995,7 @@ init_object_classes(void)
989995
object_classes[OCLASS_PROC] = RelOid_pg_proc;
990996
object_classes[OCLASS_TYPE] = RelOid_pg_type;
991997
object_classes[OCLASS_CONSTRAINT] = get_system_catalog_relid(ConstraintRelationName);
998+
object_classes[OCLASS_CONVERSION] = get_system_catalog_relid(ConversionRelationName);
992999
object_classes[OCLASS_DEFAULT] = get_system_catalog_relid(AttrDefaultRelationName);
9931000
object_classes[OCLASS_LANGUAGE] = get_system_catalog_relid(LanguageRelationName);
9941001
object_classes[OCLASS_OPERATOR] = get_system_catalog_relid(OperatorRelationName);
@@ -1039,6 +1046,11 @@ getObjectClass(const ObjectAddress *object)
10391046
Assert(object->objectSubId == 0);
10401047
return OCLASS_CONSTRAINT;
10411048
}
1049+
if (object->classId == object_classes[OCLASS_CONVERSION])
1050+
{
1051+
Assert(object->objectSubId == 0);
1052+
return OCLASS_CONVERSION;
1053+
}
10421054
if (object->classId == object_classes[OCLASS_DEFAULT])
10431055
{
10441056
Assert(object->objectSubId == 0);
@@ -1165,6 +1177,22 @@ getObjectDescription(const ObjectAddress *object)
11651177
break;
11661178
}
11671179

1180+
case OCLASS_CONVERSION:
1181+
{
1182+
HeapTuple conTup;
1183+
1184+
conTup = SearchSysCache(CONOID,
1185+
ObjectIdGetDatum(object->objectId),
1186+
0, 0, 0);
1187+
if (!HeapTupleIsValid(conTup))
1188+
elog(ERROR, "getObjectDescription: Conversion %u does not exist",
1189+
object->objectId);
1190+
appendStringInfo(&buffer, "conversion %s",
1191+
NameStr(((Form_pg_conversion) GETSTRUCT(conTup))->conname));
1192+
ReleaseSysCache(conTup);
1193+
break;
1194+
}
1195+
11681196
case OCLASS_DEFAULT:
11691197
{
11701198
Relation attrdefDesc;

src/backend/catalog/pg_conversion.c

Lines changed: 114 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,32 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.2 2002/07/16 06:58:44 ishii Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.3 2002/07/25 10:07:10 ishii Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include "postgres.h"
1616

1717
#include "access/heapam.h"
1818
#include "catalog/catname.h"
19+
#include "catalog/dependency.h"
1920
#include "catalog/indexing.h"
21+
#include "catalog/pg_class.h"
2022
#include "catalog/pg_conversion.h"
2123
#include "catalog/namespace.h"
2224
#include "utils/builtins.h"
25+
#include "utils/lsyscache.h"
2326
#include "utils/syscache.h"
27+
#include "utils/catcache.h"
2428
#include "mb/pg_wchar.h"
2529
#include "utils/fmgroids.h"
2630
#include "utils/acl.h"
2731
#include "miscadmin.h"
2832

2933
/* ----------------
3034
* ConversionCreate
35+
*
36+
* Add a new tuple to pg_coversion.
3137
* ---------------
3238
*/
3339
Oid ConversionCreate(const char *conname, Oid connamespace,
@@ -43,6 +49,8 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
4349
Datum values[Natts_pg_conversion];
4450
NameData cname;
4551
Oid oid;
52+
ObjectAddress myself,
53+
referenced;
4654

4755
/* sanity checks */
4856
if (!conname)
@@ -85,7 +93,10 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
8593
values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
8694
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
8795
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
88-
values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def);
96+
if (def == true)
97+
values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def);
98+
else
99+
nulls[Anum_pg_conversion_condefault - 1] = 'n';
89100

90101
tup = heap_formtuple(tupDesc, values, nulls);
91102

@@ -103,23 +114,39 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
103114
CatalogCloseIndices(Num_pg_conversion_indices, idescs);
104115
}
105116

117+
myself.classId = get_system_catalog_relid(ConversionRelationName);
118+
myself.objectId = HeapTupleGetOid(tup);
119+
myself.objectSubId = 0;
120+
121+
/* dependency on conversion procedure */
122+
referenced.classId = RelOid_pg_proc;
123+
referenced.objectId = conproc;
124+
referenced.objectSubId = 0;
125+
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
126+
127+
heap_freetuple(tup);
106128
heap_close(rel, RowExclusiveLock);
107129

108130
return oid;
109131
}
110132

111133
/* ----------------
112134
* ConversionDrop
135+
*
136+
* Drop a conversion and do dependency check.
113137
* ---------------
114138
*/
115-
void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
139+
void ConversionDrop(const char *conname, Oid connamespace,
140+
int32 conowner, DropBehavior behavior)
116141
{
117142
Relation rel;
118143
TupleDesc tupDesc;
119144
HeapTuple tuple;
120145
HeapScanDesc scan;
121146
ScanKeyData scanKeyData;
122147
Form_pg_conversion body;
148+
ObjectAddress object;
149+
Oid myoid;
123150

124151
/* sanity checks */
125152
if (!conname)
@@ -132,7 +159,7 @@ void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
132159
ObjectIdGetDatum(connamespace));
133160

134161
/* open pg_conversion */
135-
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
162+
rel = heap_openr(ConversionRelationName, AccessShareLock);
136163
tupDesc = rel->rd_att;
137164

138165
scan = heap_beginscan(rel, SnapshotNow,
@@ -155,18 +182,65 @@ void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
155182
if (!superuser() && ((Form_pg_conversion)GETSTRUCT(tuple))->conowner != GetUserId())
156183
elog(ERROR, "permission denied");
157184

158-
simple_heap_delete(rel, &tuple->t_self);
185+
myoid = HeapTupleGetOid(tuple);
186+
heap_endscan(scan);
187+
heap_close(rel, AccessShareLock);
188+
189+
/*
190+
* Do the deletion
191+
*/
192+
object.classId = get_system_catalog_relid(ConversionRelationName);
193+
object.objectId = myoid;
194+
object.objectSubId = 0;
195+
196+
performDeletion(&object, behavior);
197+
}
198+
199+
/* ----------------
200+
* RemoveConversionById
201+
*
202+
* Remove a tuple from pg_conversion by Oid. This function is soley
203+
* called inside catalog/dependency.c
204+
* --------------- */
205+
void
206+
RemoveConversionById(Oid conversionOid)
207+
{
208+
Relation rel;
209+
TupleDesc tupDesc;
210+
HeapTuple tuple;
211+
HeapScanDesc scan;
212+
ScanKeyData scanKeyData;
213+
214+
ScanKeyEntryInitialize(&scanKeyData,
215+
0,
216+
ObjectIdAttributeNumber,
217+
F_OIDEQ,
218+
ObjectIdGetDatum(conversionOid));
159219

220+
/* open pg_conversion */
221+
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
222+
tupDesc = rel->rd_att;
223+
224+
scan = heap_beginscan(rel, SnapshotNow,
225+
1, &scanKeyData);
226+
227+
/* search for the target tuple */
228+
if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
229+
simple_heap_delete(rel, &tuple->t_self);
230+
else
231+
elog(ERROR, "Conversion %u does not exist", conversionOid);
160232
heap_endscan(scan);
161233
heap_close(rel, RowExclusiveLock);
162234
}
163235

164236
/* ----------------
165237
* FindDefaultConversion
166238
*
167-
* find default conversion proc by for_encoding and to_encoding in this name space
239+
* Find "default" conversion proc by for_encoding and to_encoding in this name space.
240+
* If found, returns the procedure's oid, otherwise InvalidOid.
168241
* ---------------
169242
*/
243+
#ifdef NOT_USED
170244
Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
171245
{
172246
Relation rel;
@@ -205,11 +279,44 @@ Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
205279
heap_close(rel, AccessShareLock);
206280
return proc;
207281
}
282+
#endif
283+
284+
Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
285+
{
286+
CatCList *catlist;
287+
HeapTuple tuple;
288+
Form_pg_conversion body;
289+
Oid proc = InvalidOid;
290+
int i;
291+
292+
/* Check we have usage rights in target namespace */
293+
if (pg_namespace_aclcheck(name_space, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
294+
return proc;
295+
296+
catlist = SearchSysCacheList(CONDEFAULT, 3,
297+
ObjectIdGetDatum(name_space),
298+
Int32GetDatum(for_encoding),
299+
Int32GetDatum(to_encoding),
300+
0);
301+
302+
for (i = 0; i < catlist->n_members; i++)
303+
{
304+
tuple = &catlist->members[i]->tuple;
305+
body = (Form_pg_conversion)GETSTRUCT(tuple);
306+
if (body->condefault == TRUE)
307+
{
308+
proc = body->conproc;
309+
break;
310+
}
311+
}
312+
ReleaseSysCacheList(catlist);
313+
return proc;
314+
}
208315

209316
/* ----------------
210317
* FindConversionByName
211318
*
212-
* find conversion proc by possibly qualified conversion name.
319+
* Find conversion proc by possibly qualified conversion name.
213320
* ---------------
214321
*/
215322
Oid FindConversionByName(List *name)

src/backend/commands/conversioncmds.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.1 2002/07/11 07:39:27 ishii Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.2 2002/07/25 10:07:11 ishii Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -90,7 +90,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
9090
* DROP CONVERSION
9191
*/
9292
void
93-
DropConversionCommand(List *name)
93+
DropConversionCommand(List *name, DropBehavior behavior)
9494
{
9595
Oid namespaceId;
9696
char *conversion_name;
@@ -108,5 +108,5 @@ DropConversionCommand(List *name)
108108
* none existing conversion
109109
* not ower of this conversion
110110
*/
111-
ConversionDrop(conversion_name, namespaceId, GetUserId());
111+
ConversionDrop(conversion_name, namespaceId, GetUserId(), behavior);
112112
}

src/backend/tcop/utility.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.164 2002/07/18 23:11:28 petere Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.165 2002/07/25 10:07:11 ishii Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -318,8 +318,7 @@ ProcessUtility(Node *parsetree,
318318
break;
319319

320320
case DROP_CONVERSION:
321-
/* does its own permissions checks */
322-
DropConversionCommand(names);
321+
DropConversionCommand(names, stmt->behavior);
323322
break;
324323

325324
case DROP_SCHEMA:

src/backend/utils/cache/syscache.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.83 2002/07/20 05:16:58 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.84 2002/07/25 10:07:12 ishii Exp $
1212
*
1313
* NOTES
1414
* These routines allow the parser/planner/executor to perform
@@ -206,6 +206,16 @@ static const struct cachedesc cacheinfo[] = {
206206
0,
207207
0
208208
}},
209+
{ConversionRelationName, /* CONDEFAULT */
210+
ConversionDefaultIndex,
211+
0,
212+
4,
213+
{
214+
Anum_pg_conversion_connamespace,
215+
Anum_pg_conversion_conforencoding,
216+
Anum_pg_conversion_contoencoding,
217+
ObjectIdAttributeNumber,
218+
}},
209219
{ConversionRelationName, /* CONNAMENSP */
210220
ConversionNameNspIndex,
211221
0,
@@ -216,6 +226,16 @@ static const struct cachedesc cacheinfo[] = {
216226
0,
217227
0
218228
}},
229+
{ConversionRelationName, /* CONOID */
230+
ConversionOidIndex,
231+
0,
232+
1,
233+
{
234+
ObjectIdAttributeNumber,
235+
0,
236+
0,
237+
0
238+
}},
219239
{GroupRelationName, /* GRONAME */
220240
GroupNameIndex,
221241
0,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy