mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08:00
Add new CREATE CONVERSION/DROP CONVERSION command.
This is the first cut toward CREATE CONVERSION/DROP CONVERSION implementaion. The commands can now add/remove tuples to the new pg_conversion system catalog, but that's all. Still need work to make them actually working. Documentations, regression tests also need work.
This commit is contained in:
parent
f2bb1cfa85
commit
fcc962566a
@ -2,7 +2,7 @@
|
||||
#
|
||||
# Makefile for backend/catalog
|
||||
#
|
||||
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.39 2002/03/26 19:15:22 tgl Exp $
|
||||
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.40 2002/07/11 07:39:27 ishii Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -12,7 +12,7 @@ include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \
|
||||
pg_aggregate.o pg_largeobject.o pg_namespace.o \
|
||||
pg_operator.o pg_proc.o pg_type.o
|
||||
pg_operator.o pg_proc.o pg_type.o pg_conversion.o
|
||||
|
||||
BKIFILES = postgres.bki postgres.description
|
||||
|
||||
@ -31,7 +31,8 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
|
||||
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
|
||||
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
|
||||
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
|
||||
pg_namespace.h pg_database.h pg_shadow.h pg_group.h indexing.h \
|
||||
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
|
||||
indexing.h \
|
||||
)
|
||||
|
||||
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.94 2002/06/20 20:29:26 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.95 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -45,6 +45,8 @@ char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
|
||||
{AttrDefaultIndex};
|
||||
char *Name_pg_class_indices[Num_pg_class_indices] =
|
||||
{ClassNameNspIndex, ClassOidIndex};
|
||||
char *Name_pg_conversion_indices[Num_pg_conversion_indices] =
|
||||
{ConversionNameNspIndex, ConversionDefaultIndex};
|
||||
char *Name_pg_database_indices[Num_pg_database_indices] =
|
||||
{DatabaseNameIndex, DatabaseOidIndex};
|
||||
char *Name_pg_group_indices[Num_pg_group_indices] =
|
||||
|
249
src/backend/catalog/pg_conversion.c
Normal file
249
src/backend/catalog/pg_conversion.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pg_conversion.c
|
||||
* routines to support manipulation of the pg_conversion relation
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.1 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/acl.h"
|
||||
#include "miscadmin.h"
|
||||
|
||||
/* ----------------
|
||||
* ConversionCreate
|
||||
* ---------------
|
||||
*/
|
||||
Oid ConversionCreate(const char *conname, Oid connamespace,
|
||||
int32 conowner,
|
||||
int4 conforencoding, int4 contoencoding,
|
||||
Oid conproc, bool def)
|
||||
{
|
||||
int i;
|
||||
Relation rel;
|
||||
TupleDesc tupDesc;
|
||||
HeapTuple tup;
|
||||
char nulls[Natts_pg_conversion];
|
||||
Datum values[Natts_pg_conversion];
|
||||
NameData cname;
|
||||
Oid oid;
|
||||
|
||||
/* sanity checks */
|
||||
if (!conname)
|
||||
elog(ERROR, "no conversion name supplied");
|
||||
|
||||
/* make sure there is no existing conversion of same name */
|
||||
if (SearchSysCacheExists(CONNAMESP,
|
||||
PointerGetDatum(conname),
|
||||
ObjectIdGetDatum(connamespace),
|
||||
0,0))
|
||||
elog(ERROR, "conversion name \"%s\" already exists", conname);
|
||||
|
||||
if (def)
|
||||
{
|
||||
/* make sure there is no existing default
|
||||
<for encoding><to encoding> pair in this name space */
|
||||
if (FindDefaultConversion(connamespace,
|
||||
conforencoding,
|
||||
contoencoding))
|
||||
elog(ERROR, "default conversion for %s to %s already exists",
|
||||
pg_encoding_to_char(conforencoding),pg_encoding_to_char(contoencoding));
|
||||
}
|
||||
|
||||
/* open pg_conversion */
|
||||
rel = heap_openr(ConversionRelationName, RowExclusiveLock);
|
||||
tupDesc = rel->rd_att;
|
||||
|
||||
/* initialize nulls and values */
|
||||
for (i = 0; i < Natts_pg_conversion; i++)
|
||||
{
|
||||
nulls[i] = ' ';
|
||||
values[i] = (Datum) NULL;
|
||||
}
|
||||
|
||||
/* form a tuple */
|
||||
namestrcpy(&cname, conname);
|
||||
values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname);
|
||||
values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace);
|
||||
values[Anum_pg_conversion_conowner - 1] = Int32GetDatum(conowner);
|
||||
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);
|
||||
|
||||
tup = heap_formtuple(tupDesc, values, nulls);
|
||||
|
||||
/* insert a new tuple */
|
||||
oid = simple_heap_insert(rel, tup);
|
||||
Assert(OidIsValid(oid));
|
||||
|
||||
/* update the index if any */
|
||||
if (RelationGetForm(rel)->relhasindex)
|
||||
{
|
||||
Relation idescs[Num_pg_conversion_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_conversion_indices, Name_pg_conversion_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_conversion_indices, rel, tup);
|
||||
CatalogCloseIndices(Num_pg_conversion_indices, idescs);
|
||||
}
|
||||
|
||||
heap_close(rel, RowExclusiveLock);
|
||||
|
||||
return oid;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* ConversionDrop
|
||||
* ---------------
|
||||
*/
|
||||
void ConversionDrop(const char *conname, Oid connamespace, int32 conowner)
|
||||
{
|
||||
Relation rel;
|
||||
TupleDesc tupDesc;
|
||||
HeapTuple tuple;
|
||||
HeapScanDesc scan;
|
||||
ScanKeyData scanKeyData;
|
||||
Form_pg_conversion body;
|
||||
|
||||
/* 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, RowExclusiveLock);
|
||||
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;
|
||||
}
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
{
|
||||
elog(ERROR, "conversion %s not found", conname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!superuser() && ((Form_pg_conversion)GETSTRUCT(tuple))->conowner != GetUserId())
|
||||
elog(ERROR, "permission denied");
|
||||
|
||||
simple_heap_delete(rel, &tuple->t_self);
|
||||
|
||||
heap_endscan(scan);
|
||||
heap_close(rel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* FindDefaultConversion
|
||||
*
|
||||
* find default conversion proc by for_encoding and to_encoding in this name space
|
||||
* ---------------
|
||||
*/
|
||||
Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
|
||||
{
|
||||
Relation rel;
|
||||
HeapScanDesc scan;
|
||||
ScanKeyData scanKeyData;
|
||||
HeapTuple tuple;
|
||||
Form_pg_conversion body;
|
||||
Oid proc = InvalidOid;
|
||||
|
||||
/* Check we have usage rights in target namespace */
|
||||
if (pg_namespace_aclcheck(name_space, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
|
||||
return InvalidOid;
|
||||
|
||||
ScanKeyEntryInitialize(&scanKeyData,
|
||||
0,
|
||||
Anum_pg_conversion_connamespace,
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(name_space));
|
||||
|
||||
rel = heap_openr(ConversionRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(rel, SnapshotNow,
|
||||
1, &scanKeyData);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
|
||||
{
|
||||
body = (Form_pg_conversion)GETSTRUCT(tuple);
|
||||
if (body->conforencoding == for_encoding &&
|
||||
body->conforencoding == to_encoding &&
|
||||
body->condefault == TRUE) {
|
||||
proc = body->conproc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
heap_endscan(scan);
|
||||
heap_close(rel, AccessShareLock);
|
||||
return proc;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* FindConversionByName
|
||||
*
|
||||
* find conversion proc by possibly qualified conversion name.
|
||||
* ---------------
|
||||
*/
|
||||
Oid FindConversionByName(List *name)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
char *conversion_name;
|
||||
Oid namespaceId;
|
||||
Oid procoid;
|
||||
AclResult aclresult;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
namespaceId = QualifiedNameGetCreationNamespace(name, &conversion_name);
|
||||
|
||||
/* Check we have usage rights in target namespace */
|
||||
if (pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
|
||||
return InvalidOid;
|
||||
|
||||
/* search pg_conversion by namespaceId and conversion name */
|
||||
tuple = SearchSysCache(CONNAMESP,
|
||||
PointerGetDatum(conversion_name),
|
||||
ObjectIdGetDatum(namespaceId),
|
||||
0,0);
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
return InvalidOid;
|
||||
|
||||
procoid = ((Form_pg_conversion)GETSTRUCT(tuple))->conproc;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
/* Check we have execute rights for the function */
|
||||
aclresult = pg_proc_aclcheck(procoid, GetUserId(), ACL_EXECUTE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
return InvalidOid;
|
||||
|
||||
return procoid;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Makefile for backend/commands
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.28 2002/04/15 05:22:03 tgl Exp $
|
||||
# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.29 2002/07/11 07:39:27 ishii Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -12,7 +12,8 @@ subdir = src/backend/commands
|
||||
top_builddir = ../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = aggregatecmds.o analyze.o async.o cluster.o comment.o copy.o \
|
||||
OBJS = aggregatecmds.o analyze.o async.o cluster.o comment.o \
|
||||
conversioncmds.o copy.o \
|
||||
dbcommands.o define.o explain.o functioncmds.o \
|
||||
indexcmds.o lockcmds.o operatorcmds.o portalcmds.o proclang.o \
|
||||
schemacmds.o sequence.o tablecmds.o trigger.o typecmds.o user.o \
|
||||
|
112
src/backend/commands/conversioncmds.c
Normal file
112
src/backend/commands/conversioncmds.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* conversionmacmds.c
|
||||
* conversion creation command support code
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/conversioncmds.c,v 1.1 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "commands/conversioncmds.h"
|
||||
#include "miscadmin.h"
|
||||
#include "parser/parse_func.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
||||
|
||||
/*
|
||||
* CREATE CONVERSION
|
||||
*/
|
||||
void
|
||||
CreateConversionCommand(CreateConversionStmt *stmt)
|
||||
{
|
||||
Oid namespaceId;
|
||||
char *conversion_name;
|
||||
AclResult aclresult;
|
||||
int for_encoding;
|
||||
int to_encoding;
|
||||
Oid funcoid;
|
||||
Oid funcnamespace;
|
||||
char *dummy;
|
||||
|
||||
const char *for_encoding_name = stmt->for_encoding_name;
|
||||
const char *to_encoding_name = stmt->to_encoding_name;
|
||||
List *func_name = stmt->func_name;
|
||||
|
||||
static Oid funcargs[] = {INT4OID, INT4OID, 0, 0, INT4OID};
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name, &conversion_name);
|
||||
|
||||
/* Check we have creation rights in target namespace */
|
||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||
|
||||
/* Check the encoding names */
|
||||
for_encoding = pg_char_to_encoding(for_encoding_name);
|
||||
if (for_encoding < 0)
|
||||
elog(ERROR, "Invalid for encoding name: %s", for_encoding_name);
|
||||
|
||||
to_encoding = pg_char_to_encoding(to_encoding_name);
|
||||
if (to_encoding < 0)
|
||||
elog(ERROR, "Invalid to encoding name: %s", to_encoding_name);
|
||||
|
||||
/* Check the existence of the conversion function.
|
||||
* Function name could be a qualified name.
|
||||
*/
|
||||
funcoid = LookupFuncName(func_name, sizeof(funcargs)/sizeof(Oid), funcargs);
|
||||
if (!OidIsValid(funcoid))
|
||||
elog(ERROR, "Function %s does not exist", NameListToString(func_name));
|
||||
|
||||
/* 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));
|
||||
|
||||
aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, get_namespace_name(funcnamespace));
|
||||
|
||||
/* All seem ok, go ahead (possible failure would be a duplicate conversion name) */
|
||||
ConversionCreate(conversion_name, namespaceId, GetUserId(),
|
||||
for_encoding, to_encoding, funcoid, stmt->def);
|
||||
}
|
||||
|
||||
/*
|
||||
* DROP CONVERSION
|
||||
*/
|
||||
void
|
||||
DropConversionCommand(List *name)
|
||||
{
|
||||
Oid namespaceId;
|
||||
char *conversion_name;
|
||||
AclResult aclresult;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
namespaceId = QualifiedNameGetCreationNamespace(name, &conversion_name);
|
||||
|
||||
/* Check we have creation rights in target namespace */
|
||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||
|
||||
/* Go ahead (possible failure would be:
|
||||
* none existing conversion
|
||||
* not ower of this conversion
|
||||
*/
|
||||
ConversionDrop(conversion_name, namespaceId, GetUserId());
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.337 2002/07/06 20:16:35 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.338 2002/07/11 07:39:25 ishii Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -157,7 +157,7 @@ static void doNegateFloat(Value *v);
|
||||
SelectStmt, TransactionStmt, TruncateStmt,
|
||||
UnlistenStmt, UpdateStmt, VacuumStmt,
|
||||
VariableResetStmt, VariableSetStmt, VariableShowStmt,
|
||||
ViewStmt, CheckPointStmt
|
||||
ViewStmt, CheckPointStmt, CreateConversionStmt
|
||||
|
||||
%type <node> select_no_parens, select_with_parens, select_clause,
|
||||
simple_select
|
||||
@ -246,7 +246,7 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <boolean> opt_instead, opt_cursor
|
||||
%type <boolean> index_opt_unique, opt_verbose, opt_full
|
||||
%type <boolean> opt_freeze
|
||||
%type <boolean> opt_freeze, opt_default
|
||||
%type <defelt> opt_binary, opt_oids, copy_delimiter
|
||||
|
||||
%type <boolean> copy_from
|
||||
@ -335,7 +335,7 @@ static void doNegateFloat(Value *v);
|
||||
CACHE, CALLED, CASCADE, CASE, CAST, CHAIN, CHAR_P,
|
||||
CHARACTER, CHARACTERISTICS, CHECK, CHECKPOINT, CLOSE,
|
||||
CLUSTER, COALESCE, COLLATE, COLUMN, COMMENT, COMMIT,
|
||||
COMMITTED, CONSTRAINT, CONSTRAINTS, COPY, CREATE, CREATEDB,
|
||||
COMMITTED, CONSTRAINT, CONSTRAINTS, CONVERSION_P, COPY, CREATE, CREATEDB,
|
||||
CREATEUSER, CROSS, CURRENT_DATE, CURRENT_TIME,
|
||||
CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, CYCLE,
|
||||
|
||||
@ -532,6 +532,7 @@ stmt :
|
||||
| VariableResetStmt
|
||||
| ConstraintsSetStmt
|
||||
| CheckPointStmt
|
||||
| CreateConversionStmt
|
||||
| /*EMPTY*/
|
||||
{ $$ = (Node *)NULL; }
|
||||
;
|
||||
@ -2299,6 +2300,7 @@ drop_type: TABLE { $$ = DROP_TABLE; }
|
||||
| INDEX { $$ = DROP_INDEX; }
|
||||
| TYPE_P { $$ = DROP_TYPE; }
|
||||
| DOMAIN_P { $$ = DROP_DOMAIN; }
|
||||
| CONVERSION_P { $$ = DROP_CONVERSION; }
|
||||
;
|
||||
|
||||
any_name_list:
|
||||
@ -3673,6 +3675,33 @@ opt_as: AS {}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Manipulate a conversion
|
||||
*
|
||||
* CREATE [DEFAULT] CONVERSION <conversion_name>
|
||||
* FOR <encoding_name> TO <encoding_name> FROM <func_name>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CreateConversionStmt:
|
||||
CREATE opt_default CONVERSION_P any_name FOR Sconst
|
||||
TO Sconst FROM any_name
|
||||
{
|
||||
CreateConversionStmt *n = makeNode(CreateConversionStmt);
|
||||
n->conversion_name = $4;
|
||||
n->for_encoding_name = $6;
|
||||
n->to_encoding_name = $8;
|
||||
n->func_name = $10;
|
||||
n->def = $2;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
opt_default: DEFAULT { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* QUERY:
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.118 2002/07/04 15:24:01 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.119 2002/07/11 07:39:26 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -78,6 +78,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"committed", COMMITTED},
|
||||
{"constraint", CONSTRAINT},
|
||||
{"constraints", CONSTRAINTS},
|
||||
{"conversion", CONVERSION_P},
|
||||
{"copy", COPY},
|
||||
{"create", CREATE},
|
||||
{"createdb", CREATEDB},
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.268 2002/06/20 20:29:36 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.269 2002/07/11 07:39:26 ishii Exp $
|
||||
*
|
||||
* NOTES
|
||||
* this is the "main" module of the postgres backend and
|
||||
@ -1688,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
puts("\nPOSTGRES backend interactive interface ");
|
||||
puts("$Revision: 1.268 $ $Date: 2002/06/20 20:29:36 $\n");
|
||||
puts("$Revision: 1.269 $ $Date: 2002/07/11 07:39:26 $\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2211,6 +2211,9 @@ CreateCommandTag(Node *parsetree)
|
||||
case DROP_DOMAIN:
|
||||
tag = "DROP DOMAIN";
|
||||
break;
|
||||
case DROP_CONVERSION:
|
||||
tag = "DROP CONVERSON";
|
||||
break;
|
||||
default:
|
||||
tag = "???";
|
||||
}
|
||||
@ -2426,6 +2429,10 @@ CreateCommandTag(Node *parsetree)
|
||||
tag = "REINDEX";
|
||||
break;
|
||||
|
||||
case T_CreateConversionStmt:
|
||||
tag = "CREATE CONVERSION";
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(LOG, "CreateCommandTag: unknown parse node type %d",
|
||||
nodeTag(parsetree));
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.160 2002/07/01 15:27:56 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.161 2002/07/11 07:39:26 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -24,6 +24,7 @@
|
||||
#include "commands/cluster.h"
|
||||
#include "commands/comment.h"
|
||||
#include "commands/copy.h"
|
||||
#include "commands/conversioncmds.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "commands/explain.h"
|
||||
@ -319,6 +320,11 @@ ProcessUtility(Node *parsetree,
|
||||
/* RemoveDomain does its own permissions checks */
|
||||
RemoveDomain(names, stmt->behavior);
|
||||
break;
|
||||
|
||||
case DROP_CONVERSION:
|
||||
/* RemoveDomain does its own permissions checks */
|
||||
DropConversionCommand(names);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -823,6 +829,12 @@ ProcessUtility(Node *parsetree,
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CreateConversionStmt:
|
||||
{
|
||||
CreateConversionCommand((CreateConversionStmt *) parsetree);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(ERROR, "ProcessUtility: command #%d unsupported",
|
||||
nodeTag(parsetree));
|
||||
|
13
src/backend/utils/cache/syscache.c
vendored
13
src/backend/utils/cache/syscache.c
vendored
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.80 2002/06/20 20:29:39 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.81 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
* NOTES
|
||||
* These routines allow the parser/planner/executor to perform
|
||||
@ -28,6 +28,7 @@
|
||||
#include "catalog/pg_aggregate.h"
|
||||
#include "catalog/pg_amop.h"
|
||||
#include "catalog/pg_amproc.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/pg_group.h"
|
||||
#include "catalog/pg_index.h"
|
||||
#include "catalog/pg_inherits.h"
|
||||
@ -193,6 +194,16 @@ static const struct cachedesc cacheinfo[] = {
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{ConversionRelationName, /* CONNAMENSP */
|
||||
ConversionNameNspIndex,
|
||||
0,
|
||||
2,
|
||||
{
|
||||
Anum_pg_conversion_conname,
|
||||
Anum_pg_conversion_connamespace,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{GroupRelationName, /* GRONAME */
|
||||
GroupNameIndex,
|
||||
0,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: catname.h,v 1.26 2002/06/20 20:29:43 momjian Exp $
|
||||
* $Id: catname.h,v 1.27 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -20,6 +20,7 @@
|
||||
#define AccessMethodOperatorRelationName "pg_amop"
|
||||
#define AccessMethodProcedureRelationName "pg_amproc"
|
||||
#define AttributeRelationName "pg_attribute"
|
||||
#define ConversionRelationName "pg_conversion"
|
||||
#define DatabaseRelationName "pg_database"
|
||||
#define DescriptionRelationName "pg_description"
|
||||
#define GroupRelationName "pg_group"
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: catversion.h,v 1.137 2002/07/02 05:46:14 momjian Exp $
|
||||
* $Id: catversion.h,v 1.138 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200207021
|
||||
#define CATALOG_VERSION_NO 200207111
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: indexing.h,v 1.67 2002/06/20 20:29:43 momjian Exp $
|
||||
* $Id: indexing.h,v 1.68 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -27,6 +27,7 @@
|
||||
#define Num_pg_attr_indices 2
|
||||
#define Num_pg_attrdef_indices 1
|
||||
#define Num_pg_class_indices 2
|
||||
#define Num_pg_conversion_indices 2
|
||||
#define Num_pg_database_indices 2
|
||||
#define Num_pg_description_indices 1
|
||||
#define Num_pg_group_indices 2
|
||||
@ -59,6 +60,8 @@
|
||||
#define AttributeRelidNumIndex "pg_attribute_relid_attnum_index"
|
||||
#define ClassNameNspIndex "pg_class_relname_nsp_index"
|
||||
#define ClassOidIndex "pg_class_oid_index"
|
||||
#define ConversionDefaultIndex "pg_conversion_default_index"
|
||||
#define ConversionNameNspIndex "pg_conversion_name_nsp_index"
|
||||
#define DatabaseNameIndex "pg_database_datname_index"
|
||||
#define DatabaseOidIndex "pg_database_oid_index"
|
||||
#define DescriptionObjIndex "pg_description_o_c_o_index"
|
||||
@ -99,6 +102,7 @@ extern char *Name_pg_amproc_indices[];
|
||||
extern char *Name_pg_attr_indices[];
|
||||
extern char *Name_pg_attrdef_indices[];
|
||||
extern char *Name_pg_class_indices[];
|
||||
extern char *Name_pg_conversion_indices[];
|
||||
extern char *Name_pg_database_indices[];
|
||||
extern char *Name_pg_description_indices[];
|
||||
extern char *Name_pg_group_indices[];
|
||||
@ -155,6 +159,9 @@ DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree
|
||||
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index on pg_class using btree(relname name_ops, relnamespace oid_ops));
|
||||
/* This following index is not used for a cache and is not unique */
|
||||
DECLARE_INDEX(pg_conversion_default_index on pg_conversion using btree(connamespace oid_ops, conforencoding int4_ops, contoencoding int4_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_conversion_name_nsp_index on pg_conversion using btree(conname name_ops, connamespace oid_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops));
|
||||
DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops));
|
||||
|
93
src/include/catalog/pg_conversion.h
Normal file
93
src/include/catalog/pg_conversion.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pg_conversion.h
|
||||
* definition of the system "conversion" relation (pg_conversion)
|
||||
* along with the relation's initial contents.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_conversion.h,v 1.1 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
* information from the DATA() statements.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PG_CONVERSION_H
|
||||
#define PG_CONVERSION_H
|
||||
|
||||
/* ----------------
|
||||
* postgres.h contains the system type definitions and the
|
||||
* CATALOG(), BOOTSTRAP and DATA() sugar words so this file
|
||||
* can be read by both genbki.sh and the C compiler.
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* pg_conversion definition.
|
||||
*
|
||||
* cpp turns this into typedef struct FormData_pg_namespace
|
||||
*
|
||||
* conname name of the conversion
|
||||
* connamespace name space which the conversion belongs to
|
||||
* conowner ower of the conversion
|
||||
* conforencoding FOR encoding id
|
||||
* contoencoding TO encoding id
|
||||
* conproc OID of the conversion proc
|
||||
* condefault TRUE is this is a default conversion
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
CATALOG(pg_conversion)
|
||||
{
|
||||
NameData conname;
|
||||
Oid connamespace;
|
||||
int4 conowner;
|
||||
int4 conforencoding;
|
||||
int4 contoencoding;
|
||||
regproc conproc;
|
||||
bool condefault;
|
||||
} FormData_pg_conversion;
|
||||
|
||||
/* ----------------
|
||||
* Form_pg_conversion corresponds to a pointer to a tuple with
|
||||
* the format of pg_conversion relation.
|
||||
* ----------------
|
||||
*/
|
||||
typedef FormData_pg_conversion *Form_pg_conversion;
|
||||
|
||||
/* ----------------
|
||||
* compiler constants for pg_conversion
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
#define Natts_pg_conversion 7
|
||||
#define Anum_pg_conversion_conname 1
|
||||
#define Anum_pg_conversion_connamespace 2
|
||||
#define Anum_pg_conversion_conowner 3
|
||||
#define Anum_pg_conversion_conforencoding 4
|
||||
#define Anum_pg_conversion_contoencoding 5
|
||||
#define Anum_pg_conversion_conproc 6
|
||||
#define Anum_pg_conversion_condefault 7
|
||||
|
||||
/* ----------------
|
||||
* initial contents of pg_conversion
|
||||
* ---------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* prototypes for functions in pg_conversion.c
|
||||
*/
|
||||
#include "nodes/pg_list.h"
|
||||
|
||||
extern Oid ConversionCreate(const char *conname, Oid connamespace,
|
||||
int32 conowner,
|
||||
int4 conforencoding, int4 contoencoding,
|
||||
Oid conproc, bool def);
|
||||
extern void ConversionDrop(const char *conname, Oid connamespace, int32 conowner);
|
||||
extern Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding);
|
||||
extern Oid FindConversionByName(List *conname);
|
||||
|
||||
#endif /* PG_CONVERSION_H */
|
23
src/include/commands/conversioncmds.h
Normal file
23
src/include/commands/conversioncmds.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* conversioncmds.h
|
||||
* prototypes for conversioncmds.c.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: conversioncmds.h,v 1.1 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef CONVERSIONCMDS_H
|
||||
#define CONVERSIONCMDS_H
|
||||
|
||||
#include "nodes/parsenodes.h"
|
||||
|
||||
extern void CreateConversionCommand(CreateConversionStmt *parsetree);
|
||||
extern void DropConversionCommand(List *conversion_name);
|
||||
|
||||
#endif /* CONVERSIONCMDS_H */
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: nodes.h,v 1.109 2002/06/20 20:29:51 momjian Exp $
|
||||
* $Id: nodes.h,v 1.110 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -198,6 +198,7 @@ typedef enum NodeTag
|
||||
T_CreateSchemaStmt,
|
||||
T_AlterDatabaseSetStmt,
|
||||
T_AlterUserSetStmt,
|
||||
T_CreateConversionStmt,
|
||||
|
||||
T_A_Expr = 700,
|
||||
T_ColumnRef,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.183 2002/07/01 15:27:56 tgl Exp $
|
||||
* $Id: parsenodes.h,v 1.184 2002/07/11 07:39:27 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1109,6 +1109,7 @@ typedef struct CreateDomainStmt
|
||||
#define DROP_INDEX 4
|
||||
#define DROP_TYPE 5
|
||||
#define DROP_DOMAIN 6
|
||||
#define DROP_CONVERSION 7
|
||||
|
||||
typedef struct DropStmt
|
||||
{
|
||||
@ -1505,4 +1506,18 @@ typedef struct ReindexStmt
|
||||
bool all;
|
||||
} ReindexStmt;
|
||||
|
||||
/* ----------------------
|
||||
* CREATE CONVERSION Statement
|
||||
* ----------------------
|
||||
*/
|
||||
typedef struct CreateConversionStmt
|
||||
{
|
||||
NodeTag type;
|
||||
List *conversion_name; /* Name of the conversion */
|
||||
char *for_encoding_name; /* source encoding name */
|
||||
char *to_encoding_name; /* destiname encoding name */
|
||||
List *func_name; /* qualified conversion function name */
|
||||
bool def; /* is this a default conversion? */
|
||||
} CreateConversionStmt;
|
||||
|
||||
#endif /* PARSENODES_H */
|
||||
|
@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: syscache.h,v 1.48 2002/06/20 20:29:53 momjian Exp $
|
||||
* $Id: syscache.h,v 1.49 2002/07/11 07:39:28 ishii Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -38,27 +38,27 @@
|
||||
#define ATTNUM 7
|
||||
#define CLAAMNAMENSP 8
|
||||
#define CLAOID 9
|
||||
#define GRONAME 10
|
||||
#define GROSYSID 11
|
||||
#define INDEXRELID 12
|
||||
#define INHRELID 13
|
||||
#define LANGNAME 14
|
||||
#define LANGOID 15
|
||||
#define NAMESPACENAME 16
|
||||
#define NAMESPACEOID 17
|
||||
#define OPERNAMENSP 18
|
||||
#define OPEROID 19
|
||||
#define PROCNAMENSP 20
|
||||
#define PROCOID 21
|
||||
#define RELNAMENSP 22
|
||||
#define RELOID 23
|
||||
#define RULERELNAME 24
|
||||
#define SHADOWNAME 25
|
||||
#define SHADOWSYSID 26
|
||||
#define STATRELATT 27
|
||||
#define TYPENAMENSP 28
|
||||
#define TYPEOID 29
|
||||
|
||||
#define CONNAMESP 10
|
||||
#define GRONAME 11
|
||||
#define GROSYSID 12
|
||||
#define INDEXRELID 13
|
||||
#define INHRELID 14
|
||||
#define LANGNAME 15
|
||||
#define LANGOID 16
|
||||
#define NAMESPACENAME 17
|
||||
#define NAMESPACEOID 18
|
||||
#define OPERNAMENSP 19
|
||||
#define OPEROID 20
|
||||
#define PROCNAMENSP 21
|
||||
#define PROCOID 22
|
||||
#define RELNAMENSP 23
|
||||
#define RELOID 24
|
||||
#define RULERELNAME 25
|
||||
#define SHADOWNAME 26
|
||||
#define SHADOWSYSID 27
|
||||
#define STATRELATT 28
|
||||
#define TYPENAMENSP 29
|
||||
#define TYPEOID 30
|
||||
|
||||
extern void InitCatalogCache(void);
|
||||
extern void InitCatalogCachePhase2(void);
|
||||
|
@ -38,6 +38,7 @@ SELECT relname, relhasindex
|
||||
pg_attrdef | t
|
||||
pg_attribute | t
|
||||
pg_class | t
|
||||
pg_conversion | t
|
||||
pg_database | t
|
||||
pg_description | t
|
||||
pg_group | t
|
||||
@ -60,5 +61,5 @@ SELECT relname, relhasindex
|
||||
shighway | t
|
||||
tenk1 | t
|
||||
tenk2 | t
|
||||
(50 rows)
|
||||
(51 rows)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user