Re: Properly pathify the union planner

Richard Guo <guofenglinux@gmail.com>

From: Richard Guo <guofenglinux@gmail.com>
To: David Rowley <dgrowleyml@gmail.com>
Cc: Alexander Lakhin <exclusion@gmail.com>, PostgreSQL Developers <pgsql-hackers@lists.postgresql.org>
Date: 2024-03-27T03:14:52Z
Lists: pgsql-hackers
On Wed, Mar 27, 2024 at 6:23 AM David Rowley <dgrowleyml@gmail.com> wrote:

> Because this field is set, it plans the CTE thinking it's a UNION
> child and breaks when it can't find a SortGroupClause for the CTE's
> target list item.


Right.  The problem here is that we mistakenly think that the CTE query
is a subquery for the set operation and thus store the SetOperationStmt
in its qp_extra.  Currently the code for the check is:

   /*
    * Check if we're a subquery for a set operation.  If we are, store
    * the SetOperationStmt in qp_extra.
    */
   if (root->parent_root != NULL &&
       root->parent_root->parse->setOperations != NULL &&
       IsA(root->parent_root->parse->setOperations, SetOperationStmt))
       qp_extra.setop =
           (SetOperationStmt *) root->parent_root->parse->setOperations;
   else
       qp_extra.setop = NULL;

This check cannot tell if the subquery is for a set operation or a CTE,
because its parent might have setOperations set in both cases.  Hmm, is
there any way to differentiate between the two?

Thanks
Richard

Commits

  1. Don't adjust ressortgroupref in generate_setop_child_grouplist()

  2. Don't zero tuple_fraction when planning UNIONs with ORDER BYs

  3. Fix assert failure when planning setop subqueries with CTEs

  4. Allow planner to use Merge Append to efficiently implement UNION

  5. Simplify PathKey checking code

  6. Clarify the 'rows' parameter in create_append_path