From: | Kyotaro Horiguchi <horikyota(dot)ntt(at)gmail(dot)com> |
---|---|
To: | greigwise(at)comcast(dot)net |
Cc: | pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: Non-Materialized CTE bug? |
Date: | 2020-10-28 02:14:10 |
Message-ID: | 20201028.111410.893088314257858562.horikyota.ntt@gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Hello.
At Tue, 27 Oct 2020 17:43:08 -0700 (MST), greigwise <greigwise(at)comcast(dot)net> wrote in
> create table types (type varchar);
> CREATE TABLE
> insert into types values ('a');
>
> with test (i, j) as
> (values ( 1, '{"key": "a", "value": "true"}'::json), (2, '{"key": "b",
> "value": "xxx"}'::json)),
> test2 (i, j) as (select i, (j->>'value')::boolean
> from test a
> join types b on b.type = a.j->>'key') select * from test2 where j = true;
>
> ERROR: invalid input syntax for type boolean: "xxx"
>
> Why would this result in an error here? It seems like the second row from
> the "test" CTE should be excluded since the key value "b" will not join with
> anything in the "types" table. If I materialize the "test2" CTE, then it
> works as I'd expect without error. Is this a bug? It seems like the
> optimizer should be smart enough to know that it has to materialize that
> CTE. This is on version 12.4.
test2 needs to evaluate all the output columns *before* the join with
types, which leads to the error. You need to make sure that the
::boolean is evaluated after the join. MATERIALIZE prevents the CTE
from being merged into upper queries.
The following rewrites work.
with
test (i, j) as
(values ( 1, '{"key": "a", "value": "true"}'::json),
(2, '{"key": "b", "value": "xxx"}'::json)),
test2 (i, j) as MATERIALIZED
(select i, j->>'value' as j
from test a
join types b on b.type = a.j->>'key')
select i from test2 where j::boolean = true;
with
test (i, j) as
(values ( 1, '{"key": "a", "value": "true"}'::json),
(2, '{"key": "b", "value": "xxx"}'::json)),
test2 (i, j) as MATERIALIZED
(select i, j->>'value' as j
from test a
join types b on b.type = a.j->>'key'),
test3 (i, j) as
(select i, j::boolean as j from test2)
select i from test3 where j = true;
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2020-10-28 03:27:05 | Re: BUG #16688: psql removes only LF without CR at end of backquotes on windows. |
Previous Message | PG Bug reporting form | 2020-10-28 01:58:57 | BUG #16688: psql removes only LF without CR at end of backquotes on windows. |