未验证 提交 5f58e117 编写于 作者: ( (Jerome)Junfeng Yang 提交者: GitHub

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 a453004e, 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: NPaul Guo <paulguo@gmail.com>
上级 06d7fe0a
......@@ -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, ' ');
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册