• Tom Lane's avatar
    Fix rewriter to set hasModifyingCTE correctly on rewritten queries. · 03d01d74
    Tom Lane authored
    If we copy data-modifying CTEs from the original query to a replacement
    query (from a DO INSTEAD rule), we must set hasModifyingCTE properly
    in the replacement query.  Failure to do this can cause various
    unpleasantness, such as unsafe usage of parallel plans.  The code also
    neglected to propagate hasRecursive, though that's only cosmetic at
    the moment.
    
    A difficulty arises if the rule action is an INSERT...SELECT.  We
    attach the original query's RTEs and CTEs to the sub-SELECT Query, but
    data-modifying CTEs are only allowed to appear in the topmost Query.
    For the moment, throw an error in such cases.  It would probably be
    possible to avoid this error by attaching the CTEs to the top INSERT
    Query instead; but that would require a bunch of new code to adjust
    ctelevelsup references.  Given the narrowness of the use-case, and
    the need to back-patch this fix, it does not seem worth the trouble
    for now.  We can revisit this if we get field complaints.
    
    Per report from Greg Nancarrow.  Back-patch to all supported branches.
    (The test case added here does not fail before v10, but there are
    plenty of places checking top-level hasModifyingCTE in 9.6, so I have
    no doubt that this code change is necessary there too.)
    
    Greg Nancarrow and Tom Lane
    
    Discussion: https://postgr.es/m/CAJcOf-f68DT=26YAMz_i0+Au3TcLO5oiHY5=fL6Sfuits6r+_w@mail.gmail.com
    Discussion: https://postgr.es/m/CAJcOf-fAdj=nDKMsRhQzndm-O13NY4dL6xGcEvdX5Xvbbi0V7g@mail.gmail.com
    03d01d74
rewriteHandler.c 131 KB