From 5f58e1173b6d37848112aad3f4c5cadb1edd0086 Mon Sep 17 00:00:00 2001 From: "(Jerome)Junfeng Yang" Date: Tue, 30 Jun 2020 11:44:10 +0800 Subject: [PATCH] Fix a cornor case which dump CaseTestExpr for IS NOT DISTINCT FROM. (#10348) For below example: ``` CREATE TABLE mytable2 ( key character varying(20) NOT NULL, key_value character varying(50) ) DISTRIBUTED BY (key); CREATE VIEW aaa AS SELECT CASE mytable2.key_value WHEN IS NOT DISTINCT FROM 'NULL'::text THEN 'now'::text::date ELSE to_date(mytable2.key_value::text, 'YYYYMM'::text) END AS t FROM mytable2; ``` mytable2.key_value will cast to type date. For clause `(ARG1) IS NOT DISTINCT FROM (ARG2)`, this leads ARG1 to become a RelabelType node and contains CaseTestExpr node in RelabelType->arg. So when dumping the view, it'll dump extra `CASE_TEST_EXPR` as below ``` select pg_get_viewdef('notdisview3',false); pg_get_viewdef ----------------------------------------------------------------------------- SELECT + CASE mytable2.key_value + WHEN (CASE_TEST_EXPR) IS NOT DISTINCT FROM 'NULL'::text THEN ('now'::text)::date+ ELSE to_date((mytable2.key_value)::text, 'YYYYMM'::text) + END AS t + FROM mytable2; (1 row) ``` I dig into commit a453004, if left-hand argument for `IS NOT DISTINCT FROM` contains any `CaseTestExpr` node, the left-hand arg should be omitted. `CaseTestExpr` is a placeholder for CASE expression. Reviewed-by: Paul Guo --- src/backend/utils/adt/ruleutils.c | 6 +++++- src/test/regress/expected/case_gp.out | 28 +++++++++++++++++++++++++-- src/test/regress/sql/case_gp.sql | 17 +++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 3bc9f924a3..fb248d474d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -7888,7 +7888,11 @@ get_rule_expr(Node *node, deparse_context *context, Node *lhs = (Node *) linitial(dexpr->args); Node *rhs = (Node *) lsecond(dexpr->args); - if (!IsA(lhs, CaseTestExpr)) + /* + * If lhs contains CaseTestExpr node as placeholder, we should + * omit the lhs for dump + */ + if (!IsA(strip_implicit_coercions(lhs), CaseTestExpr)) { get_rule_expr(lhs, context, false); appendStringInfoChar(buf, ' '); diff --git a/src/test/regress/expected/case_gp.out b/src/test/regress/expected/case_gp.out index 1fe477b3ea..27dcf6b590 100644 --- a/src/test/regress/expected/case_gp.out +++ b/src/test/regress/expected/case_gp.out @@ -21,7 +21,7 @@ DROP VIEW IF EXISTS notdisview; NOTICE: view "notdisview" does not exist, skipping CREATE OR REPLACE VIEW notdisview AS SELECT - CASE + CASE 'a'::text = 'test'::text WHEN 'test' IS NOT DISTINCT FROM ''::text THEN 'A'::text ELSE 'B'::text END AS t; @@ -29,7 +29,7 @@ select pg_get_viewdef('notdisview',true); pg_get_viewdef ---------------------------------------------------------------------------- SELECT + - CASE + + CASE 'a'::text = 'test'::text + WHEN 'test'::text IS NOT DISTINCT FROM ''::text THEN 'A'::text+ ELSE 'B'::text + END AS t; @@ -55,6 +55,30 @@ select pg_get_viewdef('notdisview2',true); FROM mytable; (1 row) +CREATE TABLE mytable2 ( + key character varying(20) NOT NULL, + key_value character varying(50) +) DISTRIBUTED BY (key); +DROP VIEW IF EXISTS notdisview3; +NOTICE: view "notdisview3" does not exist, skipping +CREATE OR REPLACE VIEW notdisview3 AS +SELECT + CASE mytable2.key_value + WHEN IS NOT DISTINCT FROM 'NULL'::text THEN 'now'::text::date + ELSE to_date(mytable2.key_value::text, 'YYYYMM'::text) + END AS t + FROM mytable2; +select pg_get_viewdef('notdisview3',false); + pg_get_viewdef +----------------------------------------------------------------------------- + SELECT + + CASE mytable2.key_value + + WHEN IS NOT DISTINCT FROM 'NULL'::text THEN ('now'::text)::date+ + ELSE to_date((mytable2.key_value)::text, 'YYYYMM'::text) + + END AS t + + FROM mytable2; +(1 row) + CREATE OR REPLACE FUNCTION negate(int) RETURNS int AS 'SELECT $1 * (-1)' LANGUAGE sql CONTAINS SQL diff --git a/src/test/regress/sql/case_gp.sql b/src/test/regress/sql/case_gp.sql index deaea48253..e623e9c566 100644 --- a/src/test/regress/sql/case_gp.sql +++ b/src/test/regress/sql/case_gp.sql @@ -20,7 +20,7 @@ INSERT INTO mytable values (1,2,'t'), DROP VIEW IF EXISTS notdisview; CREATE OR REPLACE VIEW notdisview AS SELECT - CASE + CASE 'a'::text = 'test'::text WHEN 'test' IS NOT DISTINCT FROM ''::text THEN 'A'::text ELSE 'B'::text END AS t; @@ -36,6 +36,21 @@ SELECT FROM mytable; select pg_get_viewdef('notdisview2',true); +CREATE TABLE mytable2 ( + key character varying(20) NOT NULL, + key_value character varying(50) +) DISTRIBUTED BY (key); + +DROP VIEW IF EXISTS notdisview3; +CREATE OR REPLACE VIEW notdisview3 AS +SELECT + CASE mytable2.key_value + WHEN IS NOT DISTINCT FROM 'NULL'::text THEN 'now'::text::date + ELSE to_date(mytable2.key_value::text, 'YYYYMM'::text) + END AS t + FROM mytable2; +select pg_get_viewdef('notdisview3',false); + CREATE OR REPLACE FUNCTION negate(int) RETURNS int AS 'SELECT $1 * (-1)' LANGUAGE sql CONTAINS SQL -- GitLab