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.
#
# 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 $
#
#-------------------------------------------------------------------------
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
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)
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{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] =
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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;
+}
+
# 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 $
#
#-------------------------------------------------------------------------
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 \
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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());
+}
*
*
* 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
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
%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
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,
| VariableResetStmt
| ConstraintsSetStmt
| CheckPointStmt
+ | CreateConversionStmt
| /*EMPTY*/
{ $$ = (Node *)NULL; }
;
| INDEX { $$ = DROP_INDEX; }
| TYPE_P { $$ = DROP_TYPE; }
| DOMAIN_P { $$ = DROP_DOMAIN; }
+ | CONVERSION_P { $$ = DROP_CONVERSION; }
;
any_name_list:
;
+/*****************************************************************************
+ *
+ * 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:
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{"committed", COMMITTED},
{"constraint", CONSTRAINT},
{"constraints", CONSTRAINTS},
+ {"conversion", CONVERSION_P},
{"copy", COPY},
{"create", CREATE},
{"createdb", CREATEDB},
*
*
* 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
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");
}
/*
case DROP_DOMAIN:
tag = "DROP DOMAIN";
break;
+ case DROP_CONVERSION:
+ tag = "DROP CONVERSON";
+ break;
default:
tag = "???";
}
tag = "REINDEX";
break;
+ case T_CreateConversionStmt:
+ tag = "CREATE CONVERSION";
+ break;
+
default:
elog(LOG, "CreateCommandTag: unknown parse node type %d",
nodeTag(parsetree));
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
/* RemoveDomain does its own permissions checks */
RemoveDomain(names, stmt->behavior);
break;
+
+ case DROP_CONVERSION:
+ /* RemoveDomain does its own permissions checks */
+ DropConversionCommand(names);
+ break;
}
/*
}
break;
+ case T_CreateConversionStmt:
+ {
+ CreateConversionCommand((CreateConversionStmt *) parsetree);
+ }
+ break;
+
default:
elog(ERROR, "ProcessUtility: command #%d unsupported",
nodeTag(parsetree));
*
*
* 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
#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"
0,
0
}},
+ {ConversionRelationName, /* CONNAMENSP */
+ ConversionNameNspIndex,
+ 0,
+ 2,
+ {
+ Anum_pg_conversion_conname,
+ Anum_pg_conversion_connamespace,
+ 0,
+ 0
+ }},
{GroupRelationName, /* GRONAME */
GroupNameIndex,
0,
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200207021
+#define CATALOG_VERSION_NO 200207111
#endif
* 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 $
*
*-------------------------------------------------------------------------
*/
#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
#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"
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[];
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));
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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 */
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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 */
* 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 $
*
*-------------------------------------------------------------------------
*/
T_CreateSchemaStmt,
T_AlterDatabaseSetStmt,
T_AlterUserSetStmt,
+ T_CreateConversionStmt,
T_A_Expr = 700,
T_ColumnRef,
* 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 $
*
*-------------------------------------------------------------------------
*/
#define DROP_INDEX 4
#define DROP_TYPE 5
#define DROP_DOMAIN 6
+#define DROP_CONVERSION 7
typedef struct DropStmt
{
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 */
* 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 $
*
*-------------------------------------------------------------------------
*/
#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);
pg_attrdef | t
pg_attribute | t
pg_class | t
+ pg_conversion | t
pg_database | t
pg_description | t
pg_group | t
shighway | t
tenk1 | t
tenk2 | t
-(50 rows)
+(51 rows)