On Tue, Jun 22, 2021 at 01:13:08PM -0400, Tom Lane wrote:
> I wrote:
> > The attached seems to be enough to resolve Jim's example.  I'd like
> > to invent a test case that involves a detoast of the simple
> > expression's result, too, to show that transiently pushing a
> > snapshot for the duration of the expression is not the right fix.
> 
> Here we go.  This test case gives "cannot fetch toast data without an
> active snapshot" in v11 and v12 branch tips.  Since those branches lack
> the 73b06cf89 optimization, they push a snapshot while calling the
> SQL-language function, thus it doesn't complain.  But what comes back
> is toasted, and then we fail trying to detoast it.

This causes the server to crash during FETCH.

ts=# begin; declare b cursor for VALUES(1); fetch 100 in b;
BEGIN
DECLARE CURSOR
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

7c337b6b527b7052e6a751f966d5734c56f668b5 is the first bad commit
|       commit 7c337b6b527b7052e6a751f966d5734c56f668b5
|       Author: Tom Lane <t...@sss.pgh.pa.us>
|       Date:   Fri Jun 18 11:22:58 2021 -0400
|
|           Centralize the logic for protective copying of utility statements.

I noticed because it was tickled by pg_dump.

[109037.576659] postgres[32358]: segfault at 9a ip 00007f86a68fa7b1 sp 
00007fffd5ae2a88 error 4 in libc-2.17.so[7f86a678b000+1c4000]

< 2021-06-22 20:00:06.557 EDT  >LOG:  server process (PID 32358) was terminated 
by signal 11: Segmentation fault
< 2021-06-22 20:00:06.557 EDT  >DETAIL:  Failed process was running: FETCH 1000 
IN bloboid

Core was generated by `postgres: postgres ts [local] FETCH                      
    '.

(gdb) bt
#0  0x00007f86a68fa7b1 in __strlen_sse2_pminub () from /lib64/libc.so.6
#1  0x00000000008f7151 in string_hash (key=0x9a, keysize=64) at hashfn.c:667
#2  0x00000000008c1dd0 in hash_search (hashp=0x1534168, keyPtr=0x9a, 
action=action@entry=HASH_REMOVE, foundPtr=foundPtr@entry=0x0) at dynahash.c:959
#3  0x00000000008df29b in PortalDrop (portal=0x1532158, isTopCommit=<optimized 
out>) at portalmem.c:514
#4  0x00000000007959a7 in exec_simple_query (query_string=0x14bce88 "FETCH 1000 
IN bloboid") at postgres.c:1224
#5  0x0000000000796e2d in PostgresMain (argc=argc@entry=1, 
argv=argv@entry=0x7fffd5ae2ff0, dbname=0x14b9a78 "ts", username=<optimized 
out>) at postgres.c:4486
#6  0x00000000004890c1 in BackendRun (port=<optimized out>, port=<optimized 
out>) at postmaster.c:4507
#7  BackendStartup (port=0x14e4280) at postmaster.c:4229
#8  ServerLoop () at postmaster.c:1745
#9  0x0000000000718dcd in PostmasterMain (argc=argc@entry=3, 
argv=argv@entry=0x14b79e0) at postmaster.c:1417
#10 0x0000000000489f32 in main (argc=3, argv=0x14b79e0) at main.c:209

(gdb) p *portal
$1 = {name = 0x9a <Address 0x9a out of bounds>, prepStmtName = 0x0, 
portalContext = 0x15f5b00, resowner = 0x14f7d50, cleanup = 0x0, createSubid = 
1, activeSubid = 1,
  sourceText = 0x14bce88 "FETCH 1000 IN bloboid", commandTag = CMDTAG_FETCH, qc 
= {commandTag = CMDTAG_FETCH, nprocessed = 0}, stmts = 0x14bdc58, cplan = 0x0,
  portalParams = 0x0, queryEnv = 0x0, strategy = PORTAL_UTIL_SELECT, 
cursorOptions = 4, run_once = true, status = PORTAL_READY, portalPinned = 
false, autoHeld = false,
  queryDesc = 0x0, tupDesc = 0x15f5c18, formats = 0x15f5d28, portalSnapshot = 
0x0, holdStore = 0x165d688, holdContext = 0x165d570, holdSnapshot = 0x0, 
atStart = true,
  atEnd = true, portalPos = 0, creation_time = 677721606449684, visible = false}


Reply via email to