2525
2626#include <ctype.h>
2727
28+ #include "catalog/pg_type.h"
29+ #include "commands/dbcommands.h"
30+ #include "commands/defrem.h"
2831#include "commands/user.h"
2932#include "lib/stringinfo.h"
33+ #include "miscadmin.h"
3034#include "nodes/extensible.h"
3135#include "nodes/plannodes.h"
3236#include "nodes/relation.h"
3640#include "utils/syscache.h"
3741
3842#define NSP_NAME (nspoid ) (get_namespace_name(nspoid))
39- #define OID_TYPES_NUM (6)
40- static const Oid oid_types [OID_TYPES_NUM ] = {RELOID , TYPEOID , PROCOID , COLLOID ,
41- OPEROID , AUTHOID };
43+ #define OID_TYPES_NUM (12)
4244
45+ static const Oid oid_types [OID_TYPES_NUM ] = {RELOID , TYPEOID , PROCOID , COLLOID ,
46+ OPEROID , AUTHOID , LANGOID , AMOID ,
47+ NAMESPACEOID , DATABASEOID , RULEOID ,
48+ OPFAMILYOID };
49+ static void _printDatum (StringInfo str , Datum value , Oid typid );
4350static bool portable_output = false;
4451void
4552set_portable_output (bool value )
@@ -50,7 +57,9 @@ set_portable_output(bool value)
5057static void
5158write_oid_field (StringInfo str , Oid oid )
5259{
53- int i ;
60+ int i ;
61+ char * rulename ;
62+ Oid ev_class = InvalidOid ;
5463
5564 if (!portable_output )
5665 {
@@ -63,18 +72,23 @@ write_oid_field(StringInfo str, Oid oid)
6372 if (!OidIsValid (oid ))
6473 {
6574 /* Special case for invalid oid fields. For example, checkAsUser. */
66- appendStringInfo (str , "%u %u)" , 0 , oid );
75+ appendStringInfo (str , "0 %u)" , oid );
6776 return ;
6877 }
6978
7079 for (i = 0 ; i < OID_TYPES_NUM ; i ++ )
71- if (SearchSysCacheExists1 (oid_types [i ], oid ))
80+ if (oid_types [i ] != RULEOID )
81+ {
82+ if (SearchSysCacheExists1 (oid_types [i ], oid ))
83+ break ;
84+ }
85+ else if ((rulename = get_rule_name (oid , & ev_class )) != NULL )
7286 break ;
7387
7488 if (i == OID_TYPES_NUM )
7589 {
76- elog (INFO , "Unexpected oid type %d!" , oid );
77- appendStringInfo (str , "%u %u)" , 0 , oid );
90+ elog (LOG , "Unexpected oid type %d!" , oid );
91+ appendStringInfo (str , "0 %u)" , oid );
7892 return ;
7993 }
8094
@@ -147,6 +161,42 @@ write_oid_field(StringInfo str, Oid oid)
147161 appendStringInfo (str , "%u %s" , AUTHOID , get_rolename (oid ));
148162 break ;
149163
164+ case LANGOID :
165+ appendStringInfo (str , "%u %s" , LANGOID , get_language_name (oid , false));
166+ break ;
167+
168+ case AMOID :
169+ appendStringInfo (str , "%u %s" , AMOID , get_am_name (oid ));
170+ break ;
171+
172+ case NAMESPACEOID :
173+ appendStringInfo (str , "%u %s" , NAMESPACEOID , get_namespace_name_or_temp (oid ));
174+ break ;
175+
176+ case DATABASEOID :
177+ appendStringInfo (str , "%u %s" , DATABASEOID , get_database_name (oid ));
178+ break ;
179+
180+ case RULEOID :
181+ Assert (rulename != NULL );
182+ appendStringInfo (str , "%u %s %s %s" , RULEOID , rulename ,
183+ NSP_NAME (get_rel_namespace (ev_class )),
184+ get_rel_name (ev_class ));
185+ break ;
186+
187+ case OPFAMILYOID :
188+ {
189+ char * opfname = NULL ,
190+ * nspname = NULL ,
191+ * amname = NULL ;
192+
193+ opfname = get_opfamily_name (oid , & nspname , & amname );
194+ Assert (opfname && nspname && amname );
195+
196+ appendStringInfo (str , "%u %s %s %s" , OPFAMILYOID , opfname , nspname , amname );
197+ }
198+ break ;
199+
150200 default :
151201 Assert (0 );
152202 break ;
@@ -1125,6 +1175,8 @@ _outConst(StringInfo str, const Const *node)
11251175 appendStringInfoString (str , " :constvalue " );
11261176 if (node -> constisnull )
11271177 appendStringInfoString (str , "<>" );
1178+ else if (portable_output )
1179+ _printDatum (str , node -> constvalue , node -> consttype );
11281180 else
11291181 outDatum (str , node -> constvalue , node -> constlen , node -> constbyval );
11301182}
@@ -4125,3 +4177,50 @@ bmsToString(const Bitmapset *bms)
41254177 outBitmapset (& str , bms );
41264178 return str .data ;
41274179}
4180+
4181+ /*
4182+ * Output value in text format
4183+ */
4184+ static void
4185+ _printDatum (StringInfo str , Datum value , Oid typid )
4186+ {
4187+ Oid typOutput ;
4188+ bool typIsVarlena ;
4189+ FmgrInfo finfo ;
4190+ Datum tmpval ;
4191+ char * textvalue ;
4192+ int saveDateStyle ;
4193+
4194+ /* Get output function for the type */
4195+ getTypeOutputInfo (typid , & typOutput , & typIsVarlena );
4196+ fmgr_info (typOutput , & finfo );
4197+
4198+ /* Detoast value if needed */
4199+ if (typIsVarlena )
4200+ tmpval = PointerGetDatum (PG_DETOAST_DATUM (value ));
4201+ else
4202+ tmpval = value ;
4203+
4204+ /*
4205+ * It was found that if configuration setting for date style is
4206+ * "postgres,ymd" the output dates have format DD-MM-YYYY and they can not
4207+ * be parsed correctly by receiving party. So force ISO format YYYY-MM-DD
4208+ * in internal cluster communications, these values are always parsed
4209+ * correctly.
4210+ */
4211+ saveDateStyle = DateStyle ;
4212+ DateStyle = USE_ISO_DATES ;
4213+
4214+ if (typid == OIDOID )
4215+ {
4216+ /* Const type is "OID". Need to parse. */
4217+ Oid oid = DatumGetObjectId (value );
4218+ write_oid_field (str , oid );
4219+ }
4220+ else
4221+ {
4222+ textvalue = DatumGetCString (FunctionCall1 (& finfo , tmpval ));
4223+ outToken (str , textvalue );
4224+ }
4225+ DateStyle = saveDateStyle ;
4226+ }
0 commit comments