I wrote:
> I still think however that search-path-based lookup of default encoding
> conversions is a Bad Idea, and that we only ought to allow one default
> conversion to exist for any pair of encodings.

> I realized that we could implement that without too much trouble by
> redefining pg_conversion.condefault as being true for default conversions
> and NULL (not false) for non-default ones.  With this definition, a
> unique index on pg_conversion (conforencoding, contoencoding, condefault)
> would have the behavior we want --- sort of a poor man's partial unique
> index, except that it would work correctly on a system catalog whereas
> a true partial index wouldn't.

Turns out that indeed that works just fine.  See attached draft patch.

                        regards, tom lane

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 97ef618..dcb8b8e 100644
*** a/doc/src/sgml/catalogs.sgml
--- b/doc/src/sgml/catalogs.sgml
***************
*** 2538,2544 ****
        <entry><structfield>condefault</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>True if this is the default conversion</entry>
       </row>
  
      </tbody>
--- 2538,2545 ----
        <entry><structfield>condefault</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>True if this is the default conversion for these two encodings,
!        else NULL</entry>
       </row>
  
      </tbody>
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index f8c7ac3..eb39a9f 100644
*** a/doc/src/sgml/charset.sgml
--- b/doc/src/sgml/charset.sgml
*************** $ <userinput>psql -l</userinput>
*** 1102,1108 ****
       <literal>pg_conversion</> system catalog.  <productname>PostgreSQL</>
       comes with some predefined conversions, as shown in <xref
       linkend="multibyte-translation-table">. You can create a new
!      conversion using the SQL command <command>CREATE CONVERSION</command>.
      </para>
  
       <table id="multibyte-translation-table">
--- 1102,1108 ----
       <literal>pg_conversion</> system catalog.  <productname>PostgreSQL</>
       comes with some predefined conversions, as shown in <xref
       linkend="multibyte-translation-table">. You can create a new
!      conversion using the SQL command <xref linkend="sql-createconversion">.
      </para>
  
       <table id="multibyte-translation-table">
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index a0b42c2..f57d891 100644
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 1488,1494 ****
          original encoding is specified by
          <parameter>src_encoding</parameter>. The
          <parameter>string</parameter> must be valid in this encoding.
!         Conversions can be defined by <command>CREATE CONVERSION</command>.
          Also there are some predefined conversions. See <xref
          linkend="conversion-names"> for available conversions.
         </entry>
--- 1488,1494 ----
          original encoding is specified by
          <parameter>src_encoding</parameter>. The
          <parameter>string</parameter> must be valid in this encoding.
!         Conversions can be defined with <xref linkend="sql-createconversion">.
          Also there are some predefined conversions. See <xref
          linkend="conversion-names"> for available conversions.
         </entry>
***************
*** 1525,1534 ****
         </entry>
         <entry><type>bytea</type></entry>
         <entry>
!         Convert string to <parameter>dest_encoding</parameter>.
         </entry>
         <entry><literal>convert_to('some text', 'UTF8')</literal></entry>
!        <entry><literal>some text</literal> represented in the UTF8 encoding</entry>
        </row>
  
        <row>
--- 1525,1535 ----
         </entry>
         <entry><type>bytea</type></entry>
         <entry>
!         Convert string from the database encoding
!         to <parameter>dest_encoding</parameter>.
         </entry>
         <entry><literal>convert_to('some text', 'UTF8')</literal></entry>
!        <entry><literal>some text</literal> represented in UTF8 encoding</entry>
        </row>
  
        <row>
diff --git a/doc/src/sgml/ref/create_conversion.sgml b/doc/src/sgml/ref/create_conversion.sgml
index d2e2c01..1933107 100644
*** a/doc/src/sgml/ref/create_conversion.sgml
--- b/doc/src/sgml/ref/create_conversion.sgml
*************** CREATE [ DEFAULT ] CONVERSION <replaceab
*** 28,34 ****
  
    <para>
     <command>CREATE CONVERSION</command> defines a new conversion between
!    character set encodings.  Also, conversions that
     are marked <literal>DEFAULT</> can be used for automatic encoding
     conversion between
     client and server. For this purpose, two conversions, from encoding A to
--- 28,34 ----
  
    <para>
     <command>CREATE CONVERSION</command> defines a new conversion between
!    character set encodings.  Conversions that
     are marked <literal>DEFAULT</> can be used for automatic encoding
     conversion between
     client and server. For this purpose, two conversions, from encoding A to
*************** CREATE [ DEFAULT ] CONVERSION <replaceab
*** 53,59 ****
        <para>
         The <literal>DEFAULT</> clause indicates that this conversion
         is the default for this particular source to destination
!        encoding. There should be only one default encoding in a schema
         for the encoding pair.
        </para>
       </listitem>
--- 53,59 ----
        <para>
         The <literal>DEFAULT</> clause indicates that this conversion
         is the default for this particular source to destination
!        encoding. There can be only one default conversion in a database
         for the encoding pair.
        </para>
       </listitem>
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 8b105fe..98977f6 100644
*** a/src/backend/catalog/namespace.c
--- b/src/backend/catalog/namespace.c
***************
*** 28,34 ****
  #include "catalog/pg_authid.h"
  #include "catalog/pg_collation.h"
  #include "catalog/pg_conversion.h"
- #include "catalog/pg_conversion_fn.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_opclass.h"
  #include "catalog/pg_operator.h"
--- 28,33 ----
*************** get_conversion_oid(List *name, bool miss
*** 3416,3448 ****
  }
  
  /*
-  * FindDefaultConversionProc - find default encoding conversion proc
-  */
- Oid
- FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
- {
- 	Oid			proc;
- 	ListCell   *l;
- 
- 	recomputeNamespacePath();
- 
- 	foreach(l, activeSearchPath)
- 	{
- 		Oid			namespaceId = lfirst_oid(l);
- 
- 		if (namespaceId == myTempNamespace)
- 			continue;			/* do not look in temp namespace */
- 
- 		proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
- 		if (OidIsValid(proc))
- 			return proc;
- 	}
- 
- 	/* Not found in path */
- 	return InvalidOid;
- }
- 
- /*
   * recomputeNamespacePath - recompute path derived variables if needed.
   */
  static void
--- 3415,3420 ----
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index e2feb17..89b1ccf 100644
*** a/src/backend/catalog/pg_conversion.c
--- b/src/backend/catalog/pg_conversion.c
***************
*** 14,19 ****
--- 14,20 ----
   */
  #include "postgres.h"
  
+ #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/htup_details.h"
  #include "access/sysattr.h"
*************** ConversionCreate(const char *conname, Oi
*** 68,79 ****
  	if (def)
  	{
  		/*
! 		 * make sure there is no existing default <for encoding><to encoding>
! 		 * pair in this name space
  		 */
! 		if (FindDefaultConversion(connamespace,
! 								  conforencoding,
! 								  contoencoding))
  			ereport(ERROR,
  					(errcode(ERRCODE_DUPLICATE_OBJECT),
  					 errmsg("default conversion for %s to %s already exists",
--- 69,79 ----
  	if (def)
  	{
  		/*
! 		 * make sure there is no existing default conversion for same
! 		 * encodings
  		 */
! 		if (OidIsValid(FindDefaultConversionProc(conforencoding,
! 												 contoencoding)))
  			ereport(ERROR,
  					(errcode(ERRCODE_DUPLICATE_OBJECT),
  					 errmsg("default conversion for %s to %s already exists",
*************** ConversionCreate(const char *conname, Oi
*** 100,106 ****
  	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_form_tuple(tupDesc, values, nulls);
  
--- 100,109 ----
  	values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
  	values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
  	values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
! 	if (def)
! 		values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(true);
! 	else
! 		nulls[Anum_pg_conversion_condefault - 1] = true;
  
  	tup = heap_form_tuple(tupDesc, values, nulls);
  
*************** ConversionCreate(const char *conname, Oi
*** 145,159 ****
  /*
   * RemoveConversionById
   *
!  * Remove a tuple from pg_conversion by Oid. This function is solely
!  * called inside catalog/dependency.c
   */
  void
  RemoveConversionById(Oid conversionOid)
  {
  	Relation	rel;
  	HeapTuple	tuple;
! 	HeapScanDesc scan;
  	ScanKeyData scanKeyData;
  
  	ScanKeyInit(&scanKeyData,
--- 148,162 ----
  /*
   * RemoveConversionById
   *
!  * Remove a tuple from pg_conversion by Oid.
!  * This function is solely called inside catalog/dependency.c.
   */
  void
  RemoveConversionById(Oid conversionOid)
  {
  	Relation	rel;
  	HeapTuple	tuple;
! 	SysScanDesc scan;
  	ScanKeyData scanKeyData;
  
  	ScanKeyInit(&scanKeyData,
*************** RemoveConversionById(Oid conversionOid)
*** 161,213 ****
  				BTEqualStrategyNumber, F_OIDEQ,
  				ObjectIdGetDatum(conversionOid));
  
- 	/* open pg_conversion */
  	rel = heap_open(ConversionRelationId, RowExclusiveLock);
  
! 	scan = heap_beginscan_catalog(rel, 1, &scanKeyData);
  
! 	/* search for the target tuple */
! 	if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection)))
  		simple_heap_delete(rel, &tuple->t_self);
  	else
  		elog(ERROR, "could not find tuple for conversion %u", conversionOid);
! 	heap_endscan(scan);
  	heap_close(rel, RowExclusiveLock);
  }
  
  /*
!  * FindDefaultConversion
   *
!  * Find "default" conversion proc by for_encoding and to_encoding in the
!  * given namespace.
   *
   * If found, returns the procedure's oid, otherwise InvalidOid.  Note that
   * you get the procedure's OID not the conversion's OID!
   */
  Oid
! FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
  {
! 	CatCList   *catlist;
! 	HeapTuple	tuple;
! 	Form_pg_conversion body;
! 	Oid			proc = InvalidOid;
! 	int			i;
  
! 	catlist = SearchSysCacheList3(CONDEFAULT,
! 								  ObjectIdGetDatum(name_space),
! 								  Int32GetDatum(for_encoding),
! 								  Int32GetDatum(to_encoding));
  
! 	for (i = 0; i < catlist->n_members; i++)
  	{
! 		tuple = &catlist->members[i]->tuple;
! 		body = (Form_pg_conversion) GETSTRUCT(tuple);
! 		if (body->condefault)
! 		{
! 			proc = body->conproc;
! 			break;
! 		}
  	}
! 	ReleaseSysCacheList(catlist);
! 	return proc;
  }
--- 164,229 ----
  				BTEqualStrategyNumber, F_OIDEQ,
  				ObjectIdGetDatum(conversionOid));
  
  	rel = heap_open(ConversionRelationId, RowExclusiveLock);
  
! 	scan = systable_beginscan(rel, ConversionOidIndexId, true,
! 							  NULL, 1, &scanKeyData);
  
! 	if (HeapTupleIsValid(tuple = systable_getnext(scan)))
  		simple_heap_delete(rel, &tuple->t_self);
  	else
  		elog(ERROR, "could not find tuple for conversion %u", conversionOid);
! 
! 	systable_endscan(scan);
  	heap_close(rel, RowExclusiveLock);
  }
  
  /*
!  * FindDefaultConversionProc
   *
!  * Find "default" conversion proc converting from for_encoding to to_encoding.
   *
   * If found, returns the procedure's oid, otherwise InvalidOid.  Note that
   * you get the procedure's OID not the conversion's OID!
   */
  Oid
! FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
  {
! 	Oid			result = InvalidOid;
! 	Relation	conRel;
! 	ScanKeyData key[3];
! 	SysScanDesc conScan;
! 	HeapTuple	conTup;
  
! 	conRel = heap_open(ConversionRelationId, AccessShareLock);
  
! 	ScanKeyInit(&key[0],
! 				Anum_pg_conversion_conforencoding,
! 				BTEqualStrategyNumber, F_INT4EQ,
! 				Int32GetDatum(for_encoding));
! 	ScanKeyInit(&key[1],
! 				Anum_pg_conversion_contoencoding,
! 				BTEqualStrategyNumber, F_INT4EQ,
! 				Int32GetDatum(to_encoding));
! 	ScanKeyInit(&key[2],
! 				Anum_pg_conversion_condefault,
! 				BTEqualStrategyNumber, F_BOOLEQ,
! 				BoolGetDatum(true));
! 
! 	conScan = systable_beginscan(conRel, ConversionDefaultIndexId, true,
! 								 NULL, 3, key);
! 
! 	/* Assume there can be at most one match */
! 	if (HeapTupleIsValid(conTup = systable_getnext(conScan)))
  	{
! 		Form_pg_conversion conForm = (Form_pg_conversion) GETSTRUCT(conTup);
! 
! 		result = conForm->conproc;
  	}
! 
! 	systable_endscan(conScan);
! 
! 	relation_close(conRel, AccessShareLock);
! 
! 	return result;
  }
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 6eb2ac6..3d6f82b 100644
*** a/src/backend/utils/cache/syscache.c
--- b/src/backend/utils/cache/syscache.c
*************** static const struct cachedesc cacheinfo[
*** 303,319 ****
  		},
  		8
  	},
- 	{ConversionRelationId,		/* CONDEFAULT */
- 		ConversionDefaultIndexId,
- 		4,
- 		{
- 			Anum_pg_conversion_connamespace,
- 			Anum_pg_conversion_conforencoding,
- 			Anum_pg_conversion_contoencoding,
- 			ObjectIdAttributeNumber,
- 		},
- 		8
- 	},
  	{ConversionRelationId,		/* CONNAMENSP */
  		ConversionNameNspIndexId,
  		2,
--- 303,308 ----
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 7f1c881..b9a9686 100644
*** a/src/backend/utils/mb/mbutils.c
--- b/src/backend/utils/mb/mbutils.c
***************
*** 35,41 ****
  #include "postgres.h"
  
  #include "access/xact.h"
! #include "catalog/namespace.h"
  #include "mb/pg_wchar.h"
  #include "utils/builtins.h"
  #include "utils/memutils.h"
--- 35,41 ----
  #include "postgres.h"
  
  #include "access/xact.h"
! #include "catalog/pg_conversion_fn.h"
  #include "mb/pg_wchar.h"
  #include "utils/builtins.h"
  #include "utils/memutils.h"
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 56c0528..3421b12 100644
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
*************** dumpConversion(Archive *fout, DumpOption
*** 12178,12183 ****
--- 12178,12184 ----
  	conforencoding = PQgetvalue(res, 0, i_conforencoding);
  	contoencoding = PQgetvalue(res, 0, i_contoencoding);
  	conproc = PQgetvalue(res, 0, i_conproc);
+ 	/* condefault might be true, false, or null; this works regardless */
  	condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
  
  	/*
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index ab2c1a8..25a465b 100644
*** a/src/include/catalog/indexing.h
--- b/src/include/catalog/indexing.h
*************** DECLARE_INDEX(pg_constraint_contypid_ind
*** 123,129 ****
  DECLARE_UNIQUE_INDEX(pg_constraint_oid_index, 2667, on pg_constraint using btree(oid oid_ops));
  #define ConstraintOidIndexId  2667
  
! DECLARE_UNIQUE_INDEX(pg_conversion_default_index, 2668, on pg_conversion using btree(connamespace oid_ops, conforencoding int4_ops, contoencoding int4_ops, oid oid_ops));
  #define ConversionDefaultIndexId  2668
  DECLARE_UNIQUE_INDEX(pg_conversion_name_nsp_index, 2669, on pg_conversion using btree(conname name_ops, connamespace oid_ops));
  #define ConversionNameNspIndexId  2669
--- 123,130 ----
  DECLARE_UNIQUE_INDEX(pg_constraint_oid_index, 2667, on pg_constraint using btree(oid oid_ops));
  #define ConstraintOidIndexId  2667
  
! /* NB: this index will not enforce uniqueness for rows with null condefault */
! DECLARE_UNIQUE_INDEX(pg_conversion_default_index, 2668, on pg_conversion using btree(conforencoding int4_ops, contoencoding int4_ops, condefault bool_ops));
  #define ConversionDefaultIndexId  2668
  DECLARE_UNIQUE_INDEX(pg_conversion_name_nsp_index, 2669, on pg_conversion using btree(conname name_ops, connamespace oid_ops));
  #define ConversionNameNspIndexId  2669
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 2ccb3a7..35b0369 100644
*** a/src/include/catalog/namespace.h
--- b/src/include/catalog/namespace.h
*************** extern void PopOverrideSearchPath(void);
*** 135,141 ****
  
  extern Oid	get_collation_oid(List *collname, bool missing_ok);
  extern Oid	get_conversion_oid(List *conname, bool missing_ok);
- extern Oid	FindDefaultConversionProc(int32 for_encoding, int32 to_encoding);
  
  /* initialization & transaction cleanup code */
  extern void InitializeSearchPath(void);
--- 135,140 ----
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index 1cfe57c..7b8fff0 100644
*** a/src/include/catalog/pg_conversion.h
--- b/src/include/catalog/pg_conversion.h
***************
*** 32,38 ****
   *	conforencoding		FOR encoding id
   *	contoencoding		TO encoding id
   *	conproc				OID of the conversion proc
!  *	condefault			TRUE if this is a default conversion
   * ----------------------------------------------------------------
   */
  #define ConversionRelationId  2607
--- 32,41 ----
   *	conforencoding		FOR encoding id
   *	contoencoding		TO encoding id
   *	conproc				OID of the conversion proc
!  *	condefault			TRUE if this is a default conversion, else NULL
!  *
!  * (The odd definition of condefault allows us to make a poor man's
!  * partial unique index on conforencoding/contoencoding.)
   * ----------------------------------------------------------------
   */
  #define ConversionRelationId  2607
*************** CATALOG(pg_conversion,2607)
*** 45,51 ****
  	int32		conforencoding;
  	int32		contoencoding;
  	regproc		conproc;
! 	bool		condefault;
  } FormData_pg_conversion;
  
  /* ----------------
--- 48,57 ----
  	int32		conforencoding;
  	int32		contoencoding;
  	regproc		conproc;
! 
! #ifdef CATALOG_VARLEN			/* variable-length fields start here */
! 	bool condefault BKI_FORCE_NULL;
! #endif
  } FormData_pg_conversion;
  
  /* ----------------
diff --git a/src/include/catalog/pg_conversion_fn.h b/src/include/catalog/pg_conversion_fn.h
index 9fcdde6..fb4eef7 100644
*** a/src/include/catalog/pg_conversion_fn.h
--- b/src/include/catalog/pg_conversion_fn.h
*************** extern ObjectAddress ConversionCreate(co
*** 22,27 ****
  				 int32 conforencoding, int32 contoencoding,
  				 Oid conproc, bool def);
  extern void RemoveConversionById(Oid conversionOid);
! extern Oid	FindDefaultConversion(Oid connamespace, int32 for_encoding, int32 to_encoding);
  
  #endif   /* PG_CONVERSION_FN_H */
--- 22,27 ----
  				 int32 conforencoding, int32 contoencoding,
  				 Oid conproc, bool def);
  extern void RemoveConversionById(Oid conversionOid);
! extern Oid	FindDefaultConversionProc(int32 for_encoding, int32 to_encoding);
  
  #endif   /* PG_CONVERSION_FN_H */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 256615b..cd390b0 100644
*** a/src/include/utils/syscache.h
--- b/src/include/utils/syscache.h
*************** enum SysCacheIdentifier
*** 48,54 ****
  	CLAOID,
  	COLLNAMEENCNSP,
  	COLLOID,
- 	CONDEFAULT,
  	CONNAMENSP,
  	CONSTROID,
  	CONVOID,
--- 48,53 ----
diff --git a/src/test/regress/expected/conversion.out b/src/test/regress/expected/conversion.out
index 37965ae..7260ed2 100644
*** a/src/test/regress/expected/conversion.out
--- b/src/test/regress/expected/conversion.out
*************** CREATE CONVERSION myconv FOR 'LATIN1' TO
*** 10,23 ****
  CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  ERROR:  conversion "myconv" already exists
  --
! -- create default conversion with qualified name
  --
! CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  --
! -- cannot make default conversion with same schema/for_encoding/to_encoding
  --
! CREATE DEFAULT CONVERSION public.mydef2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
! ERROR:  default conversion for LATIN1 to UTF8 already exists
  -- test comments
  COMMENT ON CONVERSION myconv_bad IS 'foo';
  ERROR:  conversion "myconv_bad" does not exist
--- 10,29 ----
  CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  ERROR:  conversion "myconv" already exists
  --
! -- create a default conversion --- has to not match any built-in default,
! -- so we use a dummy function from regress.c
  --
! CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'BIG5' FROM iso8859_1_to_big5;
  --
! -- cannot make two default conversions for same encodings
  --
! CREATE DEFAULT CONVERSION mydef2 FOR 'LATIN1' TO 'BIG5' FROM iso8859_1_to_big5;
! ERROR:  default conversion for LATIN1 to BIG5 already exists
! --
! -- verify that we notice if wrong conversion function is specified
! --
! CREATE CONVERSION bogus FOR 'BIG5' TO 'UTF8' FROM iso8859_1_to_utf8;
! ERROR:  expected source encoding "LATIN1", but got "BIG5"
  -- test comments
  COMMENT ON CONVERSION myconv_bad IS 'foo';
  ERROR:  conversion "myconv_bad" does not exist
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 616e674..2618f69 100644
*** a/src/test/regress/expected/opr_sanity.out
--- b/src/test/regress/expected/opr_sanity.out
*************** WHERE p.oid = c.conproc AND
*** 853,859 ****
  -- there is no way to ask convert() to invoke them, and we cannot call
  -- them directly from SQL.  But there are no non-default built-in
  -- conversions anyway.
- -- (Similarly, this doesn't cope with any search path issues.)
  SELECT p1.oid, p1.conname
  FROM pg_conversion as p1
  WHERE condefault AND
--- 853,858 ----
diff --git a/src/test/regress/input/create_function_1.source b/src/test/regress/input/create_function_1.source
index f2b1561..6ed53a5 100644
*** a/src/test/regress/input/create_function_1.source
--- b/src/test/regress/input/create_function_1.source
*************** CREATE FUNCTION test_atomic_ops()
*** 62,67 ****
--- 62,72 ----
      AS '@libdir@/regress@DLSUFFIX@'
      LANGUAGE C;
  
+ CREATE FUNCTION iso8859_1_to_big5(int4, int4, cstring, internal, int4)
+     RETURNS void
+     AS '@libdir@/regress@DLSUFFIX@'
+     LANGUAGE C STRICT;
+ 
  -- Things that shouldn't work:
  
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
diff --git a/src/test/regress/output/create_function_1.source b/src/test/regress/output/create_function_1.source
index 30c2936..603499c 100644
*** a/src/test/regress/output/create_function_1.source
--- b/src/test/regress/output/create_function_1.source
*************** CREATE FUNCTION test_atomic_ops()
*** 55,60 ****
--- 55,64 ----
      RETURNS bool
      AS '@libdir@/regress@DLSUFFIX@'
      LANGUAGE C;
+ CREATE FUNCTION iso8859_1_to_big5(int4, int4, cstring, internal, int4)
+     RETURNS void
+     AS '@libdir@/regress@DLSUFFIX@'
+     LANGUAGE C STRICT;
  -- Things that shouldn't work:
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
      AS 'SELECT ''not an integer'';';
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index bb30629..294cdc4 100644
*** a/src/test/regress/regress.c
--- b/src/test/regress/regress.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "commands/trigger.h"
  #include "executor/executor.h"
  #include "executor/spi.h"
+ #include "mb/pg_wchar.h"
  #include "miscadmin.h"
  #include "port/atomics.h"
  #include "utils/builtins.h"
*************** test_atomic_ops(PG_FUNCTION_ARGS)
*** 1120,1122 ****
--- 1121,1153 ----
  
  	PG_RETURN_BOOL(true);
  }
+ 
+ 
+ PG_FUNCTION_INFO_V1(iso8859_1_to_big5);
+ Datum
+ iso8859_1_to_big5(PG_FUNCTION_ARGS)
+ {
+ 	unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
+ 	unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
+ 	int			len = PG_GETARG_INT32(4);
+ 	unsigned short c;
+ 
+ 	CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN1, PG_BIG5);
+ 
+ 	/*
+ 	 * Since this is a dummy implementation, just throw error for non-ASCII
+ 	 * characters.
+ 	 */
+ 	while (len > 0)
+ 	{
+ 		c = *src;
+ 		if (c == 0 || IS_HIGHBIT_SET(c))
+ 			report_invalid_encoding(PG_LATIN1, (const char *) src, len);
+ 		*dest++ = c;
+ 		src++;
+ 		len--;
+ 	}
+ 	*dest = '\0';
+ 
+ 	PG_RETURN_VOID();
+ }
diff --git a/src/test/regress/sql/conversion.sql b/src/test/regress/sql/conversion.sql
index e31876b..68fb6e2 100644
*** a/src/test/regress/sql/conversion.sql
--- b/src/test/regress/sql/conversion.sql
***************
*** 3,21 ****
  --
  CREATE USER conversion_test_user WITH NOCREATEDB NOCREATEROLE;
  SET SESSION AUTHORIZATION conversion_test_user;
  CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  --
  -- cannot make same name conversion in same schema
  --
  CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  --
! -- create default conversion with qualified name
  --
! CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  --
! -- cannot make default conversion with same schema/for_encoding/to_encoding
  --
! CREATE DEFAULT CONVERSION public.mydef2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  -- test comments
  COMMENT ON CONVERSION myconv_bad IS 'foo';
  COMMENT ON CONVERSION myconv IS 'bar';
--- 3,28 ----
  --
  CREATE USER conversion_test_user WITH NOCREATEDB NOCREATEROLE;
  SET SESSION AUTHORIZATION conversion_test_user;
+ 
  CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  --
  -- cannot make same name conversion in same schema
  --
  CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;
  --
! -- create a default conversion --- has to not match any built-in default,
! -- so we use a dummy function from regress.c
  --
! CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'BIG5' FROM iso8859_1_to_big5;
  --
! -- cannot make two default conversions for same encodings
  --
! CREATE DEFAULT CONVERSION mydef2 FOR 'LATIN1' TO 'BIG5' FROM iso8859_1_to_big5;
! --
! -- verify that we notice if wrong conversion function is specified
! --
! CREATE CONVERSION bogus FOR 'BIG5' TO 'UTF8' FROM iso8859_1_to_utf8;
! 
  -- test comments
  COMMENT ON CONVERSION myconv_bad IS 'foo';
  COMMENT ON CONVERSION myconv IS 'bar';
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index d6aa2e8..6216083 100644
*** a/src/test/regress/sql/opr_sanity.sql
--- b/src/test/regress/sql/opr_sanity.sql
*************** WHERE p.oid = c.conproc AND
*** 488,494 ****
  -- there is no way to ask convert() to invoke them, and we cannot call
  -- them directly from SQL.  But there are no non-default built-in
  -- conversions anyway.
- -- (Similarly, this doesn't cope with any search path issues.)
  
  SELECT p1.oid, p1.conname
  FROM pg_conversion as p1
--- 488,493 ----
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to