@@ -1454,6 +1454,7 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
14541454 Query * parse = root -> parse ;
14551455 Query * subselect = (Query * ) sublink -> subselect ;
14561456 Node * whereClause ;
1457+ PlannerInfo subroot ;
14571458 int rtoffset ;
14581459 int varno ;
14591460 Relids clause_varnos ;
@@ -1515,6 +1516,35 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
15151516 if (contain_volatile_functions (whereClause ))
15161517 return NULL ;
15171518
1519+ /*
1520+ * Scan the rangetable for relation RTEs and retrieve the necessary
1521+ * catalog information for each relation. Using this information, clear
1522+ * the inh flag for any relation that has no children, collect not-null
1523+ * attribute numbers for any relation that has column not-null
1524+ * constraints, and expand virtual generated columns for any relation that
1525+ * contains them.
1526+ *
1527+ * Note: we construct up an entirely dummy PlannerInfo for use here. This
1528+ * is fine because only the "glob" and "parse" links will be used in this
1529+ * case.
1530+ *
1531+ * Note: we temporarily assign back the WHERE clause so that any virtual
1532+ * generated column references within it can be expanded. It should be
1533+ * separated out again afterward.
1534+ */
1535+ MemSet (& subroot , 0 , sizeof (subroot ));
1536+ subroot .type = T_PlannerInfo ;
1537+ subroot .glob = root -> glob ;
1538+ subroot .parse = subselect ;
1539+ subselect -> jointree -> quals = whereClause ;
1540+ subselect = preprocess_relation_rtes (& subroot );
1541+
1542+ /*
1543+ * Now separate out the WHERE clause again.
1544+ */
1545+ whereClause = subselect -> jointree -> quals ;
1546+ subselect -> jointree -> quals = NULL ;
1547+
15181548 /*
15191549 * The subquery must have a nonempty jointree, but we can make it so.
15201550 */
@@ -1732,6 +1762,7 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
17321762 Node * * testexpr , List * * paramIds )
17331763{
17341764 Node * whereClause ;
1765+ PlannerInfo subroot ;
17351766 List * leftargs ,
17361767 * rightargs ,
17371768 * opids ,
@@ -1791,12 +1822,15 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
17911822 * parent aliases were flattened already, and we're not going to pull any
17921823 * child Vars (of any description) into the parent.
17931824 *
1794- * Note: passing the parent's root to eval_const_expressions is
1795- * technically wrong, but we can get away with it since only the
1796- * boundParams (if any) are used, and those would be the same in a
1797- * subroot.
1798- */
1799- whereClause = eval_const_expressions (root , whereClause );
1825+ * Note: we construct up an entirely dummy PlannerInfo to pass to
1826+ * eval_const_expressions. This is fine because only the "glob" and
1827+ * "parse" links are used by eval_const_expressions.
1828+ */
1829+ MemSet (& subroot , 0 , sizeof (subroot ));
1830+ subroot .type = T_PlannerInfo ;
1831+ subroot .glob = root -> glob ;
1832+ subroot .parse = subselect ;
1833+ whereClause = eval_const_expressions (& subroot , whereClause );
18001834 whereClause = (Node * ) canonicalize_qual ((Expr * ) whereClause , false);
18011835 whereClause = (Node * ) make_ands_implicit ((Expr * ) whereClause );
18021836
0 commit comments