diff --git a/src/backend/gporca/libgpopt/src/xforms/CXformSplitWindowFunc.cpp b/src/backend/gporca/libgpopt/src/xforms/CXformSplitWindowFunc.cpp index 92a310101bc..be1c5efa278 100644 --- a/src/backend/gporca/libgpopt/src/xforms/CXformSplitWindowFunc.cpp +++ b/src/backend/gporca/libgpopt/src/xforms/CXformSplitWindowFunc.cpp @@ -375,6 +375,16 @@ CXformSplitWindowFunc::Transform(CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexprLocalSelect = GPOS_NEW(mp) CExpression(mp, pSelectCopy, pexprLocal, pexprScalarCmp); + // the global SequenceProject below takes ownership of one reference each to + // pds, pdrgpos and pdrgpwf, just like the local SequenceProject above. Only + // a single AddRef() was issued for each of them, so add the matching + // references here; otherwise the reference count underflows, these objects + // are freed while still in use, and the dangling memory later crashes the + // DXL-to-PlStmt translation (use-after-free) + pds->AddRef(); + pdrgpos->AddRef(); + pdrgpwf->AddRef(); + CExpression *pexprGlobal = GPOS_NEW(mp) CExpression(mp, GPOS_NEW(mp) CLogicalSequenceProject( @@ -382,6 +392,9 @@ CXformSplitWindowFunc::Transform(CXformContext *pxfctxt, CXformResult *pxfres, pdrgpos, pdrgpwf), pexprLocalSelect, pexprProjectListGlobal); + pexpr->Pop()->AddRef(); + pexprScalarCmp->AddRef(); + CExpression *pexprGlobalSelect = GPOS_NEW(mp) CExpression(mp, pexpr->Pop(), pexprGlobal, pexprScalarCmp);