BUG #16712: Wrong Sub-Query Record Filtering

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

BUG #16712: Wrong Sub-Query Record Filtering

apt.postgresql.org Repository Update
The following bug has been logged on the website:

Bug reference:      16712
Logged by:          SP
Email address:      [hidden email]
PostgreSQL version: 13.0
Operating system:   seems any (tested on Ubuntu 18.04 and macOS 10.15)
Description:        

An unexpected result returns when running this query:

WITH data_cte(str) AS (
    SELECT *
    FROM (VALUES ('a')) data_tmp(str)
    WHERE FALSE
)
SELECT str::INTEGER
FROM data_cte;

While empty result is expected, we get this:

ERROR:  invalid input syntax for type integer: "a"

Because of these type casting error, it seems that the outer query has
access to the data_cte record!

The strange thing is that if records of data_tmp (or data_cte, it doesn't
matter) be more than one, result will be true. So, for this query:

WITH data_cte(str) AS (
    SELECT *
    FROM (VALUES ('1a'), ('2b')) data_tmp(str)
    WHERE FALSE
)
SELECT str::INTEGER
FROM data_cte;

we get this:

 substring
-----------
(0 rows)

Reply | Threaded
Open this post in threaded view
|

Re: BUG #16712: Wrong Sub-Query Record Filtering

David G Johnston
On Thu, Nov 12, 2020 at 7:34 AM PG Bug reporting form <[hidden email]> wrote:
The following bug has been logged on the website:

Bug reference:      16712
Logged by:          SP
Email address:      [hidden email]
PostgreSQL version: 13.0
Operating system:   seems any (tested on Ubuntu 18.04 and macOS 10.15)
Description:       

An unexpected result returns when running this query:

WITH data_cte(str) AS (
    SELECT *
    FROM (VALUES ('a')) data_tmp(str)
    WHERE FALSE
)
SELECT str::INTEGER
FROM data_cte;

While empty result is expected, we get this:

ERROR:  invalid input syntax for type integer: "a"

Because of these type casting error, it seems that the outer query has
access to the data_cte record!


It does - right there in the "FROM data_cte" clause.  The planner has chosen to optimize this query by taking the two parts and making them one, reducing a level of execution indirection.  If you don't wish for this to happen you need to add MATERIALIZED to the WITH clause element.  This is one of the more impactful changes with v13, in prior versions materialized was the default (and optimization was not possible).

David J.