From 9c5f67fd6256246b2a788a8feb1d42b79dcd0448 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 2 Apr 2021 11:01:49 +0200 Subject: [PATCH] Add support for NullIfExpr in eval_const_expressions Author: Hou Zhijie Discussion: https://www.postgresql.org/message-id/flat/7ea5ce773bbc4eea9ff1a381acd3b102@G08CNEXMBPEKD05.g08.fujitsu.local --- src/backend/optimizer/util/clauses.c | 30 ++++++++++++++++++++++++++++ src/test/regress/expected/case.out | 25 +++++++++++++++++++++++ src/test/regress/sql/case.sql | 11 ++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index e89571ed40..bea1cc4d67 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2497,6 +2497,36 @@ 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); + } + + /* + * Need to get OID of underlying function before checking if + * the function is OK to evaluate. + */ + set_opfuncid((OpExpr *) expr); + + if (!has_nonconst_input && + ece_function_is_safe(expr->opfuncid, context)) + return ece_evaluate_expr(expr); + + return (Node *) expr; + } case T_ScalarArrayOpExpr: { ScalarArrayOpExpr *saop; diff --git a/src/test/regress/expected/case.out b/src/test/regress/expected/case.out index 7fcfe9a7a6..f5136c17ab 100644 --- a/src/test/regress/expected/case.out +++ b/src/test/regress/expected/case.out @@ -263,6 +263,31 @@ SELECT * 4 | | 2 | -4 (2 rows) +-- Tests for constant subexpression simplification +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 0655d266f6..83fe43be6b 100644 --- a/src/test/regress/sql/case.sql +++ b/src/test/regress/sql/case.sql @@ -137,6 +137,17 @@ SELECT * FROM CASE_TBL a, CASE2_TBL b WHERE COALESCE(f,b.i) = 2; +-- Tests for constant subexpression simplification + +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 --