Fix permissions-checking bugs and namespace-search-path bugs in
CONVERSION code. Still need to figure out what to do about inappropriate coding in parsing.
This commit is contained in:
parent
08dd92cdeb
commit
6a7273e14c
|
@ -1,4 +1,4 @@
|
||||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_conversion.sgml,v 1.4 2002/09/21 18:32:54 petere Exp $ -->
|
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_conversion.sgml,v 1.5 2002/11/02 02:33:03 tgl Exp $ -->
|
||||||
|
|
||||||
<refentry id="SQL-CREATECONVERSION">
|
<refentry id="SQL-CREATECONVERSION">
|
||||||
<refmeta>
|
<refmeta>
|
||||||
|
@ -14,8 +14,7 @@
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
|
CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
|
||||||
FOR <replaceable>source_encoding</replaceable>
|
FOR <replaceable>source_encoding</replaceable> TO <replaceable>dest_encoding</replaceable> FROM <replaceable>funcname</replaceable>
|
||||||
TO <replaceable>dest_encoding</replaceable> FROM <replaceable>funcname</replaceable>
|
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
@ -24,18 +23,16 @@ CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>CREATE CONVERSION</command> defines a new encoding
|
<command>CREATE CONVERSION</command> defines a new encoding
|
||||||
conversion. There are two kinds of conversions. A default
|
conversion. Conversion names may be used in the CONVERT() function
|
||||||
conversion is used for an automatic encoding conversion between
|
to specify a particular encoding conversion. Also, conversions that
|
||||||
frontend and backend. There should be only one default conversion
|
are marked DEFAULT can be used for automatic encoding conversion between
|
||||||
for source/destination encodings pair in a schema. None default
|
frontend and backend. For this purpose, two conversions, from encoding A to
|
||||||
conversion never be used for the automatic conversion. Instead it
|
B AND from encoding B to A, must be defined.
|
||||||
can be used for CONVERT() function.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To be able to create a conversion, you must have the execute right
|
To be able to create a conversion, you must have the execute right
|
||||||
on the function and the usage right on the schema the function
|
on the function and the create right on the destination schema.
|
||||||
belongs to.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
@ -49,11 +46,7 @@ CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
|
||||||
The <literal>DEFAULT</> clause indicates that this conversion
|
The <literal>DEFAULT</> clause indicates that this conversion
|
||||||
is the default for this particular source to destination
|
is the default for this particular source to destination
|
||||||
encoding. There should be only one default encoding in a schema
|
encoding. There should be only one default encoding in a schema
|
||||||
for the encoding pair. A default encoding can be used for not
|
for the encoding pair.
|
||||||
only CONVERT() function, but also for the automatic encoding
|
|
||||||
conversion between frontend and backend. For this purpose, two
|
|
||||||
conversions, from encoding A to B AND encoding B to A, must be
|
|
||||||
defined.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -64,8 +57,8 @@ CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The name of the conversion. The conversion name may be
|
The name of the conversion. The conversion name may be
|
||||||
schema-qualified. If it is not, a conversion is defined in the
|
schema-qualified. If it is not, the conversion is defined in the
|
||||||
current schema. The conversion name must be unique with in a
|
current schema. The conversion name must be unique within a
|
||||||
schema.
|
schema.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -102,7 +95,7 @@ CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The function must have following signature:
|
The function must have the following signature:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
conv_proc(
|
conv_proc(
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.36 2002/09/23 20:43:40 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.37 2002/11/02 02:33:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1275,32 +1275,33 @@ PopSpecialNamespace(Oid namespaceId)
|
||||||
Oid
|
Oid
|
||||||
FindConversionByName(List *name)
|
FindConversionByName(List *name)
|
||||||
{
|
{
|
||||||
|
char *schemaname;
|
||||||
char *conversion_name;
|
char *conversion_name;
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
Oid conoid;
|
Oid conoid;
|
||||||
List *lptr;
|
List *lptr;
|
||||||
|
|
||||||
/* Convert list of names to a name and namespace */
|
/* deconstruct the name list */
|
||||||
namespaceId = QualifiedNameGetCreationNamespace(name, &conversion_name);
|
DeconstructQualifiedName(name, &schemaname, &conversion_name);
|
||||||
|
|
||||||
if (length(name) > 1)
|
if (schemaname)
|
||||||
{
|
{
|
||||||
/* Check we have usage rights in target namespace */
|
/* use exact schema given */
|
||||||
if (pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
|
namespaceId = LookupExplicitNamespace(schemaname);
|
||||||
return InvalidOid;
|
|
||||||
|
|
||||||
return FindConversion(conversion_name, namespaceId);
|
return FindConversion(conversion_name, namespaceId);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
recomputeNamespacePath();
|
|
||||||
|
|
||||||
foreach(lptr, namespaceSearchPath)
|
|
||||||
{
|
{
|
||||||
Oid namespaceId = (Oid) lfirsti(lptr);
|
/* search for it in search path */
|
||||||
|
recomputeNamespacePath();
|
||||||
|
|
||||||
conoid = FindConversion(conversion_name, namespaceId);
|
foreach(lptr, namespaceSearchPath)
|
||||||
if (OidIsValid(conoid))
|
{
|
||||||
return conoid;
|
namespaceId = (Oid) lfirsti(lptr);
|
||||||
|
conoid = FindConversion(conversion_name, namespaceId);
|
||||||
|
if (OidIsValid(conoid))
|
||||||
|
return conoid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not found in path */
|
/* Not found in path */
|
||||||
|
@ -1308,7 +1309,7 @@ FindConversionByName(List *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FindDefaultConversionProc - find default encoding cnnversion proc
|
* FindDefaultConversionProc - find default encoding conversion proc
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
|
FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.6 2002/09/04 20:31:14 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.7 2002/11/02 02:33:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -30,16 +30,15 @@
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* ConversionCreate
|
* ConversionCreate
|
||||||
*
|
*
|
||||||
* Add a new tuple to pg_coversion.
|
* Add a new tuple to pg_conversion.
|
||||||
* ---------------
|
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
ConversionCreate(const char *conname, Oid connamespace,
|
ConversionCreate(const char *conname, Oid connamespace,
|
||||||
int32 conowner,
|
int32 conowner,
|
||||||
int4 conforencoding, int4 contoencoding,
|
int32 conforencoding, int32 contoencoding,
|
||||||
Oid conproc, bool def)
|
Oid conproc, bool def)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -58,7 +57,7 @@ ConversionCreate(const char *conname, Oid connamespace,
|
||||||
elog(ERROR, "no conversion name supplied");
|
elog(ERROR, "no conversion name supplied");
|
||||||
|
|
||||||
/* make sure there is no existing conversion of same name */
|
/* make sure there is no existing conversion of same name */
|
||||||
if (SearchSysCacheExists(CONNAMESP,
|
if (SearchSysCacheExists(CONNAMENSP,
|
||||||
PointerGetDatum(conname),
|
PointerGetDatum(conname),
|
||||||
ObjectIdGetDatum(connamespace),
|
ObjectIdGetDatum(connamespace),
|
||||||
0, 0))
|
0, 0))
|
||||||
|
@ -74,7 +73,8 @@ ConversionCreate(const char *conname, Oid connamespace,
|
||||||
conforencoding,
|
conforencoding,
|
||||||
contoencoding))
|
contoencoding))
|
||||||
elog(ERROR, "default conversion for %s to %s already exists",
|
elog(ERROR, "default conversion for %s to %s already exists",
|
||||||
pg_encoding_to_char(conforencoding), pg_encoding_to_char(contoencoding));
|
pg_encoding_to_char(conforencoding),
|
||||||
|
pg_encoding_to_char(contoencoding));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open pg_conversion */
|
/* open pg_conversion */
|
||||||
|
@ -96,10 +96,7 @@ ConversionCreate(const char *conname, Oid connamespace,
|
||||||
values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
|
values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
|
||||||
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
|
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
|
||||||
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
|
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
|
||||||
if (def == true)
|
values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def);
|
||||||
values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def);
|
|
||||||
else
|
|
||||||
nulls[Anum_pg_conversion_condefault - 1] = 'n';
|
|
||||||
|
|
||||||
tup = heap_formtuple(tupDesc, values, nulls);
|
tup = heap_formtuple(tupDesc, values, nulls);
|
||||||
|
|
||||||
|
@ -110,11 +107,11 @@ ConversionCreate(const char *conname, Oid connamespace,
|
||||||
/* update the index if any */
|
/* update the index if any */
|
||||||
CatalogUpdateIndexes(rel, tup);
|
CatalogUpdateIndexes(rel, tup);
|
||||||
|
|
||||||
myself.classId = get_system_catalog_relid(ConversionRelationName);
|
myself.classId = RelationGetRelid(rel);
|
||||||
myself.objectId = HeapTupleGetOid(tup);
|
myself.objectId = HeapTupleGetOid(tup);
|
||||||
myself.objectSubId = 0;
|
myself.objectSubId = 0;
|
||||||
|
|
||||||
/* dependency on conversion procedure */
|
/* create dependency on conversion procedure */
|
||||||
referenced.classId = RelOid_pg_proc;
|
referenced.classId = RelOid_pg_proc;
|
||||||
referenced.objectId = conproc;
|
referenced.objectId = conproc;
|
||||||
referenced.objectSubId = 0;
|
referenced.objectSubId = 0;
|
||||||
|
@ -126,79 +123,46 @@ ConversionCreate(const char *conname, Oid connamespace,
|
||||||
return oid;
|
return oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* ConversionDrop
|
* ConversionDrop
|
||||||
*
|
*
|
||||||
* Drop a conversion and do dependency check.
|
* Drop a conversion after doing permission checks.
|
||||||
* ---------------
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ConversionDrop(const char *conname, Oid connamespace,
|
ConversionDrop(Oid conversionOid, DropBehavior behavior)
|
||||||
int32 conowner, DropBehavior behavior)
|
|
||||||
{
|
{
|
||||||
Relation rel;
|
|
||||||
TupleDesc tupDesc;
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
HeapScanDesc scan;
|
|
||||||
ScanKeyData scanKeyData;
|
|
||||||
Form_pg_conversion body;
|
|
||||||
ObjectAddress object;
|
ObjectAddress object;
|
||||||
Oid myoid;
|
|
||||||
|
|
||||||
/* sanity checks */
|
|
||||||
if (!conname)
|
|
||||||
elog(ERROR, "no conversion name supplied");
|
|
||||||
|
|
||||||
ScanKeyEntryInitialize(&scanKeyData,
|
|
||||||
0,
|
|
||||||
Anum_pg_conversion_connamespace,
|
|
||||||
F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(connamespace));
|
|
||||||
|
|
||||||
/* open pg_conversion */
|
|
||||||
rel = heap_openr(ConversionRelationName, AccessShareLock);
|
|
||||||
tupDesc = rel->rd_att;
|
|
||||||
|
|
||||||
scan = heap_beginscan(rel, SnapshotNow,
|
|
||||||
1, &scanKeyData);
|
|
||||||
|
|
||||||
/* search for the target tuple */
|
|
||||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
|
|
||||||
{
|
|
||||||
body = (Form_pg_conversion) GETSTRUCT(tuple);
|
|
||||||
if (!strncmp(NameStr(body->conname), conname, NAMEDATALEN))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tuple = SearchSysCache(CONOID,
|
||||||
|
ObjectIdGetDatum(conversionOid),
|
||||||
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
{
|
elog(ERROR, "Conversion %u search from syscache failed",
|
||||||
elog(ERROR, "conversion %s not found", conname);
|
conversionOid);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!superuser() && ((Form_pg_conversion) GETSTRUCT(tuple))->conowner != GetUserId())
|
if (!superuser() &&
|
||||||
|
((Form_pg_conversion) GETSTRUCT(tuple))->conowner != GetUserId())
|
||||||
elog(ERROR, "permission denied");
|
elog(ERROR, "permission denied");
|
||||||
|
|
||||||
myoid = HeapTupleGetOid(tuple);
|
ReleaseSysCache(tuple);
|
||||||
heap_endscan(scan);
|
|
||||||
heap_close(rel, AccessShareLock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the deletion
|
* Do the deletion
|
||||||
*/
|
*/
|
||||||
object.classId = get_system_catalog_relid(ConversionRelationName);
|
object.classId = get_system_catalog_relid(ConversionRelationName);
|
||||||
object.objectId = myoid;
|
object.objectId = conversionOid;
|
||||||
object.objectSubId = 0;
|
object.objectSubId = 0;
|
||||||
|
|
||||||
performDeletion(&object, behavior);
|
performDeletion(&object, behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* RemoveConversionById
|
* RemoveConversionById
|
||||||
*
|
*
|
||||||
* Remove a tuple from pg_conversion by Oid. This function is soley
|
* Remove a tuple from pg_conversion by Oid. This function is solely
|
||||||
* called inside catalog/dependency.c
|
* called inside catalog/dependency.c
|
||||||
* --------------- */
|
*/
|
||||||
void
|
void
|
||||||
RemoveConversionById(Oid conversionOid)
|
RemoveConversionById(Oid conversionOid)
|
||||||
{
|
{
|
||||||
|
@ -230,15 +194,17 @@ RemoveConversionById(Oid conversionOid)
|
||||||
heap_close(rel, RowExclusiveLock);
|
heap_close(rel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* FindDefaultConversion
|
* 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 the
|
||||||
* If found, returns the procedure's oid, otherwise InvalidOid.
|
* given namespace.
|
||||||
* ---------------
|
*
|
||||||
|
* If found, returns the procedure's oid, otherwise InvalidOid. Note that
|
||||||
|
* you get the procedure's OID not the conversion's OID!
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
|
FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
|
||||||
{
|
{
|
||||||
CatCList *catlist;
|
CatCList *catlist;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
@ -246,10 +212,6 @@ FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
|
||||||
Oid proc = InvalidOid;
|
Oid proc = InvalidOid;
|
||||||
int i;
|
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,
|
catlist = SearchSysCacheList(CONDEFAULT, 3,
|
||||||
ObjectIdGetDatum(name_space),
|
ObjectIdGetDatum(name_space),
|
||||||
Int32GetDatum(for_encoding),
|
Int32GetDatum(for_encoding),
|
||||||
|
@ -260,7 +222,7 @@ FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
|
||||||
{
|
{
|
||||||
tuple = &catlist->members[i]->tuple;
|
tuple = &catlist->members[i]->tuple;
|
||||||
body = (Form_pg_conversion) GETSTRUCT(tuple);
|
body = (Form_pg_conversion) GETSTRUCT(tuple);
|
||||||
if (body->condefault == TRUE)
|
if (body->condefault)
|
||||||
{
|
{
|
||||||
proc = body->conproc;
|
proc = body->conproc;
|
||||||
break;
|
break;
|
||||||
|
@ -270,12 +232,11 @@ FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* FindConversionByName
|
* FindConversion
|
||||||
*
|
*
|
||||||
* Find conversion by namespace and conversion name.
|
* Find conversion by namespace and conversion name.
|
||||||
* Returns conversion oid.
|
* Returns conversion OID.
|
||||||
* ---------------
|
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
FindConversion(const char *conname, Oid connamespace)
|
FindConversion(const char *conname, Oid connamespace)
|
||||||
|
@ -286,13 +247,13 @@ FindConversion(const char *conname, Oid connamespace)
|
||||||
AclResult aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
/* search pg_conversion by connamespace and conversion name */
|
/* search pg_conversion by connamespace and conversion name */
|
||||||
tuple = SearchSysCache(CONNAMESP,
|
tuple = SearchSysCache(CONNAMENSP,
|
||||||
PointerGetDatum(conname),
|
PointerGetDatum(conname),
|
||||||
ObjectIdGetDatum(connamespace),
|
ObjectIdGetDatum(connamespace),
|
||||||
0, 0);
|
0, 0);
|
||||||
|
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
return InvalidOid;
|
return InvalidOid;
|
||||||
|
|
||||||
procoid = ((Form_pg_conversion) GETSTRUCT(tuple))->conproc;
|
procoid = ((Form_pg_conversion) GETSTRUCT(tuple))->conproc;
|
||||||
conoid = HeapTupleGetOid(tuple);
|
conoid = HeapTupleGetOid(tuple);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.4 2002/09/04 20:31:14 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.5 2002/11/02 02:33:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -38,17 +38,14 @@ CreateConversionCommand(CreateConversionStmt *stmt)
|
||||||
int for_encoding;
|
int for_encoding;
|
||||||
int to_encoding;
|
int to_encoding;
|
||||||
Oid funcoid;
|
Oid funcoid;
|
||||||
Oid funcnamespace;
|
|
||||||
char *dummy;
|
|
||||||
|
|
||||||
const char *for_encoding_name = stmt->for_encoding_name;
|
const char *for_encoding_name = stmt->for_encoding_name;
|
||||||
const char *to_encoding_name = stmt->to_encoding_name;
|
const char *to_encoding_name = stmt->to_encoding_name;
|
||||||
List *func_name = stmt->func_name;
|
List *func_name = stmt->func_name;
|
||||||
|
|
||||||
static Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, CSTRINGOID, INT4OID};
|
static Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, CSTRINGOID, INT4OID};
|
||||||
|
|
||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name, &conversion_name);
|
namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name,
|
||||||
|
&conversion_name);
|
||||||
|
|
||||||
/* Check we have creation rights in target namespace */
|
/* Check we have creation rights in target namespace */
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
|
||||||
|
@ -70,17 +67,13 @@ CreateConversionCommand(CreateConversionStmt *stmt)
|
||||||
*/
|
*/
|
||||||
funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid), funcargs);
|
funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid), funcargs);
|
||||||
if (!OidIsValid(funcoid))
|
if (!OidIsValid(funcoid))
|
||||||
elog(ERROR, "Function %s does not exist", NameListToString(func_name));
|
func_error("CreateConversion", func_name,
|
||||||
|
sizeof(funcargs) / sizeof(Oid), funcargs, NULL);
|
||||||
/* Check the rights for this function and name space */
|
|
||||||
funcnamespace = QualifiedNameGetCreationNamespace(func_name, &dummy);
|
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
|
|
||||||
if (aclresult != ACLCHECK_OK)
|
|
||||||
aclcheck_error(aclresult, get_namespace_name(funcnamespace));
|
|
||||||
|
|
||||||
|
/* Check we have EXECUTE rights for the function */
|
||||||
aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
|
aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, get_namespace_name(funcnamespace));
|
aclcheck_error(aclresult, NameListToString(func_name));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All seem ok, go ahead (possible failure would be a duplicate
|
* All seem ok, go ahead (possible failure would be a duplicate
|
||||||
|
@ -96,21 +89,12 @@ CreateConversionCommand(CreateConversionStmt *stmt)
|
||||||
void
|
void
|
||||||
DropConversionCommand(List *name, DropBehavior behavior)
|
DropConversionCommand(List *name, DropBehavior behavior)
|
||||||
{
|
{
|
||||||
Oid namespaceId;
|
Oid conversionOid;
|
||||||
char *conversion_name;
|
|
||||||
AclResult aclresult;
|
|
||||||
|
|
||||||
/* Convert list of names to a name and namespace */
|
conversionOid = FindConversionByName(name);
|
||||||
namespaceId = QualifiedNameGetCreationNamespace(name, &conversion_name);
|
|
||||||
|
|
||||||
/* Check we have creation rights in target namespace */
|
if (!OidIsValid(conversionOid))
|
||||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
|
elog(ERROR, "conversion %s not found", NameListToString(name));
|
||||||
if (aclresult != ACLCHECK_OK)
|
|
||||||
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
|
||||||
|
|
||||||
/*
|
ConversionDrop(conversionOid, behavior);
|
||||||
* Go ahead (possible failure would be: none existing conversion not
|
|
||||||
* ower of this conversion
|
|
||||||
*/
|
|
||||||
ConversionDrop(conversion_name, namespaceId, GetUserId(), behavior);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_conversion.h,v 1.6 2002/09/04 20:31:37 momjian Exp $
|
* $Id: pg_conversion.h,v 1.7 2002/11/02 02:33:03 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -85,12 +85,11 @@ typedef FormData_pg_conversion *Form_pg_conversion;
|
||||||
|
|
||||||
extern Oid ConversionCreate(const char *conname, Oid connamespace,
|
extern Oid ConversionCreate(const char *conname, Oid connamespace,
|
||||||
int32 conowner,
|
int32 conowner,
|
||||||
int4 conforencoding, int4 contoencoding,
|
int32 conforencoding, int32 contoencoding,
|
||||||
Oid conproc, bool def);
|
Oid conproc, bool def);
|
||||||
extern void ConversionDrop(const char *conname, Oid connamespace,
|
extern void ConversionDrop(Oid conversionOid, DropBehavior behavior);
|
||||||
int32 conowner, DropBehavior behavior);
|
|
||||||
extern void RemoveConversionById(Oid conversionOid);
|
extern void RemoveConversionById(Oid conversionOid);
|
||||||
extern Oid FindConversion(const char *conname, Oid connamespace);
|
extern Oid FindConversion(const char *conname, Oid connamespace);
|
||||||
extern Oid FindDefaultConversion(Oid connamespace, int4 for_encoding, int4 to_encoding);
|
extern Oid FindDefaultConversion(Oid connamespace, int32 for_encoding, int32 to_encoding);
|
||||||
|
|
||||||
#endif /* PG_CONVERSION_H */
|
#endif /* PG_CONVERSION_H */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: syscache.h,v 1.53 2002/09/04 20:31:46 momjian Exp $
|
* $Id: syscache.h,v 1.54 2002/11/02 02:33:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
#define CLAAMNAMENSP 9
|
#define CLAAMNAMENSP 9
|
||||||
#define CLAOID 10
|
#define CLAOID 10
|
||||||
#define CONDEFAULT 11
|
#define CONDEFAULT 11
|
||||||
#define CONNAMESP 12
|
#define CONNAMENSP 12
|
||||||
#define CONOID 13
|
#define CONOID 13
|
||||||
#define GRONAME 14
|
#define GRONAME 14
|
||||||
#define GROSYSID 15
|
#define GROSYSID 15
|
||||||
|
|
Loading…
Reference in New Issue