Thread: BUG #17236: Postgres core on pstate->p_multiassign_exprs

BUG #17236: Postgres core on pstate->p_multiassign_exprs

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

Bug reference:      17236
Logged by:          ocean-dot-li
Email address:      ocean_li_996@163.com
PostgreSQL version: 14.0
Operating system:   centos linux
Description:

Postgres will crash when executing the following SQL:
CREATE TABLE v0 ( v1 INT , v2 INT ) ; 
UPDATE v0 SET ( v1 , v2 ) = ( SELECT v2 + 127 , v1 FROM v0 ) , v2 = ( v2 ,
v1 ) , v1 = 53 , v2 = 54 ;


ENVIRONMENT

Postgres cmmit hash:
commit 384f1abdb9b0f669279fcd57ba2173eb31724740

Postgres version:
$./bin/psql pgdb
psql (15devel)
Type "help" for help.

pgdb=# select version();
                                                  version
------------------------------------------------------------------------------------------------------------
 PostgreSQL 15devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5
20150623 (Red Hat 4.8.5-39), 64-bit
(1 row)

Install:
$git clone https://github.com/postgres/postgres
$cd postgres
$git pull
$./configure --enable-debug --enable-cassert --prefix=/home/postgres/pgsql
$make
$make install
$mkdir /home/postgres/pgsql/data
$chown -R postgres:postgres /home/postgres/pgsql/data
$/home/postgres/pgsql/bin/initdb -D /home/postgres/pgsql/data
$/home/postgres/pgsql/bin/pg_ctl -D /home/postgres/pgsql/data -l logfile
start
$/home/postgres/pgsql/bin/createdb pgdb 
$/home/postgres/pgsql/bin/psql pgdb


OUTPUT

Result:
$/home/postgres/pgsql/bin/psql pgdb
psql (15devel)
Type "help" for help.

pgdb=# \d
Did not find any relations.
pgdb=# CREATE TABLE v0 ( v1 INT , v2 INT ) ;
CREATE TABLE
pgdb=# SELECT * FROM v0;
 v1 | v2
----+----
(0 rows)

pgdb=# UPDATE v0 SET ( v1 , v2 ) = ( SELECT v2 + 127 , v1 FROM v0 ) , v2 = (
v2 , v1 ) , v1 = 53 , v2 = 54 ;
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.
!?>

Corefile:
$gdb /home/postgres/pgsql/bin/postgres
/home/postgres/pgsql/data/corefile-postgres-9995-1634527109
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/postgres/pgsql/bin/postgres...done.
[New LWP 9995]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `postgres: postgres pgdb [local] UPDATE     '.
Program terminated with signal 6, Aborted.
#0  0x00007f2e85bec277 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install
glibc-2.17-260.alios7.x86_64 libgcc-4.8.5-39.3.alios7.x86_64
(gdb) bt
#0  0x00007f2e85bec277 in raise () from /lib64/libc.so.6
#1  0x00007f2e85bed968 in abort () from /lib64/libc.so.6
#2  0x000000000093c85b in ExceptionalCondition
(conditionName=conditionName@entry=0xa4ee00 "pstate->p_multiassign_exprs ==
NIL",
    errorType=errorType@entry=0x994ad7 "FailedAssertion",
fileName=fileName@entry=0xa4ef41 "parse_target.c",
    lineNumber=lineNumber@entry=277) at assert.c:69
#3  0x00000000005d4fd9 in transformExpressionList
(pstate=pstate@entry=0x2a016f0, exprlist=0x2a01218, exprKind=<optimized
out>,
    allowDefault=allowDefault@entry=false) at parse_target.c:277
#4  0x00000000005c2c99 in transformRowExpr (pstate=pstate@entry=0x2a016f0,
allowDefault=allowDefault@entry=false, r=0x2a01348,
    r=0x2a01348) at parse_expr.c:2081
#5  0x00000000005c4210 in transformExprRecurse
(pstate=pstate@entry=0x2a016f0, expr=expr@entry=0x2a01348) at
parse_expr.c:232
#6  0x00000000005c3c38 in transformExpr (pstate=pstate@entry=0x2a016f0,
expr=expr@entry=0x2a01348,
    exprKind=exprKind@entry=EXPR_KIND_UPDATE_SOURCE) at parse_expr.c:104
#7  0x00000000005d2f72 in transformTargetEntry
(pstate=pstate@entry=0x2a016f0, node=0x2a01348, expr=expr@entry=0x0,
    exprKind=exprKind@entry=EXPR_KIND_UPDATE_SOURCE, colname=0x2a010c8 "v2",
resjunk=resjunk@entry=false) at parse_target.c:95
#8  0x00000000005d5037 in transformTargetList
(pstate=pstate@entry=0x2a016f0, targetlist=targetlist@entry=0x2a00958,
    exprKind=exprKind@entry=EXPR_KIND_UPDATE_SOURCE) at parse_target.c:183
#9  0x0000000000597d30 in transformUpdateTargetList
(pstate=pstate@entry=0x2a016f0, origTlist=0x2a00958) at analyze.c:2390
#10 0x0000000000599330 in transformUpdateStmt (stmt=0x2a01608,
pstate=0x2a016f0) at analyze.c:2365
#11 transformStmt (pstate=0x2a016f0, parseTree=0x2a01608) at analyze.c:313
#12 0x000000000059bba8 in transformTopLevelStmt (parseTree=0x2a01660,
pstate=0x2a016f0) at analyze.c:218
#13 parse_analyze (parseTree=0x2a01660,
    sourceText=0x29ffdd0 "UPDATE v0 SET ( v1 , v2 ) = ( SELECT v2 + 127 , v1
FROM v0 ) , v2 = ( v2 , v1 ) , v1 = 53 , v2 = 54 ;",
    paramTypes=0x0, numParams=0, queryEnv=0x0) at analyze.c:127
#14 0x000000000080c483 in pg_analyze_and_rewrite
(parsetree=parsetree@entry=0x2a01660,
    query_string=query_string@entry=0x29ffdd0 "UPDATE v0 SET ( v1 , v2 ) = (
SELECT v2 + 127 , v1 FROM v0 ) , v2 = ( v2 , v1 ) , v1 = 53 , v2 = 54 ;",
paramTypes=paramTypes@entry=0x0, numParams=numParams@entry=0,
queryEnv=queryEnv@entry=0x0) at postgres.c:657
#15 0x000000000080ca1f in exec_simple_query (
    query_string=0x29ffdd0 "UPDATE v0 SET ( v1 , v2 ) = ( SELECT v2 + 127 ,
v1 FROM v0 ) , v2 = ( v2 , v1 ) , v1 = 53 , v2 = 54 ;")
    at postgres.c:1130
#16 0x000000000080e862 in PostgresMain (dbname=<optimized out>,
username=<optimized out>) at postgres.c:4497
#17 0x000000000048a782 in BackendRun (port=<optimized out>, port=<optimized
out>) at postmaster.c:4560
#18 BackendStartup (port=0x2a22db0) at postmaster.c:4288
#19 ServerLoop () at postmaster.c:1801
#20 0x0000000000779c6f in PostmasterMain (argc=argc@entry=3,
argv=argv@entry=0x29fa960) at postmaster.c:1473
#21 0x000000000048be26 in main (argc=3, argv=0x29fa960) at main.c:198


Re: BUG #17236: Postgres core on pstate->p_multiassign_exprs

From
Tom Lane
Date:
PG Bug reporting form <noreply@postgresql.org> writes:
> Postgres will crash when executing the following SQL:
> CREATE TABLE v0 ( v1 INT , v2 INT ) ; 
> UPDATE v0 SET ( v1 , v2 ) = ( SELECT v2 + 127 , v1 FROM v0 ) , v2 = ( v2 ,
> v1 ) , v1 = 53 , v2 = 54 ;

Hmm, with assertions off I get

ERROR:  column "v2" is of type integer but expression is of type record
LINE 1: ...( v1 , v2 ) = ( SELECT v2 + 127 , v1 FROM v0 ) , v2 = ( v2 ,
                                                                 ^
HINT:  You will need to rewrite or cast the expression.

and if I remove that I get a complaint about multiple assignments
to the same column.

Were you expecting this query to do something useful, or was it
just fuzzing?

(Not that we shouldn't fix the assertion failure.  I'm just
wondering about the context.)

            regards, tom lane



Re: BUG #17236: Postgres core on pstate->p_multiassign_exprs

From
Tom Lane
Date:
PG Bug reporting form <noreply@postgresql.org> writes:
> Postgres will crash when executing the following SQL:
> CREATE TABLE v0 ( v1 INT , v2 INT ) ; 
> UPDATE v0 SET ( v1 , v2 ) = ( SELECT v2 + 127 , v1 FROM v0 ) , v2 = ( v2 ,
> v1 ) , v1 = 53 , v2 = 54 ;

After further reflection, this assertion is just wrong, and we
should remove it, as I've now done.  The lack of previous field
reports doubtless stems from the fact that most users don't
use assert-enabled builds, so there was no bug for them.

Thanks for the report!

            regards, tom lane