BUG #17800: ON CONFLICT DO UPDATE fails to detect incompatible fields that leads to a server crash - Mailing list pgsql-bugs
From | PG Bug reporting form |
---|---|
Subject | BUG #17800: ON CONFLICT DO UPDATE fails to detect incompatible fields that leads to a server crash |
Date | |
Msg-id | 17800-ff90866b3906c964@postgresql.org Whole thread Raw |
Responses |
Re: BUG #17800: ON CONFLICT DO UPDATE fails to detect incompatible fields that leads to a server crash
|
List | pgsql-bugs |
The following bug has been logged on the website: Bug reference: 17800 Logged by: Alexander Lakhin Email address: exclusion@gmail.com PostgreSQL version: 15.2 Operating system: Ubuntu 22.04 Description: When executing the following queries: CREATE TABLE t (a INT PRIMARY KEY, b TEXT) PARTITION BY LIST (a); CREATE TABLE tp1 (b TEXT, a INT PRIMARY KEY); ALTER TABLE t ATTACH PARTITION tp1 FOR VALUES IN (1); CREATE TABLE tp2 (a INT PRIMARY KEY, b TEXT); ALTER TABLE t ATTACH PARTITION tp2 FOR VALUES IN (2); INSERT INTO t VALUES (1), (2); INSERT INTO t VALUES (1), (2) ON CONFLICT(a) DO UPDATE SET (a, b) = (SELECT t.a, t.b || '+'); I get the server crashed with the coredump: Core was generated by `postgres: law regression [local] INSERT '. Program terminated with signal SIGSEGV, Segmentation fault. warning: Section `.reg-xstate/1121242' in core file too small. #0 0x000056173f49d91d in pg_detoast_datum_packed (datum=0x2) at fmgr.c:1853 1853 if (VARATT_IS_COMPRESSED(datum) || VARATT_IS_EXTERNAL(datum)) (gdb) bt #0 0x000056173f49d91d in pg_detoast_datum_packed (datum=0x2) at fmgr.c:1853 #1 0x000056173f44bb3c in textcat (fcinfo=0x561740c0a4d8) at varlena.c:750 #2 0x000056173efebd6e in ExecInterpExpr (state=0x561740c09ff0, econtext=0x561740c09d18, isnull=0x7ffc5f595d2f) at execExprInterp.c:752 #3 0x000056173f04a86a in ExecEvalExprSwitchContext (state=0x561740c09ff0, econtext=0x561740c09d18, isNull=0x7ffc5f595d2f) at ../../../src/include/executor/executor.h:344 #4 0x000056173f04a8e2 in ExecProject (projInfo=0x561740c09fe8) at ../../../src/include/executor/executor.h:378 #5 0x000056173f04ab19 in ExecResult (pstate=0x561740c09c08) at nodeResult.c:136 #6 0x000056173f04e40d in ExecProcNode (node=0x561740c09c08) at ../../../src/include/executor/executor.h:262 #7 0x000056173f0508fe in ExecSetParamPlan (node=0x561740c112c0, econtext=0x561740c0f8c8) at nodeSubplan.c:1133 #8 0x000056173efef225 in ExecEvalParamExec (state=0x561740c0fa80, op=0x561740c0fb48, econtext=0x561740c0f8c8) at execExprInterp.c:2428 #9 0x000056173efec5e8 in ExecInterpExpr (state=0x561740c0fa80, econtext=0x561740c0f8c8, isnull=0x7ffc5f5961cf) at execExprInterp.c:1065 #10 0x000056173efee179 in ExecInterpExprStillValid (state=0x561740c0fa80, econtext=0x561740c0f8c8, isNull=0x7ffc5f5961cf) at execExprInterp.c:1838 #11 0x000056173f040b4a in ExecEvalExprSwitchContext (state=0x561740c0fa80, econtext=0x561740c0f8c8, isNull=0x7ffc5f5961cf) at ../../../src/include/executor/executor.h:344 #12 0x000056173f040bc2 in ExecProject (projInfo=0x561740c0fa78) at ../../../src/include/executor/executor.h:378 #13 0x000056173f044def in ExecOnConflictUpdate (context=0x7ffc5f596420, resultRelInfo=0x561740c2c418, conflictTid=0x7ffc5f5962e2, excludedSlot=0x561740c0b138, canSetTag=true, returning=0x7ffc5f5962e8) at nodeModifyTable.c:2659 #14 0x000056173f0426d8 in ExecInsert (context=0x7ffc5f596420, resultRelInfo=0x561740c2c418, slot=0x561740c0b138, canSetTag=true, inserted_tuple=0x0, insert_destrel=0x0) at nodeModifyTable.c:1059 #15 0x000056173f046dc6 in ExecModifyTable (pstate=0x561740c0a578) at nodeModifyTable.c:3810 #16 0x000056173f004dd3 in ExecProcNodeFirst (node=0x561740c0a578) at execProcnode.c:464 #17 0x000056173eff7ff6 in ExecProcNode (node=0x561740c0a578) at ../../../src/include/executor/executor.h:262 #18 0x000056173effae2b in ExecutePlan (estate=0x561740c09938, planstate=0x561740c0a578, use_parallel_mode=false, operation=CMD_INSERT, sendTuples=false, numberTuples=0, direction=ForwardScanDirection, dest=0x561740c0f310, execute_once=true) at execMain.c:1633 #19 0x000056173eff86de in standard_ExecutorRun (queryDesc=0x561740c12c78, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:364 #20 0x000056173eff84e7 in ExecutorRun (queryDesc=0x561740c12c78, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:308 #21 0x000056173f2aa948 in ProcessQuery (plan=0x561740c20158, sourceText=0x561740b1a178 "INSERT INTO t VALUES (1), (2) ON CONFLICT(a)\n DO UPDATE SET (a, b) = (SELECT t.a, t.b || '+');", params=0x0, queryEnv=0x0, dest=0x561740c0f310, qc=0x7ffc5f596880) at pquery.c:160 #22 0x000056173f2ac4ec in PortalRunMulti (portal=0x561740b926c8, isTopLevel=true, setHoldSnapshot=false, dest=0x561740c0f310, altdest=0x561740c0f310, qc=0x7ffc5f596880) at pquery.c:1277 #23 0x000056173f2ab9e0 in PortalRun (portal=0x561740b926c8, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x561740c0f310, altdest=0x561740c0f310, qc=0x7ffc5f596880) at pquery.c:791 #24 0x000056173f2a4743 in exec_simple_query ( query_string=0x561740b1a178 "INSERT INTO t VALUES (1), (2) ON CONFLICT(a)\n DO UPDATE SET (a, b) = (SELECT t.a, t.b || '+');") at postgres.c:1237 #25 0x000056173f2a9754 in PostgresMain (dbname=0x561740b52578 "regression", username=0x561740b17708 "law") at postgres.c:4565 #26 0x000056173f1cd4bb in BackendRun (port=0x561740b42b10) at postmaster.c:4461 #27 0x000056173f1ccd47 in BackendStartup (port=0x561740b42b10) at postmaster.c:4189 #28 0x000056173f1c908c in ServerLoop () at postmaster.c:1779 #29 0x000056173f1c8936 in PostmasterMain (argc=3, argv=0x561740b15640) at postmaster.c:1463 #30 0x000056173f082cfa in main (argc=3, argv=0x561740b15640) at main.c:200 But when executing: UPDATE t SET (a, b) = (SELECT t.a, t.b || '+'); I get: ERROR: attribute 1 of type tp1 has wrong type DETAIL: Table has type text, but query expects integer. By comparing two callstacks I can see that in the second case ExecInterpExprStillValid() is executed after the latest ExecEvalExprSwitchContext(). The ExecInterpExprStillValid() function contains: /* skip the check during further executions */ state->evalfunc = (ExprStateEvalFunc) state->evalfunc_private; If just call evalfunc_private() here, the first case ends with the error as expected. Observed on REL_11_STABLE..master.
pgsql-bugs by date: