@@ -36,7 +36,7 @@ static PlannedStmt *HOOK_Planner_injection(Query *parse, int cursorOptions,
3636 ParamListInfo 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 ,
4040 const char * querySourceText );
4141static void execute_query (char * planString );
4242
@@ -91,12 +91,14 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
9191
9292 if ((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 {
9698 char conninfo [1024 ];
9799 int 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 */
102104 sprintf (conninfo , "host=localhost port=5433%c" , '\0' );
@@ -108,6 +110,8 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
108110 if (status == 0 )
109111 elog (ERROR , "Query sending error: %s" , PQerrorMessage (conn ));
110112 }
113+ else if (node_number1 == 0 )
114+ elog (LOG , "UTILITY query without sending: %s" , queryString );
111115
112116 if (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)
142149 elog (LOG , "Connection error. conninfo: %s" , conninfo );
143150
144151 SQLCommand = (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);
147154 status = PQsendQuery (conn , SQLCommand );
148155 if (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 );
185194 elog (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 }
189197 else
190198 {
@@ -217,7 +225,7 @@ HOOK_ExecEnd_injection(QueryDesc *queryDesc)
217225 standard_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,
226234 int splan_len ,
227235 sparams_len ,
228236 qtext_len ,
237+ tot_len ,
229238 econtainer_len ;
230239 char * serialized_plan ,
231240 * container ,
232- * start_address ,
233- * econtainer ;
241+ * econtainer ,
242+ * start_address ;
234243
235244 serialized_plan = nodeToString (pstmt );
236-
245+ // elog(LOG, "serialized_plan: %s", serialized_plan);
237246 /* We use len+1 bytes for include end-of-string symbol. */
238247 splan_len = strlen (serialized_plan ) + 1 ;
239248 qtext_len = strlen (querySourceText ) + 1 ;
240249
241250 sparams_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 );
249259 Assert (start_address == container + splan_len + sparams_len );
250260 memcpy (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 */
260267 econtainer [econtainer_len ] = '\0' ;
261268
262269 return econtainer ;
@@ -309,21 +316,22 @@ Datum
309316pg_execute_plan (PG_FUNCTION_ARGS )
310317{
311318 char * data = TextDatumGetCString (PG_GETARG_DATUM (0 ));
319+ char * decdata ;
320+ int decdata_len ;
312321 PlannedStmt * pstmt ;
313322 QueryDesc * queryDesc ;
314323 char * queryString ;
315324 ParamListInfo 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 ;
327335 paramLI = RestoreParamList ((char * * ) & start_addr );
328336 queryString = start_addr ;
329337// elog(LOG, "Decoded query: %s\n", start_addr);
0 commit comments