Running Postgres 9.1.2.

I've attached a backtrace. Looking at the backtrace it looks like
ExecGetResultType() gets called with a NULL planstate and causes the
segmentation fault:

https://github.com/postgres/postgres/blob/master/src/backend/executor/execUtils.c#L470

Following the stack I see that an optimization for writeable CTE's
inserts a NULL subplanstate:

https://github.com/postgres/postgres/blob/master/src/backend/executor/execMain.c#L2344

ExecInitCteScan() is what eventually passes it to ExecGetResultType():

https://github.com/postgres/postgres/blob/master/src/backend/executor/nodeCtescan.c#L255

I've also attached a proposed fix. In this optimized case it says that
we won't ever use the subplan anyway, so I figured that not setting
the scan tuple type won't matter. I also added an Assert() to
ExecGetResultType(). I modified the declaration of 'slot' to remove a
compiler warning. This patch is against master but should backport to
9.1 cleanly. It also passed all regression tests. If you end up using
this patch please also credit Rick Pufky who helped me with this.
#0  ExecGetResultType (planstate=0x0) at execUtils.c:479
#1  0x00000000005893d9 in ExecInitCteScan (node=0x13d3a30, estate=0x143d6f0, 
    eflags=<value optimized out>) at nodeCtescan.c:259
#2  0x0000000000570f75 in ExecInitNode (node=0x0, estate=0x143d6f0, 
eflags=21224384)
    at execProcnode.c:227
#3  0x000000000056e564 in EvalPlanQualStart (epqstate=0x141ea30, 
    parentestate=<value optimized out>) at execMain.c:2293
#4  EvalPlanQualBegin (epqstate=0x141ea30, parentestate=<value optimized out>)
    at execMain.c:2144
#5  0x000000000056ec96 in EvalPlanQual (estate=0x141d6a0, epqstate=0x141ea30, 
    relation=<value optimized out>, rti=3, tid=0x7fff46ea4630, 
    priorXmax=<value optimized out>) at execMain.c:1710
#6  0x0000000000586e91 in ExecUpdate (node=0x141e990) at nodeModifyTable.c:587
#7  ExecModifyTable (node=0x141e990) at nodeModifyTable.c:838
#8  0x0000000000570d98 in ExecProcNode (node=0x141e990) at execProcnode.c:371
#9  0x000000000058956c in CteScanNext (node=0x1426a00) at nodeCtescan.c:103
#10 0x0000000000577fce in ExecScanFetch (node=0x1426a00, 
    accessMtd=<value optimized out>, recheckMtd=<value optimized out>) at 
execScan.c:82
#11 ExecScan (node=0x1426a00, accessMtd=<value optimized out>, 
    recheckMtd=<value optimized out>) at execScan.c:167
#12 0x0000000000570ce8 in ExecProcNode (node=0x1426a00) at execProcnode.c:424
#13 0x000000000058a835 in ExecSetParamPlan (node=0x1430e90, econtext=0x142c3b0)
    at nodeSubplan.c:922
#14 0x0000000000576bd7 in ExecEvalParamExec (exprstate=<value optimized out>, 
    econtext=0x1a30, isNull=0x7fff46ea481f "", isDone=0x1) at execQual.c:990
#15 0x00000000005710cc in ExecEvalNot (notclause=<value optimized out>, 
    econtext=0x1a30, isNull=0x7fff46ea481f "", isDone=<value optimized out>)
    at execQual.c:2566
#16 0x00000000005715df in ExecQual (qual=<value optimized out>, 
econtext=0x142c3b0, 
    resultForNull=0 '\000') at execQual.c:5006
#17 0x0000000000587fe6 in ExecResult (node=0x142c2a0) at nodeResult.c:82
#18 0x0000000000570da8 in ExecProcNode (node=0x142c2a0) at execProcnode.c:367
#19 0x0000000000577fce in ExecScanFetch (node=0x1429958, 
    accessMtd=<value optimized out>, recheckMtd=<value optimized out>) at 
execScan.c:82
#20 ExecScan (node=0x1429958, accessMtd=<value optimized out>, 
    recheckMtd=<value optimized out>) at execScan.c:167
#21 0x0000000000570d18 in ExecProcNode (node=0x1429958) at execProcnode.c:412
#22 0x000000000058653e in ExecModifyTable (node=0x1429048) at 
nodeModifyTable.c:765
#23 0x0000000000570d98 in ExecProcNode (node=0x1429048) at execProcnode.c:371
#24 0x000000000056fc32 in ExecutePlan (queryDesc=0x1409670, direction=6704, 
count=0)
    at execMain.c:1439
#25 standard_ExecutorRun (queryDesc=0x1409670, direction=6704, count=0)
    at execMain.c:313
#26 0x00007f386af2a68b in explain_ExecutorRun (queryDesc=<value optimized out>, 
    direction=<value optimized out>, count=<value optimized out>) at 
auto_explain.c:214
#27 0x00000000005913f1 in _SPI_pquery (plan=<value optimized out>, 
    paramLI=<value optimized out>, snapshot=<value optimized out>, 
    crosscheck_snapshot=<value optimized out>, read_only=0 '\000', 
    fire_triggers=<value optimized out>, tcount=<value optimized out>) at 
spi.c:2110
#28 _SPI_execute_plan (plan=<value optimized out>, paramLI=<value optimized 
out>, 
    snapshot=<value optimized out>, crosscheck_snapshot=<value optimized out>, 
    read_only=0 '\000', fire_triggers=<value optimized out>, 
    tcount=<value optimized out>) at spi.c:1922
#29 0x00000000005917ac in SPI_execute_plan_with_paramlist (plan=0x1396340, 
    params=<value optimized out>, read_only=0 '\000', tcount=<value optimized 
out>)
    at spi.c:423
#30 0x00007f36ddb6f9dd in exec_stmt_execsql (estate=0x7fff46ea4f70, 
stmt=0x1387350)
    at pl_exec.c:3036
#31 0x00007f36ddb71c6e in exec_stmt (estate=0x7fff46ea4f70, stmts=<value 
optimized out>)
    at pl_exec.c:1342
#32 exec_stmts (estate=0x7fff46ea4f70, stmts=<value optimized out>) at 
pl_exec.c:1241
#33 0x00007f36ddb7330f in exec_stmt_block (estate=<value optimized out>, 
    block=<value optimized out>) at pl_exec.c:1179
#34 0x00007f36ddb73e82 in plpgsql_exec_function (func=0x1344358, 
fcinfo=0x135e220)
    at pl_exec.c:319
#35 0x00007f36ddb68f33 in plpgsql_call_handler (fcinfo=<value optimized out>)
    at pl_handler.c:122
#36 0x00000000006fd6c9 in fmgr_security_definer (fcinfo=<value optimized out>)
    at fmgr.c:968
#37 0x00000000005762bd in ExecMakeFunctionResult (fcache=0x135e1b0, 
    econtext=<value optimized out>, isNull=0x135f4c8 "", isDone=<value 
optimized out>)
    at execQual.c:1824
#38 0x00000000005717d6 in ExecTargetList (projInfo=<value optimized out>, 
    isDone=<value optimized out>) at execQual.c:5104
#39 ExecProject (projInfo=<value optimized out>, isDone=<value optimized out>)
    at execQual.c:5319
#40 0x0000000000587f9b in ExecResult (node=0x135deb0) at nodeResult.c:155
#41 0x0000000000570da8 in ExecProcNode (node=0x135deb0) at execProcnode.c:367
#42 0x000000000056fc32 in ExecutePlan (queryDesc=0x13de430, direction=6704, 
count=0)
    at execMain.c:1439
#43 standard_ExecutorRun (queryDesc=0x13de430, direction=6704, count=0)
    at execMain.c:313
#44 0x00007f386af2a68b in explain_ExecutorRun (queryDesc=<value optimized out>, 
    direction=<value optimized out>, count=<value optimized out>) at 
auto_explain.c:214
#45 0x000000000063c047 in PortalRunSelect (portal=0x1365db0, 
    forward=<value optimized out>, count=0, dest=0x1318eb0) at pquery.c:943
#46 0x000000000063d368 in PortalRun (portal=<value optimized out>, 
    count=<value optimized out>, isTopLevel=<value optimized out>, 
    dest=<value optimized out>, altdest=<value optimized out>, 
    completionTag=<value optimized out>) at pquery.c:787
#47 0x000000000063ad13 in exec_execute_message (argc=<value optimized out>, 
    argv=<value optimized out>, username=<value optimized out>) at 
postgres.c:1963
#48 PostgresMain (argc=<value optimized out>, argv=<value optimized out>, 
    username=<value optimized out>) at postgres.c:3983
#49 0x00000000005fc289 in BackendRun () at postmaster.c:3601
#50 BackendStartup () at postmaster.c:3286
#51 ServerLoop () at postmaster.c:1455
#52 0x00000000005fe9cc in PostmasterMain (argc=3, argv=0x1226400) at 
postmaster.c:1116
#53 0x000000000059fcc0 in main (argc=3, argv=0x12263f0) at main.c:199
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
new file mode 100644
index 6db42e7..faba8b2
*** a/src/backend/executor/execUtils.c
--- b/src/backend/executor/execUtils.c
*************** ExecAssignResultTypeFromTL(PlanState *pl
*** 474,480 ****
  TupleDesc
  ExecGetResultType(PlanState *planstate)
  {
! 	TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
  
  	return slot->tts_tupleDescriptor;
  }
--- 474,483 ----
  TupleDesc
  ExecGetResultType(PlanState *planstate)
  {
! 	TupleTableSlot *slot;
! 
! 	Assert(planstate != NULL);
! 	slot = planstate->ps_ResultTupleSlot;
  
  	return slot->tts_tupleDescriptor;
  }
diff --git a/src/backend/executor/nodeCtescan.c b/src/backend/executor/nodeCtescan.c
new file mode 100644
index 7ab15ac..e485c1a
*** a/src/backend/executor/nodeCtescan.c
--- b/src/backend/executor/nodeCtescan.c
*************** ExecInitCteScan(CteScan *node, EState *e
*** 255,262 ****
  	/*
  	 * The scan tuple type (ie, the rowtype we expect to find in the work
  	 * table) is the same as the result rowtype of the CTE query.
  	 */
! 	ExecAssignScanType(&scanstate->ss,
  					   ExecGetResultType(scanstate->cteplanstate));
  
  	/*
--- 255,265 ----
  	/*
  	 * The scan tuple type (ie, the rowtype we expect to find in the work
  	 * table) is the same as the result rowtype of the CTE query.
+ 	 * We must check for NULL because we don't initialize data-modifying
+ 	 * CTE's with a ModifyTable node at the top.
  	 */
! 	if (scanstate->cteplanstate != NULL)
! 		ExecAssignScanType(&scanstate->ss,
  					   ExecGetResultType(scanstate->cteplanstate));
  
  	/*
-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to