In CREATE CONVERSION, test that the given function is a valid conversion
authorHeikki Linnakangas
Fri, 27 Feb 2009 16:35:26 +0000 (16:35 +0000)
committerHeikki Linnakangas
Fri, 27 Feb 2009 16:35:26 +0000 (16:35 +0000)
function for the specified source and destination encodings. We do that by
calling the function with an empty string. If it can't perform the requested
conversion, it will throw an error.

Backport to 7.4 - 8.3. Per bug report #4680 by Denis Afonin.

src/backend/commands/conversioncmds.c

index a02b98f73d7635fe78ca37f0007c690a459cb60f..13c55d51bff26e3afc04ba673c7aa2ca2822d2a2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.37 2009/01/01 17:23:37 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.38 2009/02/27 16:35:26 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,6 +49,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
    const char *to_encoding_name = stmt->to_encoding_name;
    List       *func_name = stmt->func_name;
    static Oid  funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID};
+   char        result[1];
 
    /* Convert list of names to a name and namespace */
    namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name,
@@ -95,6 +96,19 @@ CreateConversionCommand(CreateConversionStmt *stmt)
        aclcheck_error(aclresult, ACL_KIND_PROC,
                       NameListToString(func_name));
 
+   /*
+    * Check that the conversion function is suitable for the requested
+    * source and target encodings. We do that by calling the function with
+    * an empty string; the conversion function should throw an error if it
+    * can't perform the requested conversion.
+    */
+   OidFunctionCall5(funcoid,
+                    Int32GetDatum(from_encoding),
+                    Int32GetDatum(to_encoding),
+                    CStringGetDatum(""),
+                    CStringGetDatum(result),
+                    Int32GetDatum(0));
+
    /*
     * All seem ok, go ahead (possible failure would be a duplicate conversion
     * name)