Thread: BUG #17702: An assert failed in parse_utilcmd.c

BUG #17702: An assert failed in parse_utilcmd.c

From
PG Bug reporting form
Date:
The following bug has been logged on the website:

Bug reference:      17702
Logged by:          xin wen
Email address:      xinwen@stu.scu.edu.cn
PostgreSQL version: 15.1
Operating system:   Ubuntu 20.04
Description:

When executing the following query:

CREATE FUNCTION function0 () RETURNS INT LANGUAGE SQL AS $$ CREATE TABLE
table1 ( column0 INT CHECK ( 'x' = 'x' )) ; SELECT 1 ; $$ ;
SELECT function0 () FROM ( VALUES ( 1 ) , ( 1 ) ) AS alias0;

I get a failed assertion with the following stacktrace:

Core was generated by `postgres: postgres test [local] SELECT
'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007faf78ccc859 in __GI_abort () at abort.c:79
#2  0x000055af27392a88 in ExceptionalCondition
(conditionName=conditionName@entry=0x55af274b0131 "stmt->constraints ==
NIL", errorType=errorType@entry=0x55af273f0498 "FailedAssertion",
fileName=fileName@entry=0x55af274ae8f8
"/home/postgres/postgresql-15.1/bld_debugging/../src/backend/parser/parse_utilcmd.c",
lineNumber=lineNumber@entry=307) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/utils/error/assert.c:69
#3  0x000055af27049dbd in transformCreateStmt
(stmt=stmt@entry=0x55af287f9608,
queryString=queryString@entry=0x55af287f89b0 " CREATE TABLE table1 ( column0
INT CHECK ( 'x' = 'x' )) ; SELECT 1 ; ") at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/parser/parse_utilcmd.c:307
#4  0x000055af2726cff7 in ProcessUtilitySlow (pstate=0x55af287aa490,
pstmt=0x55af287fa1d0, queryString=0x55af287f89b0 " CREATE TABLE table1 (
column0 INT CHECK ( 'x' = 'x' )) ; SELECT 1 ; ",
context=PROCESS_UTILITY_QUERY, params=0x0, queryEnv=0x0, qc=0x0,
dest=<optimized out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/tcop/utility.c:1147
#5  0x000055af2726c541 in standard_ProcessUtility (pstmt=0x55af287fa1d0,
queryString=0x55af287f89b0 " CREATE TABLE table1 ( column0 INT CHECK ( 'x' =
'x' )) ; SELECT 1 ; ", readOnlyTree=<optimized out>,
context=PROCESS_UTILITY_QUERY, params=0x0, queryEnv=0x0, dest=0x55af276a45a0
<donothingDR>, qc=0x0) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/tcop/utility.c:1074
#6  0x000055af270e7cac in postquel_getnext (es=0x55af287fa268,
es=0x55af287fa268, fcache=0x55af287f8870, fcache=0x55af287f8870) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/executor/functions.c:887
#7  fmgr_sql (fcinfo=0x55af287cc618) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/executor/functions.c:1203
#8  0x000055af270d2683 in ExecInterpExpr (state=0x55af287cc530,
econtext=0x55af287cc0d8, isnull=<optimized out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/executor/execExprInterp.c:1262
#9  0x000055af270e0c35 in ExecEvalExprSwitchContext (isNull=0x7ffce366c3f7,
econtext=0x55af287cc0d8, state=0x55af287cc530) at
/home/postgres/postgresql-15.1/bld_debugging/../src/include/executor/executor.h:341
#10 ExecProject (projInfo=0x55af287cc528) at
/home/postgres/postgresql-15.1/bld_debugging/../src/include/executor/executor.h:375
#11 ExecScan (node=<optimized out>, accessMtd=0x55af271125b0 <ValuesNext>,
recheckMtd=0x55af271125a0 <ValuesRecheck>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/executor/execScan.c:238
#12 0x000055af270d6c93 in ExecProcNode (node=0x55af287cbed0) at
/home/postgres/postgresql-15.1/bld_debugging/../src/include/executor/executor.h:259
#13 ExecutePlan (execute_once=<optimized out>, dest=0x55af287a5c50,
direction=<optimized out>, numberTuples=0, sendTuples=<optimized out>,
operation=CMD_SELECT, use_parallel_mode=<optimized out>,
planstate=0x55af287cbed0, estate=0x55af287cbc90) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/executor/execMain.c:1636
#14 standard_ExecutorRun (queryDesc=0x55af287c57c0, direction=<optimized
out>, count=0, execute_once=<optimized out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/executor/execMain.c:363
#15 0x000055af27269e5f in PortalRunSelect (portal=0x55af2874b560,
forward=<optimized out>, count=0, dest=<optimized out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/tcop/pquery.c:924
#16 0x000055af2726b431 in PortalRun (portal=portal@entry=0x55af2874b560,
count=count@entry=9223372036854775807, isTopLevel=isTopLevel@entry=true,
run_once=run_once@entry=true, dest=dest@entry=0x55af287a5c50,
altdest=altdest@entry=0x55af287a5c50, qc=0x7ffce366c6a0) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/tcop/pquery.c:768
#17 0x000055af27267202 in exec_simple_query (query_string=0x55af286de010
"SELECT function0 () FROM ( VALUES ( 1 ) , ( 1 ) ) AS alias0;") at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/tcop/postgres.c:1250
#18 0x000055af27268f8c in PostgresMain (dbname=<optimized out>,
username=<optimized out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/tcop/postgres.c:4581
#19 0x000055af271d5e8a in BackendRun (port=<optimized out>, port=<optimized
out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/postmaster/postmaster.c:4504
#20 BackendStartup (port=<optimized out>) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/postmaster/postmaster.c:4232
#21 ServerLoop () at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/postmaster/postmaster.c:1806
#22 0x000055af271d6ffb in PostmasterMain (argc=<optimized out>,
argv=0x55af286d8310) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/postmaster/postmaster.c:1478
#23 0x000055af26f01630 in main (argc=3, argv=0x55af286d8310) at
/home/postgres/postgresql-15.1/bld_debugging/../src/backend/main/main.c:202


I also find this assert failed in 14.6 using the same statement.


Re: BUG #17702: An assert failed in parse_utilcmd.c

From
Daniel Gustafsson
Date:
> On 29 Nov 2022, at 03:45, PG Bug reporting form <noreply@postgresql.org> wrote:

> When executing the following query:
>
> CREATE FUNCTION function0 () RETURNS INT LANGUAGE SQL AS $$ CREATE TABLE
> table1 ( column0 INT CHECK ( 'x' = 'x' )) ; SELECT 1 ; $$ ;
> SELECT function0 () FROM ( VALUES ( 1 ) , ( 1 ) ) AS alias0;
>
> I get a failed assertion with the following stacktrace:
>
> Core was generated by `postgres: postgres test [local] SELECT
> '.
> Program terminated with signal SIGABRT, Aborted.
> #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
> #1  0x00007faf78ccc859 in __GI_abort () at abort.c:79
> #2  0x000055af27392a88 in ExceptionalCondition
> (conditionName=conditionName@entry=0x55af274b0131 "stmt->constraints ==
> NIL", errorType=errorType@entry=0x55af273f0498 "FailedAssertion",
> fileName=fileName@entry=0x55af274ae8f8

This is AFAICT due to the utility statement already having gone through parse
analysis and thus have the constraints list already set here.  Forcing a read-
only protection via the functionality from 7c337b6b5 the assertion is avoided
and the function executes as expected:

diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index e134a82ff7..b0941151b2 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -884,7 +884,7 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
        {
                ProcessUtility(es->qd->plannedstmt,
                                           fcache->src,
-                                          false,
+                                          (nodeTag(es->qd->plannedstmt->utilityStmt) == T_CreateStmt ? true : false),
                                           PROCESS_UTILITY_QUERY,
                                           es->qd->params,
                                           es->qd->queryEnv,

Maintaining a list of statements that scribble and force those to readonly
could be a way forward?  Forcing processing of all utility statements to be
readonly seems like a blunt instrument here, not sure what the best course of
action would be.

--
Daniel Gustafsson        https://vmware.com/




Re: BUG #17702: An assert failed in parse_utilcmd.c

From
Tom Lane
Date:
Daniel Gustafsson <daniel@yesql.se> writes:
>> On 29 Nov 2022, at 03:45, PG Bug reporting form <noreply@postgresql.org> wrote:
>> When executing the following query:
>>
>> CREATE FUNCTION function0 () RETURNS INT LANGUAGE SQL AS $$ CREATE TABLE
>> table1 ( column0 INT CHECK ( 'x' = 'x' )) ; SELECT 1 ; $$ ;
>> SELECT function0 () FROM ( VALUES ( 1 ) , ( 1 ) ) AS alias0;
>>
>> I get a failed assertion with the following stacktrace:

> This is AFAICT due to the utility statement already having gone through parse
> analysis and thus have the constraints list already set here.  Forcing a read-
> only protection via the functionality from 7c337b6b5 the assertion is avoided
> and the function executes as expected:

Right.

> Maintaining a list of statements that scribble and force those to readonly
> could be a way forward?  Forcing processing of all utility statements to be
> readonly seems like a blunt instrument here, not sure what the best course of
> action would be.

No, I think that's exactly what we should do.  This is just a silly
oversight in 7c337b6b5 --- I should have thought about SQL functions
executing more than once in a query.

(Eventually we ought to nuke functions.c's private version of a plan
cache in favor of using plancache.c, but nobody's got to that yet.
It'd be more obvious then that we have to protect the cached copy.)

            regards, tom lane



Re: BUG #17702: An assert failed in parse_utilcmd.c

From
Daniel Gustafsson
Date:
> On 29 Nov 2022, at 17:22, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> Daniel Gustafsson <daniel@yesql.se> writes:
>>> On 29 Nov 2022, at 03:45, PG Bug reporting form <noreply@postgresql.org> wrote:
>>> When executing the following query:
>>>
>>> CREATE FUNCTION function0 () RETURNS INT LANGUAGE SQL AS $$ CREATE TABLE
>>> table1 ( column0 INT CHECK ( 'x' = 'x' )) ; SELECT 1 ; $$ ;
>>> SELECT function0 () FROM ( VALUES ( 1 ) , ( 1 ) ) AS alias0;
>>>
>>> I get a failed assertion with the following stacktrace:
>
>> This is AFAICT due to the utility statement already having gone through parse
>> analysis and thus have the constraints list already set here.  Forcing a read-
>> only protection via the functionality from 7c337b6b5 the assertion is avoided
>> and the function executes as expected:
>
> Right.

Thanks for confirming.

>> Maintaining a list of statements that scribble and force those to readonly
>> could be a way forward?  Forcing processing of all utility statements to be
>> readonly seems like a blunt instrument here, not sure what the best course of
>> action would be.
>
> No, I think that's exactly what we should do.  This is just a silly
> oversight in 7c337b6b5 --- I should have thought about SQL functions
> executing more than once in a query.

Oh, ok.  I'll go enforce readonly on all utility statements in HEAD and the
applicable backbranches tonight then.

--
Daniel Gustafsson        https://vmware.com/




Re: BUG #17702: An assert failed in parse_utilcmd.c

From
Daniel Gustafsson
Date:
> On 29 Nov 2022, at 17:47, Daniel Gustafsson <daniel@yesql.se> wrote:

> I'll go enforce readonly on all utility statements in HEAD and the
> applicable backbranches tonight then.

.. and just as I hit send I noticed that you had fixed it already =) Sorry for the noise.

--
Daniel Gustafsson        https://vmware.com/