@@ -36,7 +36,7 @@ static PlannedStmt *HOOK_Planner_injection(Query *parse, int cursorOptions,
3636ParamListInfo boundParams );
3737static void HOOK_ExecStart_injection (QueryDesc * queryDesc ,int eflags );
3838static void HOOK_ExecEnd_injection (QueryDesc * queryDesc );
39- static char * serialize_plan (PlannedStmt * pstmt ,ParamListInfo boundParams ,
39+ static char * serialize_plan (PlannedStmt * pstmt ,ParamListInfo boundParams ,
4040const char * querySourceText );
4141static void execute_query (char * planString );
4242
@@ -91,12 +91,14 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
9191
9292if ((OidIsValid (get_extension_oid ("execplan" , true)))&&
9393(node_number1 == 0 )&&
94- (nodeTag (parsetree )== T_CreateStmt ))
94+ (nodeTag (parsetree )!= T_CopyStmt )&&
95+ (nodeTag (parsetree )!= T_CreateExtensionStmt )&&
96+ (context != PROCESS_UTILITY_SUBCOMMAND ))
9597{
9698char conninfo [1024 ];
9799int status ;
98100
99- elog (LOG ,"Send UTILITY query: %s" ,queryString );
101+ elog (LOG ,"Send UTILITY query %d : %s" , nodeTag ( parsetree ) ,queryString );
100102
101103/* Connect to slave and send it a query plan */
102104sprintf (conninfo ,"host=localhost port=5433%c" ,'\0' );
@@ -108,6 +110,8 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
108110if (status == 0 )
109111elog (ERROR ,"Query sending error: %s" ,PQerrorMessage (conn ));
110112}
113+ else if (node_number1 == 0 )
114+ elog (LOG ,"UTILITY query without sending: %s" ,queryString );
111115
112116if (next_ProcessUtility_hook )
113117(* next_ProcessUtility_hook ) (pstmt ,queryString ,context ,params ,
@@ -128,6 +132,9 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
128132}
129133}
130134
135+ /*
136+ * INPUT: a base64-encoded serialized plan
137+ */
131138static void
132139execute_query (char * planString )
133140{
@@ -142,7 +149,7 @@ execute_query(char *planString)
142149elog (LOG ,"Connection error. conninfo: %s" ,conninfo );
143150
144151SQLCommand = (char * )palloc0 (strlen (planString )+ 100 );
145- sprintf (SQLCommand ,"SELECT pg_execute_plan('%s')" ,planString );
152+ sprintf (SQLCommand ,"SELECT pg_execute_plan('%s'); " ,planString );
146153//elog(LOG, "query: %s", SQLCommand);
147154status = PQsendQuery (conn ,SQLCommand );
148155if (status == 0 )
@@ -182,9 +189,10 @@ HOOK_ExecStart_injection(QueryDesc *queryDesc, int eflags)
182189(node_number1 == 0 )&&
183190((parsetree == NULL )|| (nodeTag (parsetree )!= T_CreatedbStmt )))
184191{
192+ char * exec_plan_query = serialize_plan (queryDesc -> plannedstmt ,queryDesc -> params ,
193+ queryDesc -> sourceText );
185194elog (LOG ,"Send query: %s" ,queryDesc -> sourceText );
186- execute_query (serialize_plan (queryDesc -> plannedstmt ,queryDesc -> params ,
187- queryDesc -> sourceText ));
195+ execute_query (exec_plan_query );
188196}
189197else
190198{
@@ -217,7 +225,7 @@ HOOK_ExecEnd_injection(QueryDesc *queryDesc)
217225standard_ExecutorEnd (queryDesc );
218226}
219227
220- #include "utils/fmgrprotos .h"
228+ #include "common/base64 .h"
221229
222230static char *
223231serialize_plan (PlannedStmt * pstmt ,ParamListInfo boundParams ,
@@ -226,37 +234,36 @@ serialize_plan(PlannedStmt *pstmt, ParamListInfo boundParams,
226234int splan_len ,
227235sparams_len ,
228236qtext_len ,
237+ tot_len ,
229238econtainer_len ;
230239char * serialized_plan ,
231240* container ,
232- * start_address ,
233- * econtainer ;
241+ * econtainer ,
242+ * start_address ;
234243
235244serialized_plan = nodeToString (pstmt );
236-
245+ //elog(LOG, "serialized_plan: %s", serialized_plan);
237246/* We use len+1 bytes for include end-of-string symbol. */
238247splan_len = strlen (serialized_plan )+ 1 ;
239248qtext_len = strlen (querySourceText )+ 1 ;
240249
241250sparams_len = EstimateParamListSpace (boundParams );
251+ tot_len = splan_len + sparams_len + qtext_len ;
242252
243- container = (char * )palloc0 (splan_len + sparams_len + qtext_len );
244- //elog(LOG, "Serialize sizes: plan: %d params: %d, numParams: %d", splan_len, sparams_len, boundParams->numParams);
245- memcpy (container ,serialized_plan ,splan_len );
246- start_address = container + splan_len ;
247- SerializeParamList (boundParams ,& start_address );
253+ container = (char * )palloc0 (tot_len );
254+ start_address = container ;
248255
256+ memcpy (start_address ,serialized_plan ,splan_len );
257+ start_address += splan_len ;
258+ SerializeParamList (boundParams ,& start_address );
249259Assert (start_address == container + splan_len + sparams_len );
250260memcpy (start_address ,querySourceText ,qtext_len );
251261
252- econtainer_len = pg_base64_enc_len (container ,splan_len + sparams_len + qtext_len );
253- econtainer = (char * )palloc0 (econtainer_len + 1 );
254- if (econtainer_len != pg_base64_encode (container ,splan_len + sparams_len +
255- qtext_len ,econtainer ))
256- elog (LOG ,"econtainer_len: %d %d" ,econtainer_len ,pg_base64_encode (container ,splan_len + sparams_len +
257- qtext_len ,econtainer ));
258- Assert (econtainer_len == pg_base64_encode (container ,splan_len + sparams_len +
259- qtext_len ,econtainer ));
262+ econtainer_len = pg_b64_enc_len (tot_len );
263+ econtainer = (char * )palloc0 (econtainer_len + 1 );
264+ Assert (pg_b64_encode (container ,tot_len ,econtainer ) <=econtainer_len );
265+
266+ /* In accordance with example from fe-auth-scram.c */
260267econtainer [econtainer_len ]= '\0' ;
261268
262269return econtainer ;
@@ -309,21 +316,22 @@ Datum
309316pg_execute_plan (PG_FUNCTION_ARGS )
310317{
311318char * data = TextDatumGetCString (PG_GETARG_DATUM (0 ));
319+ char * decdata ;
320+ int decdata_len ;
312321PlannedStmt * pstmt ;
313322QueryDesc * queryDesc ;
314323char * queryString ;
315324ParamListInfo paramLI = NULL ;
316- int dec_tot_len ;
317- char * dcontainer ,
318- * start_addr ;
319-
320- /* Compute decoded size of bytea data */
321- dec_tot_len = pg_base64_dec_len (data ,strlen (data ));
322- dcontainer = (char * )palloc0 (dec_tot_len );
323- Assert (dec_tot_len == pg_base64_decode (data ,strlen (data ),dcontainer ));
324-
325- pstmt = (PlannedStmt * )stringToNode ((char * )dcontainer );
326- start_addr = dcontainer + strlen (dcontainer )+ 1 ;
325+ char * start_addr ;
326+
327+ Assert (data != NULL );
328+ decdata_len = pg_b64_dec_len (strlen (data ));
329+ decdata = (char * )palloc (decdata_len );
330+ //elog(LOG, "Decode query");
331+ Assert (pg_b64_decode (data ,strlen (data ),decdata ) <=decdata_len );
332+ //elog(LOG, "Decode query1");
333+ pstmt = (PlannedStmt * )stringToNode ((char * )decdata );
334+ start_addr = decdata + strlen (decdata )+ 1 ;
327335paramLI = RestoreParamList ((char * * )& start_addr );
328336queryString = start_addr ;
329337//elog(LOG, "Decoded query: %s\n", start_addr);