@@ -36,7 +36,7 @@ static PlannedStmt *HOOK_Planner_injection(Query *parse, int cursorOptions,
36
36
ParamListInfo boundParams );
37
37
static void HOOK_ExecStart_injection (QueryDesc * queryDesc ,int eflags );
38
38
static void HOOK_ExecEnd_injection (QueryDesc * queryDesc );
39
- static char * serialize_plan (PlannedStmt * pstmt ,ParamListInfo boundParams ,
39
+ static char * serialize_plan (PlannedStmt * pstmt ,ParamListInfo boundParams ,
40
40
const char * querySourceText );
41
41
static void execute_query (char * planString );
42
42
@@ -91,12 +91,14 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
91
91
92
92
if ((OidIsValid (get_extension_oid ("execplan" , true)))&&
93
93
(node_number1 == 0 )&&
94
- (nodeTag (parsetree )== T_CreateStmt ))
94
+ (nodeTag (parsetree )!= T_CopyStmt )&&
95
+ (nodeTag (parsetree )!= T_CreateExtensionStmt )&&
96
+ (context != PROCESS_UTILITY_SUBCOMMAND ))
95
97
{
96
98
char conninfo [1024 ];
97
99
int status ;
98
100
99
- elog (LOG ,"Send UTILITY query: %s" ,queryString );
101
+ elog (LOG ,"Send UTILITY query %d : %s" , nodeTag ( parsetree ) ,queryString );
100
102
101
103
/* Connect to slave and send it a query plan */
102
104
sprintf (conninfo ,"host=localhost port=5433%c" ,'\0' );
@@ -108,6 +110,8 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
108
110
if (status == 0 )
109
111
elog (ERROR ,"Query sending error: %s" ,PQerrorMessage (conn ));
110
112
}
113
+ else if (node_number1 == 0 )
114
+ elog (LOG ,"UTILITY query without sending: %s" ,queryString );
111
115
112
116
if (next_ProcessUtility_hook )
113
117
(* next_ProcessUtility_hook ) (pstmt ,queryString ,context ,params ,
@@ -128,6 +132,9 @@ HOOK_Utility_injection(PlannedStmt *pstmt,
128
132
}
129
133
}
130
134
135
+ /*
136
+ * INPUT: a base64-encoded serialized plan
137
+ */
131
138
static void
132
139
execute_query (char * planString )
133
140
{
@@ -142,7 +149,7 @@ execute_query(char *planString)
142
149
elog (LOG ,"Connection error. conninfo: %s" ,conninfo );
143
150
144
151
SQLCommand = (char * )palloc0 (strlen (planString )+ 100 );
145
- sprintf (SQLCommand ,"SELECT pg_execute_plan('%s')" ,planString );
152
+ sprintf (SQLCommand ,"SELECT pg_execute_plan('%s'); " ,planString );
146
153
//elog(LOG, "query: %s", SQLCommand);
147
154
status = PQsendQuery (conn ,SQLCommand );
148
155
if (status == 0 )
@@ -182,9 +189,10 @@ HOOK_ExecStart_injection(QueryDesc *queryDesc, int eflags)
182
189
(node_number1 == 0 )&&
183
190
((parsetree == NULL )|| (nodeTag (parsetree )!= T_CreatedbStmt )))
184
191
{
192
+ char * exec_plan_query = serialize_plan (queryDesc -> plannedstmt ,queryDesc -> params ,
193
+ queryDesc -> sourceText );
185
194
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 );
188
196
}
189
197
else
190
198
{
@@ -217,7 +225,7 @@ HOOK_ExecEnd_injection(QueryDesc *queryDesc)
217
225
standard_ExecutorEnd (queryDesc );
218
226
}
219
227
220
- #include "utils/fmgrprotos .h"
228
+ #include "common/base64 .h"
221
229
222
230
static char *
223
231
serialize_plan (PlannedStmt * pstmt ,ParamListInfo boundParams ,
@@ -226,37 +234,36 @@ serialize_plan(PlannedStmt *pstmt, ParamListInfo boundParams,
226
234
int splan_len ,
227
235
sparams_len ,
228
236
qtext_len ,
237
+ tot_len ,
229
238
econtainer_len ;
230
239
char * serialized_plan ,
231
240
* container ,
232
- * start_address ,
233
- * econtainer ;
241
+ * econtainer ,
242
+ * start_address ;
234
243
235
244
serialized_plan = nodeToString (pstmt );
236
-
245
+ //elog(LOG, "serialized_plan: %s", serialized_plan);
237
246
/* We use len+1 bytes for include end-of-string symbol. */
238
247
splan_len = strlen (serialized_plan )+ 1 ;
239
248
qtext_len = strlen (querySourceText )+ 1 ;
240
249
241
250
sparams_len = EstimateParamListSpace (boundParams );
251
+ tot_len = splan_len + sparams_len + qtext_len ;
242
252
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 ;
248
255
256
+ memcpy (start_address ,serialized_plan ,splan_len );
257
+ start_address += splan_len ;
258
+ SerializeParamList (boundParams ,& start_address );
249
259
Assert (start_address == container + splan_len + sparams_len );
250
260
memcpy (start_address ,querySourceText ,qtext_len );
251
261
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 */
260
267
econtainer [econtainer_len ]= '\0' ;
261
268
262
269
return econtainer ;
@@ -309,21 +316,22 @@ Datum
309
316
pg_execute_plan (PG_FUNCTION_ARGS )
310
317
{
311
318
char * data = TextDatumGetCString (PG_GETARG_DATUM (0 ));
319
+ char * decdata ;
320
+ int decdata_len ;
312
321
PlannedStmt * pstmt ;
313
322
QueryDesc * queryDesc ;
314
323
char * queryString ;
315
324
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 ;
327
335
paramLI = RestoreParamList ((char * * )& start_addr );
328
336
queryString = start_addr ;
329
337
//elog(LOG, "Decoded query: %s\n", start_addr);