From 45a4d3aa352894386a88436048106c38335b94b2 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Tue, 12 Jan 2021 01:39:50 -0500
Subject: [PATCH] add nullif case for eval_const_expressions

---
 src/backend/optimizer/util/clauses.c | 23 +++++++++++++++++++++++
 src/test/regress/expected/case.out   | 24 ++++++++++++++++++++++++
 src/test/regress/sql/case.sql        |  9 +++++++++
 3 files changed, 56 insertions(+)

diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 51d26a0..94e703e 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -2329,6 +2329,29 @@ eval_const_expressions_mutator(Node *node,
 				newexpr->location = expr->location;
 				return (Node *) newexpr;
 			}
+		case T_NullIfExpr:
+			{
+				NullIfExpr	   *expr;
+				ListCell	   *arg;
+				bool			has_nonconst_input = false;
+
+				/* Copy the node and const-simplify its arguments */
+				expr = (NullIfExpr *) ece_generic_processing(node);
+
+				/* If either argument is NULL they can't be equal */
+				foreach(arg, expr->args)
+				{
+					if (!IsA(lfirst(arg), Const))
+						has_nonconst_input = true;
+					else if (((Const *) lfirst(arg))->constisnull)
+						return (Node *) linitial(expr->args);
+				}
+
+				if(!has_nonconst_input)
+					return ece_evaluate_expr(expr);
+
+				return (Node *) expr;
+			}
 		case T_DistinctExpr:
 			{
 				DistinctExpr *expr = (DistinctExpr *) node;
diff --git a/src/test/regress/expected/case.out b/src/test/regress/expected/case.out
index 7fcfe9a..2063c73 100644
--- a/src/test/regress/expected/case.out
+++ b/src/test/regress/expected/case.out
@@ -263,6 +263,30 @@ SELECT *
  4 |   | 2 | -4
 (2 rows)
 
+explain (costs off)
+SELECT * FROM CASE_TBL WHERE NULLIF(1, 2) = 2;
+        QUERY PLAN        
+--------------------------
+ Result
+   One-Time Filter: false
+(2 rows)
+
+explain (costs off)
+SELECT * FROM CASE_TBL WHERE NULLIF(1, 1) IS NOT NULL;
+        QUERY PLAN        
+--------------------------
+ Result
+   One-Time Filter: false
+(2 rows)
+
+explain (costs off)
+SELECT * FROM CASE_TBL WHERE NULLIF(1, null) = 2;
+        QUERY PLAN        
+--------------------------
+ Result
+   One-Time Filter: false
+(2 rows)
+
 --
 -- Examples of updates involving tables
 --
diff --git a/src/test/regress/sql/case.sql b/src/test/regress/sql/case.sql
index 0655d26..4742e1d 100644
--- a/src/test/regress/sql/case.sql
+++ b/src/test/regress/sql/case.sql
@@ -137,6 +137,15 @@ SELECT *
   FROM CASE_TBL a, CASE2_TBL b
   WHERE COALESCE(f,b.i) = 2;
 
+explain (costs off)
+SELECT * FROM CASE_TBL WHERE NULLIF(1, 2) = 2;
+
+explain (costs off)
+SELECT * FROM CASE_TBL WHERE NULLIF(1, 1) IS NOT NULL;
+
+explain (costs off)
+SELECT * FROM CASE_TBL WHERE NULLIF(1, null) = 2;
+
 --
 -- Examples of updates involving tables
 --
-- 
1.8.3.1

