In CREATE CONVERSION, test that the given function is a valid conversion
authorHeikki Linnakangas <heikki@enterprisedb.com>
Fri, 27 Feb 2009 16:35:47 +0000 (16:35 +0000)
committerHeikki Linnakangas <heikki@enterprisedb.com>
Fri, 27 Feb 2009 16:35:47 +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 f5485e05fed50038b33aed5c78b88ed9235d3eec..62f3c31bc03561a061f789c3ccce41384924bf27 100644 (file)
@@ -46,7 +46,8 @@ CreateConversionCommand(CreateConversionStmt *stmt)
        const char *from_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, CSTRINGOID, CSTRINGOID, INT4OID};
+       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,
@@ -86,6 +87,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)