Re: BUG #17983: Assert IsTransactionState() failed when empty string statement prepared in aborted transaction - Mailing list pgsql-bugs

From Japin Li
Subject Re: BUG #17983: Assert IsTransactionState() failed when empty string statement prepared in aborted transaction
Date
Msg-id MEYP282MB16691E0295CE3501C8EABD89B65CA@MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM
Whole thread Raw
In response to BUG #17983: Assert IsTransactionState() failed when empty string statement prepared in aborted transaction  (PG Bug reporting form <noreply@postgresql.org>)
Responses Re: BUG #17983: Assert IsTransactionState() failed when empty string statement prepared in aborted transaction  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
On Tue, 20 Jun 2023 at 03:00, PG Bug reporting form <noreply@postgresql.org> wrote:
> The following bug has been logged on the website:
>
> Bug reference:      17983
> Logged by:          Alexander Lakhin
> Email address:      exclusion@gmail.com
> PostgreSQL version: 16beta1
> Operating system:   Ubuntu 22.04
> Description:        
>
> The following psql script:
> BEGIN;
> ERROR;
> ;
> \gdesc
>
> triggers an assertion failure with the following stack trace:
> Core was generated by `postgres: law regression [local] PARSE               
>                         '.
> Program terminated with signal SIGABRT, Aborted.
>
> warning: Section `.reg-xstate/2900464' in core file too small.
> #0  __pthread_kill_implementation (no_tid=0, signo=6,
> threadid=140715061659456) at ./nptl/pthread_kill.c:44
> 44      ./nptl/pthread_kill.c: No such file or directory.
> (gdb) bt
> #0  __pthread_kill_implementation (no_tid=0, signo=6,
> threadid=140715061659456) at ./nptl/pthread_kill.c:44
> #1  __pthread_kill_internal (signo=6, threadid=140715061659456) at
> ./nptl/pthread_kill.c:78
> #2  __GI___pthread_kill (threadid=140715061659456, signo=signo@entry=6) at
> ./nptl/pthread_kill.c:89
> #3  0x00007ffac6a09476 in __GI_raise (sig=sig@entry=6) at
> ../sysdeps/posix/raise.c:26
> #4  0x00007ffac69ef7f3 in __GI_abort () at ./stdlib/abort.c:79
> #5  0x000055917976c830 in ExceptionalCondition (conditionName=0x5591799946f4
> "IsTransactionState()", 
>     fileName=0x55917999443e "catcache.c", lineNumber=1208) at assert.c:66
> #6  0x0000559179747288 in SearchCatCacheInternal (cache=0x55917acc5380,
> nkeys=1, v1=10, v2=0, v3=0, v4=0)
>     at catcache.c:1208
> #7  0x0000559179747159 in SearchCatCache1 (cache=0x55917acc5380, v1=10) at
> catcache.c:1162
> #8  0x0000559179764caf in SearchSysCache1 (cacheId=11, key1=10) at
> syscache.c:825
> #9  0x000055917912ed4d in recomputeNamespacePath () at namespace.c:3834
> #10 0x000055917912e180 in GetOverrideSearchPath (context=0x55917ad3a5a0) at
> namespace.c:3409
> #11 0x00005591797521e4 in CompleteCachedPlan (plansource=0x55917ac92ae8,
> querytree_list=0x0, 
>     querytree_context=0x55917ad3a5a0, param_types=0x0, num_params=0,
> parserSetup=0x0, parserSetupArg=0x0, 
>     cursor_options=2048, fixed_result=true) at plancache.c:408
> #12 0x000055917958392c in exec_parse_message (query_string=0x55917ac68679
> ";", stmt_name=0x55917ac68678 "", 
>     paramTypes=0x0, numParams=0) at postgres.c:1550
> #13 0x00005591795884b3 in PostgresMain (dbname=0x55917aca0af8 "regression",
> username=0x55917ac646e8 "law")
>     at postgres.c:4663
> #14 0x00005591794a94ff in BackendRun (port=0x55917ac91090) at
> postmaster.c:4461
> #15 0x00005591794a8d8b in BackendStartup (port=0x55917ac91090) at
> postmaster.c:4189
> #16 0x00005591794a50d0 in ServerLoop () at postmaster.c:1779
> #17 0x00005591794a497a in PostmasterMain (argc=3, argv=0x55917ac62620) at
> postmaster.c:1463
> #18 0x00005591793591f2 in main (argc=3, argv=0x55917ac62620) at main.c:198
>
> With "SELECT 1" instead of ";" I get:
> ERROR:  current transaction is aborted, commands ignored until end of
> transaction block
> as expected.
>
> postgres.c contains:
>     if (parsetree_list != NIL)
>     {
> ...
>         /*
>          * If we are in an aborted transaction, reject all commands except
>          * COMMIT/ROLLBACK.  It is important that this test occur before we
>          * try to do parse analysis, rewrite, or planning, since all those
>          * phases try to do database accesses, which may fail in abort state.
>          * (It might be safe to allow some additional utility commands in this
>          * state, but not many...)
>          */
>         if (IsAbortedTransactionBlockState() &&
>             !IsTransactionExitStmt(raw_parse_tree->stmt))
>             ereport(ERROR,
>                     (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
>                      errmsg("current transaction is aborted, "
>                             "commands ignored until end of transaction block"),
>                      errdetail_abort()));
> ...
>     }
>     else
>     {
>         /* Empty input string.  This is legal. */
>         raw_parse_tree = NULL;
>         psrc = CreateCachedPlan(raw_parse_tree, query_string,
>                                 CMDTAG_UNKNOWN);
>         querytree_list = NIL;
>     }
> ...
> so maybe an empty input string is not legal for creating a cached plan
> when the transaction is aborted?
>
> Reproduced on REL_11_STABLE .. HEAD.

Yeah, SearchSysCache1() need in an transaction block, here is a patch
fixed it.

Another question, why should we need to create a plan cache entry for
empty input?

-- 
Regrads,
Japin Li.


Attachment

pgsql-bugs by date:

Previous
From: Michael Paquier
Date:
Subject: Re: BUG #17973: Reinit of pgstats entry for dropped DB can break autovacuum daemon
Next
From: Amit Kapila
Date:
Subject: Re: BUG #17976: Inconsistent results of SELECT using CASE WHEN clause