BUG #17702: An assert failed in parse_utilcmd.c

Started by PG Bug reporting formover 3 years ago5 messagesbugs
Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

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.

#2Daniel Gustafsson
daniel@yesql.se
In reply to: PG Bug reporting form (#1)
Re: BUG #17702: An assert failed in parse_utilcmd.c

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/

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Gustafsson (#2)
Re: BUG #17702: An assert failed in parse_utilcmd.c

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

#4Daniel Gustafsson
daniel@yesql.se
In reply to: Tom Lane (#3)
Re: BUG #17702: An assert failed in parse_utilcmd.c

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/

#5Daniel Gustafsson
daniel@yesql.se
In reply to: Daniel Gustafsson (#4)
Re: BUG #17702: An assert failed in parse_utilcmd.c

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/