deparse: support CREATE CAST
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 10 Feb 2015 17:09:51 +0000 (14:09 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 7 Apr 2015 17:09:38 +0000 (14:09 -0300)
src/backend/tcop/deparse_utility.c

index 83dd59b29c715c73fc872023c3855a3e48d1125e..46d571a6739f1899b04aa254180543a0a4001506 100644 (file)
@@ -4441,6 +4441,81 @@ deparse_CreateConversion(Oid objectId, Node *parsetree)
    return ccStmt;
 }
 
+static ObjTree *
+deparse_CreateCastStmt(Oid objectId, Node *parsetree)
+{
+   CreateCastStmt *node = (CreateCastStmt *) parsetree;
+   Relation    castrel;
+   HeapTuple   castTup;
+   Form_pg_cast castForm;
+   ObjTree    *createCast;
+   char       *context;
+
+   castrel = heap_open(CastRelationId, AccessShareLock);
+   castTup = get_catalog_object_by_oid(castrel, objectId);
+   if (!HeapTupleIsValid(castTup))
+       elog(ERROR, "cache lookup failed for cast with OID %u", objectId);
+   castForm = (Form_pg_cast) GETSTRUCT(castTup);
+
+   createCast = new_objtree_VA("CREATE CAST (%{sourcetype}T AS %{targettype}T) %{mechanism}s %{context}s",
+                               2, "sourcetype", ObjTypeObject,
+                               new_objtree_for_type(castForm->castsource, -1),
+                               "targettype", ObjTypeObject,
+                               new_objtree_for_type(castForm->casttarget, -1));
+
+   if (node->inout)
+       append_string_object(createCast, "mechanism", "WITH INOUT");
+   else if (node->func == NULL)
+       append_string_object(createCast, "mechanism", "WITHOUT FUNCTION");
+   else
+   {
+       ObjTree    *tmp;
+       StringInfoData func;
+       HeapTuple   funcTup;
+       Form_pg_proc funcForm;
+       int         i;
+
+       funcTup = SearchSysCache1(PROCOID, castForm->castfunc);
+       funcForm = (Form_pg_proc) GETSTRUCT(funcTup);
+
+       initStringInfo(&func);
+       appendStringInfo(&func, "%s(",
+                       quote_qualified_identifier(get_namespace_name(funcForm->pronamespace),
+                                                  NameStr(funcForm->proname)));
+       for (i = 0; i < funcForm->pronargs; i++)
+           appendStringInfoString(&func,
+                                  format_type_be_qualified(funcForm->proargtypes.values[i]));
+       appendStringInfoChar(&func, ')');
+
+       tmp = new_objtree_VA("WITH FUNCTION %{castfunction}s", 1,
+                            "castfunction", ObjTypeString, func.data);
+       append_object_object(createCast, "mechanism", tmp);
+
+       ReleaseSysCache(funcTup);
+   }
+
+   switch (node->context)
+   {
+       case COERCION_IMPLICIT:
+           context = "AS IMPLICIT";
+           break;
+       case COERCION_ASSIGNMENT:
+           context = "AS ASSIGNMENT";
+           break;
+       case COERCION_EXPLICIT:
+           context = "";
+           break;
+       default:
+           elog(ERROR, "invalid coercion code %c", node->context);
+           return NULL;    /* keep compiler quiet */
+   }
+   append_string_object(createCast, "context", context);
+
+   heap_close(castrel, AccessShareLock);
+
+   return createCast;
+}
+
 static ObjTree *
 deparse_CreateOpFamily(Oid objectId, Node *parsetree)
 {
@@ -5204,7 +5279,7 @@ deparse_simple_command(StashedCommand *cmd)
            break;
 
        case T_CreateCastStmt:
-           elog(ERROR, "unimplemented deparse of %s", CreateCommandTag(parsetree));
+           command = deparse_CreateCastStmt(objectId, parsetree);
            break;
 
        case T_CreateOpClassStmt: