diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 3d1126bf01f172db1c7e6e6ced2def74e9babe49..0d021964b7a48a2dc3e8813e023e4914c4d1ee78 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -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) diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 4f8ee1d39799f353f013e19af1f0f018fd996b61..5611edda85343827176b48aa1353bce71607dbcd 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -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] = diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c new file mode 100644 index 0000000000000000000000000000000000000000..8cddcf064db9cb8610b0d7fc6fb7e4e5ef032ccd --- /dev/null +++ b/src/backend/catalog/pg_conversion.c @@ -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; +} + diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile index 190b0fd64f64d75290ce2767864f39c1e606f26f..58e8fe20e2d3c5386c381cb1ad48c430ed883acb 100644 --- a/src/backend/commands/Makefile +++ b/src/backend/commands/Makefile @@ -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 \ diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c new file mode 100644 index 0000000000000000000000000000000000000000..077fe9d8d874defe04b1d5d6350b5e25b9a775a2 --- /dev/null +++ b/src/backend/commands/conversioncmds.c @@ -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()); +} diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index e8e5aeabc77da8d4634eebe22a82d53c4dfeffb1..18b349c4ee2f211cc18ba29813ec7f12113fba28 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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: diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 92920ee4f7dfc3e6f638fcd88358643dc64ef9f6..907a26baee67ea9677fd5af63df27493605081dc 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -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}, diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index a8f83e48e4da376187848e21e1c8b1a1bf568f9d..c6b8fcfafd6c0394a39d21b1e141a92c25691c50 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -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)); diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index f5c38d071ed74db1e815955f86abd65e5b7e2b9f..e5e57d4a6de8ce8f6685ba12e242a283f0e9af22 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -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)); diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index e409ab7bc8ef3c280fae592346948637038a60dd..a724a0874eec35050497b54161ed2d5cb62cd7b1 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -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, diff --git a/src/include/catalog/catname.h b/src/include/catalog/catname.h index d679b06618c53694e79d3f71493bd03c32864dd2..6f755c9f9dc77302d845db3274cdaf10260abf1f 100644 --- a/src/include/catalog/catname.h +++ b/src/include/catalog/catname.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: 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" diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index d4d04d6db96d185432b6fdb75659093181a92af9..81f52bd9b34565ea2aaf031840ff6ba1ade38733 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -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 diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index bbc1b5ec995b21adf19bde4ee8049ddc3acd3d32..9413e5c8586dd27a7ed006e6bd575848c7b438fd 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -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)); diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h new file mode 100644 index 0000000000000000000000000000000000000000..d4c406b8ee110519de6134d59ff9bcf32784cfd0 --- /dev/null +++ b/src/include/catalog/pg_conversion.h @@ -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 */ diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h new file mode 100644 index 0000000000000000000000000000000000000000..fc4e5e6f51bb12d8e199e16a6bc4b986045fe6ee --- /dev/null +++ b/src/include/commands/conversioncmds.h @@ -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 */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 815a9ea861f392104327bfd3fb47ad6d4cd135c6..a2980a1ff20bf0a99300009c4867f191807a9ac0 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.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, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ce914c5cd0911edd94527e6d9bc8c033a0c0946b..19693d57b3affbd60f91e1c79d09cffd1108ea6b 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.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: 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 */ diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 0cd6b7ae5f3e22513b6b6056e0feb3a7ec25285a..f40471d7948754c01e645dce11330dbe905eb172 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.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); diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index 7958da8433179a96290bf9625820722a6c9efdac..37544dd0ccb1f1956d212145cd8c60506f12668a 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -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)