From 730b8d8b445460b9e5cbb4473985feb908febee7 Mon Sep 17 00:00:00 2001
From: Richard Guo <riguo@pivotal.io>
Date: Wed, 17 Oct 2018 07:29:00 +0000
Subject: [PATCH] Pull up sublink of type 'NOT NOT (expr)'.

---
 src/backend/optimizer/prep/prepjointree.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index cd6e119..abc1688 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -454,13 +454,14 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
 	}
 	if (not_clause(node))
 	{
-		/* If the immediate argument of NOT is EXISTS, try to convert */
-		SubLink    *sublink = (SubLink *) get_notclausearg((Expr *) node);
+		Node       *arg = (Node *) get_notclausearg((Expr *) node);
 		JoinExpr   *j;
 		Relids		child_rels;
 
-		if (sublink && IsA(sublink, SubLink))
+		/* If the immediate argument of NOT is EXISTS, try to convert */
+		if (arg && IsA(arg, SubLink))
 		{
+			SubLink    *sublink = (SubLink *) arg;
 			if (sublink->subLinkType == EXISTS_SUBLINK)
 			{
 				if ((j = convert_EXISTS_sublink_to_join(root, sublink, true,
@@ -516,6 +517,16 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
 				}
 			}
 		}
+		else if (not_clause(arg))
+		{
+			/* NOT NOT (expr) => (expr)  */
+			return pull_up_sublinks_qual_recurse(root,
+												 (Node *) get_notclausearg((Expr *) arg),
+												 jtlink1,
+												 available_rels1,
+												 jtlink2,
+												 available_rels2);
+		}
 		/* Else return it unmodified */
 		return node;
 	}
-- 
2.7.4

