From: | "houzj(dot)fnst(at)fujitsu(dot)com" <houzj(dot)fnst(at)fujitsu(dot)com> |
---|---|
To: | Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>, "tsunakawa(dot)takay(at)fujitsu(dot)com" <tsunakawa(dot)takay(at)fujitsu(dot)com> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | RE: batch fdw insert bug (Postgres 14) |
Date: | 2021-05-07 12:46:44 |
Message-ID: | OS0PR01MB5716743FF4AD2851AAB9D41A94579@OS0PR01MB5716.jpnprd01.prod.outlook.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
> I am testing new features in Postgres 14, and I found bug
> EXPLAIN ANALYZE VERBOSE for insert to FDW table with batch_size 1000 returns
> -------------------------------------------------------------------------------------------------------------------------------
> Insert on public.vzdalena_tabulka2 (cost=0.00..175.00 rows=0 width=0) (actual time=30.269..30.270 rows=0 loops=1)
> Remote SQL: \x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F
> Batch Size: 1000
> -> Function Scan on pg_catalog.generate_series g (cost=0.00..175.00 rows=10000 width=36) (actual time=0.453..1.988 rows=10
> Output: g.i, ('AHOJ'::text || (g.i)::text)
> Function Call: generate_series(1, 10000)
> Planning Time: 0.075 ms
> Execution Time: 31.032 ms
> (8 rows)
> reproducer
I can reproduce the issue and did some basic analysis on it.
The "Remote SQL" is built from the following code:
----------------
char *sql = strVal(list_nth(fdw_private,
FdwModifyPrivateUpdateSql));
ExplainPropertyText("Remote SQL", sql, es);
---------------
It use the query string stored in list fdw_private.
However, the "fmstate->query" will also point to the string in fdw_private,
by postgresBeginForeignModify --> create_foreign_modify --> "fmstate->query = query;"
And in execute_foreign_modify(), " fmstate->query " will be freed when rebuild the query
string to do the batch insert like the following:
----------------
if (operation == CMD_INSERT && fmstate->num_slots != *numSlots)
{
...
/* Build INSERT string with numSlots records in its VALUES clause. */
initStringInfo(&sql);
rebuildInsertSql(&sql, fmstate->orig_query, fmstate->values_end,
fmstate->p_nums, *numSlots - 1)
** pfree(fmstate->query);
fmstate->query = sql.data;
----------------
So, it output the freed pointer as "Remote SQL".
For the fix.
The query string could be rebuilt depending on the numSlots,
which query string should be output ?
should we just output the original query string like the attached patch ?
Or should we output the last one?
Best regards,
houzj
Attachment | Content-Type | Size |
---|---|---|
0001-fix-explain-info-about-fdw-batch-insert.patch | application/octet-stream | 947 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Jeevan Ladhe | 2021-05-07 12:53:06 | Re: Query regarding RANGE Partitioning |
Previous Message | Dilip Kumar | 2021-05-07 12:35:57 | Re: Logical Replication - behavior of TRUNCATE ... CASCADE |