1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

Implement DROP CONVERSION

Add regression test
This commit is contained in:
Tatsuo Ishii
2002-07-25 10:07:13 +00:00
parent 8d600a7d1f
commit 0345f58496
16 changed files with 852 additions and 104 deletions

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.5 2002/07/18 23:11:27 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.6 2002/07/25 10:07:10 ishii Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +23,7 @@
#include "catalog/indexing.h"
#include "catalog/pg_attrdef.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_language.h"
#include "catalog/pg_namespace.h"
@@ -52,6 +53,7 @@ typedef enum ObjectClasses
OCLASS_PROC, /* pg_proc */
OCLASS_TYPE, /* pg_type */
OCLASS_CONSTRAINT, /* pg_constraint */
OCLASS_CONVERSION, /* pg_conversion */
OCLASS_DEFAULT, /* pg_attrdef */
OCLASS_LANGUAGE, /* pg_language */
OCLASS_OPERATOR, /* pg_operator */
@@ -581,6 +583,10 @@ doDeletion(const ObjectAddress *object)
RemoveConstraintById(object->objectId);
break;
case OCLASS_CONVERSION:
RemoveConversionById(object->objectId);
break;
case OCLASS_DEFAULT:
RemoveAttrDefaultById(object->objectId);
break;
@@ -989,6 +995,7 @@ init_object_classes(void)
object_classes[OCLASS_PROC] = RelOid_pg_proc;
object_classes[OCLASS_TYPE] = RelOid_pg_type;
object_classes[OCLASS_CONSTRAINT] = get_system_catalog_relid(ConstraintRelationName);
object_classes[OCLASS_CONVERSION] = get_system_catalog_relid(ConversionRelationName);
object_classes[OCLASS_DEFAULT] = get_system_catalog_relid(AttrDefaultRelationName);
object_classes[OCLASS_LANGUAGE] = get_system_catalog_relid(LanguageRelationName);
object_classes[OCLASS_OPERATOR] = get_system_catalog_relid(OperatorRelationName);
@@ -1039,6 +1046,11 @@ getObjectClass(const ObjectAddress *object)
Assert(object->objectSubId == 0);
return OCLASS_CONSTRAINT;
}
if (object->classId == object_classes[OCLASS_CONVERSION])
{
Assert(object->objectSubId == 0);
return OCLASS_CONVERSION;
}
if (object->classId == object_classes[OCLASS_DEFAULT])
{
Assert(object->objectSubId == 0);
@@ -1165,6 +1177,22 @@ getObjectDescription(const ObjectAddress *object)
break;
}
case OCLASS_CONVERSION:
{
HeapTuple conTup;
conTup = SearchSysCache(CONOID,
ObjectIdGetDatum(object->objectId),
0, 0, 0);
if (!HeapTupleIsValid(conTup))
elog(ERROR, "getObjectDescription: Conversion %u does not exist",
object->objectId);
appendStringInfo(&buffer, "conversion %s",
NameStr(((Form_pg_conversion) GETSTRUCT(conTup))->conname));
ReleaseSysCache(conTup);
break;
}
case OCLASS_DEFAULT:
{
Relation attrdefDesc;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.2 2002/07/16 06:58:44 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.3 2002/07/25 10:07:10 ishii Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,11 +16,15 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_class.h"
#include "catalog/pg_conversion.h"
#include "catalog/namespace.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/catcache.h"
#include "mb/pg_wchar.h"
#include "utils/fmgroids.h"
#include "utils/acl.h"
@@ -28,6 +32,8 @@
/* ----------------
* ConversionCreate
*
* Add a new tuple to pg_coversion.
* ---------------
*/
Oid ConversionCreate(const char *conname, Oid connamespace,
@@ -43,6 +49,8 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
Datum values[Natts_pg_conversion];
NameData cname;
Oid oid;
ObjectAddress myself,
referenced;
/* sanity checks */
if (!conname)
@@ -85,7 +93,10 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def);
if (def == true)
values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def);
else
nulls[Anum_pg_conversion_condefault - 1] = 'n';
tup = heap_formtuple(tupDesc, values, nulls);
@@ -103,6 +114,17 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
CatalogCloseIndices(Num_pg_conversion_indices, idescs);
}
myself.classId = get_system_catalog_relid(ConversionRelationName);
myself.objectId = HeapTupleGetOid(tup);
myself.objectSubId = 0;
/* dependency on conversion procedure */
referenced.classId = RelOid_pg_proc;
referenced.objectId = conproc;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
return oid;
@@ -110,9 +132,12 @@ Oid ConversionCreate(const char *conname, Oid connamespace,
/* ----------------
* ConversionDrop
*
* Drop a conversion and do dependency check.
* ---------------
*/
void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
void ConversionDrop(const char *conname, Oid connamespace,
int32 conowner, DropBehavior behavior)
{
Relation rel;
TupleDesc tupDesc;
@@ -120,6 +145,8 @@ void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
HeapScanDesc scan;
ScanKeyData scanKeyData;
Form_pg_conversion body;
ObjectAddress object;
Oid myoid;
/* sanity checks */
if (!conname)
@@ -132,7 +159,7 @@ void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
ObjectIdGetDatum(connamespace));
/* open pg_conversion */
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
rel = heap_openr(ConversionRelationName, AccessShareLock);
tupDesc = rel->rd_att;
scan = heap_beginscan(rel, SnapshotNow,
@@ -155,8 +182,53 @@ void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
if (!superuser() && ((Form_pg_conversion)GETSTRUCT(tuple))->conowner != GetUserId())
elog(ERROR, "permission denied");
simple_heap_delete(rel, &tuple->t_self);
myoid = HeapTupleGetOid(tuple);
heap_endscan(scan);
heap_close(rel, AccessShareLock);
/*
* Do the deletion
*/
object.classId = get_system_catalog_relid(ConversionRelationName);
object.objectId = myoid;
object.objectSubId = 0;
performDeletion(&object, behavior);
}
/* ----------------
* RemoveConversionById
*
* Remove a tuple from pg_conversion by Oid. This function is soley
* called inside catalog/dependency.c
* --------------- */
void
RemoveConversionById(Oid conversionOid)
{
Relation rel;
TupleDesc tupDesc;
HeapTuple tuple;
HeapScanDesc scan;
ScanKeyData scanKeyData;
ScanKeyEntryInitialize(&scanKeyData,
0,
ObjectIdAttributeNumber,
F_OIDEQ,
ObjectIdGetDatum(conversionOid));
/* open pg_conversion */
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
tupDesc = rel->rd_att;
scan = heap_beginscan(rel, SnapshotNow,
1, &scanKeyData);
/* search for the target tuple */
if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
simple_heap_delete(rel, &tuple->t_self);
else
elog(ERROR, "Conversion %u does not exist", conversionOid);
heap_endscan(scan);
heap_close(rel, RowExclusiveLock);
}
@@ -164,9 +236,11 @@ void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
/* ----------------
* FindDefaultConversion
*
* find default conversion proc by for_encoding and to_encoding in this name space
* Find "default" conversion proc by for_encoding and to_encoding in this name space.
* If found, returns the procedure's oid, otherwise InvalidOid.
* ---------------
*/
#ifdef NOT_USED
Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
{
Relation rel;
@@ -205,11 +279,44 @@ Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
heap_close(rel, AccessShareLock);
return proc;
}
#endif
Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
{
CatCList *catlist;
HeapTuple tuple;
Form_pg_conversion body;
Oid proc = InvalidOid;
int i;
/* Check we have usage rights in target namespace */
if (pg_namespace_aclcheck(name_space, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
return proc;
catlist = SearchSysCacheList(CONDEFAULT, 3,
ObjectIdGetDatum(name_space),
Int32GetDatum(for_encoding),
Int32GetDatum(to_encoding),
0);
for (i = 0; i < catlist->n_members; i++)
{
tuple = &catlist->members[i]->tuple;
body = (Form_pg_conversion)GETSTRUCT(tuple);
if (body->condefault == TRUE)
{
proc = body->conproc;
break;
}
}
ReleaseSysCacheList(catlist);
return proc;
}
/* ----------------
* FindConversionByName
*
* find conversion proc by possibly qualified conversion name.
* Find conversion proc by possibly qualified conversion name.
* ---------------
*/
Oid FindConversionByName(List *name)

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.1 2002/07/11 07:39:27 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.2 2002/07/25 10:07:11 ishii Exp $
*
*-------------------------------------------------------------------------
*/
@@ -90,7 +90,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
* DROP CONVERSION
*/
void
DropConversionCommand(List *name)
DropConversionCommand(List *name, DropBehavior behavior)
{
Oid namespaceId;
char *conversion_name;
@@ -108,5 +108,5 @@ DropConversionCommand(List *name)
* none existing conversion
* not ower of this conversion
*/
ConversionDrop(conversion_name, namespaceId, GetUserId());
ConversionDrop(conversion_name, namespaceId, GetUserId(), behavior);
}

View File

@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.164 2002/07/18 23:11:28 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.165 2002/07/25 10:07:11 ishii Exp $
*
*-------------------------------------------------------------------------
*/
@@ -318,8 +318,7 @@ ProcessUtility(Node *parsetree,
break;
case DROP_CONVERSION:
/* does its own permissions checks */
DropConversionCommand(names);
DropConversionCommand(names, stmt->behavior);
break;
case DROP_SCHEMA:

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.83 2002/07/20 05:16:58 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.84 2002/07/25 10:07:12 ishii Exp $
*
* NOTES
* These routines allow the parser/planner/executor to perform
@@ -206,6 +206,16 @@ static const struct cachedesc cacheinfo[] = {
0,
0
}},
{ConversionRelationName, /* CONDEFAULT */
ConversionDefaultIndex,
0,
4,
{
Anum_pg_conversion_connamespace,
Anum_pg_conversion_conforencoding,
Anum_pg_conversion_contoencoding,
ObjectIdAttributeNumber,
}},
{ConversionRelationName, /* CONNAMENSP */
ConversionNameNspIndex,
0,
@@ -216,6 +226,16 @@ static const struct cachedesc cacheinfo[] = {
0,
0
}},
{ConversionRelationName, /* CONOID */
ConversionOidIndex,
0,
1,
{
ObjectIdAttributeNumber,
0,
0,
0
}},
{GroupRelationName, /* GRONAME */
GroupNameIndex,
0,

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.93 2002/06/20 20:29:40 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.94 2002/07/25 10:07:12 ishii Exp $
*
*-------------------------------------------------------------------------
*/
@@ -185,56 +185,6 @@ SetDataDir(const char *dir)
DataDir = new;
}
/* ----------------------------------------------------------------
* MULTIBYTE stub code
*
* Even if MULTIBYTE is not enabled, these functions are necessary
* since pg_proc.h has references to them.
* ----------------------------------------------------------------
*/
#ifndef MULTIBYTE
Datum
getdatabaseencoding(PG_FUNCTION_ARGS)
{
return DirectFunctionCall1(namein, CStringGetDatum("SQL_ASCII"));
}
Datum
pg_client_encoding(PG_FUNCTION_ARGS)
{
return DirectFunctionCall1(namein, CStringGetDatum("SQL_ASCII"));
}
Datum
PG_encoding_to_char(PG_FUNCTION_ARGS)
{
return DirectFunctionCall1(namein, CStringGetDatum("SQL_ASCII"));
}
Datum
PG_char_to_encoding(PG_FUNCTION_ARGS)
{
PG_RETURN_INT32(0);
}
Datum
pg_convert(PG_FUNCTION_ARGS)
{
elog(ERROR, "convert is not supported. To use convert, you need to enable multibyte capability");
return DirectFunctionCall1(textin, CStringGetDatum(""));
}
Datum
pg_convert2(PG_FUNCTION_ARGS)
{
elog(ERROR, "convert is not supported. To use convert, you need to enable multibyte capability");
return DirectFunctionCall1(textin, CStringGetDatum(""));
}
#endif
/* ----------------------------------------------------------------
* CYR_RECODE support
* ----------------------------------------------------------------

View File

@@ -3,10 +3,10 @@
* client encoding and server internal encoding.
* (currently mule internal code (mic) is used)
* Tatsuo Ishii
* $Id: mbutils.c,v 1.28 2002/07/18 02:02:30 ishii Exp $
* $Id: mbutils.c,v 1.29 2002/07/25 10:07:12 ishii Exp $
*/
#include "postgres.h"
#include "access/xact.h"
#include "miscadmin.h"
#include "mb/pg_wchar.h"
#include "utils/builtins.h"
@@ -35,7 +35,8 @@ SetClientEncoding(int encoding, bool doit)
if (!PG_VALID_FE_ENCODING(encoding))
return (-1);
if (current_server_encoding == encoding)
if (current_server_encoding == encoding ||
(current_server_encoding == PG_SQL_ASCII || encoding == PG_SQL_ASCII))
{
ClientEncoding = &pg_enc2name_tbl[encoding];
return 0;
@@ -102,9 +103,15 @@ pg_do_encoding_conversion(unsigned char *src, int len,
unsigned char *result;
Oid proc;
if (!IsTransactionState())
return src;
if (src_encoding == dest_encoding)
return src;
if (src_encoding == PG_SQL_ASCII || dest_encoding == PG_SQL_ASCII)
return src;
proc = FindDefaultConversionProc(src_encoding, dest_encoding);
if (!OidIsValid(proc))
{