Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rmbga-008sjy-28 for pgsql-bugs@arkaria.postgresql.org; Tue, 19 Mar 2024 15:47:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rmbgY-00GX3r-D5 for pgsql-bugs@arkaria.postgresql.org; Tue, 19 Mar 2024 15:47:30 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rmbgY-00GX3j-5B for pgsql-bugs@lists.postgresql.org; Tue, 19 Mar 2024 15:47:30 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rmbgU-005LQM-T0 for pgsql-bugs@lists.postgresql.org; Tue, 19 Mar 2024 15:47:29 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 42JFlQoL3877107; Tue, 19 Mar 2024 11:47:26 -0400 From: Tom Lane To: scknoblich@gmail.com cc: pgsql-bugs@lists.postgresql.org Subject: Re: BUG #18399: Query plan optimization results in runtime error when hoisting cast from inside subquery In-reply-to: <18399-17778030a1971177@postgresql.org> References: <18399-17778030a1971177@postgresql.org> Comments: In-reply-to PG Bug reporting form message dated "Mon, 18 Mar 2024 23:23:44 -0000" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <3877105.1710863246.1@sss.pgh.pa.us> Date: Tue, 19 Mar 2024 11:47:26 -0400 Message-ID: <3877106.1710863246@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk PG Bug reporting form writes: > My expectation was that the query should behave as if the CTE (or subquery > if I had used that instead) has fully executed before moving on to the main > query and this behavior breaks that assumption (which may or may not be > correct). I attempted to search the docs for anything related to this, > either CTE/subquery execution order guarantees or hoisting of casts, but I > couldn't find anything about it. If this turns out not to a bug and is just > expected behavior with existing documentation could you please link me to > the relevant page for future reference? You need to materialize the CTE to be certain that it won't be intermingled with the calling query: =# with raw_data(id, value) as (values (1, '1900'), (2, '2100'), (3, 'abc')), integers as materialized (select value::integer from raw_data where id in (select id from raw_data where value ~ '^\d+$')) select count(*) from integers where value < 2000; count ------- 1 (1 row) See https://www.postgresql.org/docs/current/sql-select.html#SQL-WITH (last few paras of that sub-section). The real bottom line here is that the cast to integer is presumed to be side-effect-free, which isn't true if you're working with data where it could throw errors. My advice is to rethink your data model: this sort of EAV approach with inconsistent data types in the "same" column just does not play nice with SQL optimizers, so it'll cause you ongoing heartburn. If you think you're too far down the road for that, consider replacing the cast with some non-error-throwing user-defined function, about like case when x ~ '^\d+$' then x::integer else null::integer end regards, tom lane