0001-patch-eval-NULLIF.patch
application/octet-stream
Filename: 0001-patch-eval-NULLIF.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: OSS patch eval NULLIF
| File | + | − |
|---|---|---|
| src/backend/optimizer/util/clauses.c | 70 | 0 |
| src/test/regress/expected/case.out | 24 | 0 |
| src/test/regress/sql/case.sql | 9 | 0 |
From 888dcb811bcdd6ed6a576ebd65f851b750da3937 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Tue, 10 Nov 2020 14:13:22 -0500
Subject: [PATCH] OSS patch eval NULLIF
---
src/backend/optimizer/util/clauses.c | 70 ++++++++++++++++++++++++++++++++++++
src/test/regress/expected/case.out | 24 +++++++++++++
src/test/regress/sql/case.sql | 9 +++++
3 files changed, 103 insertions(+)
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 65534ed..d83ce24 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -2596,6 +2596,76 @@ eval_const_expressions_mutator(Node *node,
newexpr->location = expr->location;
return (Node *) newexpr;
}
+ case T_NullIfExpr:
+ {
+ NullIfExpr *expr = (NullIfExpr *) node;
+ List *args = expr->args;
+ ListCell *arg;
+ Expr *simple;
+ NullIfExpr *newexpr;
+
+ /* Recursively simplify the args */
+ args = (List *) expression_tree_mutator((Node *) expr->args,
+ eval_const_expressions_mutator,
+ (void *) context);
+
+ /* If either argument is NULL they can't be equal */
+ foreach(arg, args)
+ {
+ if (IsA(lfirst(arg), Const) && ((Const *) lfirst(arg))->constisnull)
+ {
+ return (Node *) linitial(args);
+ }
+ }
+
+ /*
+ * Need to get OID of underlying function. Okay to scribble
+ * on input to this extent.
+ */
+ set_opfuncid(expr);
+
+ /*
+ * Code for op/func reduction is pretty bulky, so split it out
+ * as a separate function.
+ */
+ simple = simplify_function(expr->opfuncid,
+ BOOLOID, -1,
+ expr->opcollid,
+ expr->inputcollid,
+ &args,
+ false,
+ false,
+ true,
+ context);
+
+ /* successfully simplified it */
+ if (simple && IsA(simple, Const))
+ {
+ /* if the arguments are equal return null */
+ if(DatumGetBool(((Const *) simple)->constvalue))
+ return (Node *) makeNullConst(exprType(node),
+ exprTypmod(node),
+ exprCollation(node));
+ else
+ return (Node *) linitial(args);
+ }
+
+ /*
+ * The expression cannot be simplified any further, so build
+ * and return a replacement NullIfExpr node using the
+ * possibly-simplified arguments.
+ */
+ newexpr = makeNode(NullIfExpr);
+ newexpr->opno = expr->opno;
+ newexpr->opfuncid = expr->opfuncid;
+ newexpr->opresulttype = expr->opresulttype;
+ newexpr->opretset = expr->opretset;
+ newexpr->opcollid = expr->opcollid;
+ newexpr->inputcollid = expr->inputcollid;
+ newexpr->args = args;
+ newexpr->location = expr->location;
+ return (Node *) newexpr;
+ }
case T_DistinctExpr:
{
DistinctExpr *expr = (DistinctExpr *) node;
diff --git a/src/test/regress/expected/case.out b/src/test/regress/expected/case.out
index c0c8acf..130b9f0 100644
--- a/src/test/regress/expected/case.out
+++ b/src/test/regress/expected/case.out
@@ -263,6 +263,30 @@ SELECT '' AS "Two", *
| 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 17436c5..c328f34 100644
--- a/src/test/regress/sql/case.sql
+++ b/src/test/regress/sql/case.sql
@@ -137,6 +137,15 @@ SELECT '' AS "Two", *
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
--
--
2.7.2.windows.1