Skip to content

Commit 43fa334

Browse files
committed
Test with Table Oid error
1 parent 0bafb66 commit 43fa334

File tree

3 files changed

+114
-34
lines changed

3 files changed

+114
-34
lines changed

exec_plan.c

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static PlannedStmt *HOOK_Planner_injection(Query *parse, int cursorOptions,
3636
ParamListInfo boundParams);
3737
static void HOOK_ExecStart_injection(QueryDesc *queryDesc, int eflags);
3838
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,
4040
const char *querySourceText);
4141
static 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+
*/
131138
static void
132139
execute_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

222230
static char *
223231
serialize_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
309316
pg_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);

scripts/pexec.sh

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/bin/bash
2+
3+
. ./paths.sh
4+
U=`whoami`
5+
6+
pkill -e postgres
7+
ulimit -c unlimited
8+
9+
rm master.log
10+
rm slave.log
11+
rm -rf PGDATA_Master
12+
mkdir PGDATA_Master
13+
rm -rf PGDATA_Slave
14+
mkdir PGDATA_Slave
15+
16+
initdb -D PGDATA_Master
17+
initdb -D PGDATA_Slave
18+
19+
echo "shared_preload_libraries = 'execplan'" >> PGDATA_Master/postgresql.conf
20+
echo "lc_messages='en_US.utf8'" >> PGDATA_Master/postgresql.conf
21+
echo "shared_preload_libraries = 'execplan'" >> PGDATA_Slave/postgresql.conf
22+
echo "lc_messages='en_US.utf8'" >> PGDATA_Slave/postgresql.conf
23+
echo "pargres.node = 1" >> PGDATA_Slave/postgresql.conf
24+
25+
pg_ctl -c -o "-p 5432" -D PGDATA_Master -l master.log start
26+
pg_ctl -c -o "-p 5433" -D PGDATA_Slave -l slave.log start
27+
28+
createdb -p 5432 $U
29+
createdb -p 5433 $U
30+
#exit
31+
psql -p 5432 -c "CREATE EXTENSION execplan;"
32+
psql -p 5433 -c "CREATE EXTENSION execplan;"
33+
psql -p 5432 -c "SELECT proname, oid FROM pg_proc WHERE proname LIKE 'pg_exec%';"
34+
psql -p 5432 -c "CREATE TABLE t1 (id Serial, b INT, PRIMARY KEY(id));"
35+
36+
#psql -p 5433 -c "CREATE TABLE t1 (id Serial, b INT, PRIMARY KEY(id));"
37+
38+
psql -p 5432 -f test.sql
39+
40+
psql -p 5432 -c "SELECT * FROM t1;"
41+
psql -p 5433 -c "SELECT * FROM t1;"
42+
43+
# pgbench test
44+
#pgbench -p 5433 -i -s 1
45+
# If we will plan query at master consistency will be guaranteed
46+
#psql -p 5433 -c "DELETE FROM pgbench_accounts;"
47+
#psql -p 5433 -c "DELETE FROM pgbench_branches;"
48+
#psql -p 5433 -c "DELETE FROM pgbench_tellers;"
49+
psql -p 5433 -c "CREATE TABLE t2 (id Serial, b INT, PRIMARY KEY(id));"
50+
pgbench -p 5432 -i -s 1
51+
52+
psql -c "select oid, relname from pg_class WHERE relname LIKE 'pgbench%';"
53+
psql -p 5433 -c "select oid, relname from pg_class WHERE relname LIKE 'pgbench%';"
54+
# Copy all tuples from pgbench_accounts
55+
#psql -p 5433 -c "INSERT INTO pgbench_accounts (SELECT * FROM pgbench_accounts) ON CONFLICT (aid) DO UPDATE SET abalance=pgbench_accounts.abalance;"
56+
psql -p 5432 -c "INSERT INTO pgbench_accounts (SELECT * FROM pgbench_accounts) ON CONFLICT (aid) DO NOTHING;"
57+
58+
#pgbench -t 1000 -j 4 -c 4
59+
60+
psql -p 5433 -c "SELECT count(*) FROM pgbench_accounts;"
61+
62+
#pg_ctl -D PGDATA_Master stop
63+
pg_ctl -D PGDATA_Slave stop
64+

scripts/test.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
INSERT INTO t1 (b) VALUES (3);
2+
INSERT INTO t1 (b) VALUES (15);
3+
INSERT INTO t1 (id, b) VALUES (3, 15);
4+
5+
-- Check params serialization
6+
PREPARE fooplan (numeric, numeric) AS INSERT INTO t1 VALUES($1, $2);
7+
EXECUTE fooplan(13, 200);
8+

0 commit comments

Comments
 (0)