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.98.2) (envelope-from ) id 1xBvGL-00000003SR1-19QQ for pgsql-bugs@arkaria.postgresql.org; Wed, 30 Sep 2026 14:26:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1xBvGK-00000002m3t-0OLz for pgsql-bugs@arkaria.postgresql.org; Wed, 30 Sep 2026 14:26:24 +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.98.2) (envelope-from ) id 1xBt2e-00000002CVJ-0xhx for pgsql-bugs@lists.postgresql.org; Wed, 30 Sep 2026 12:04:08 +0000 Received: from mahout.postgresql.org ([2001:4800:3e1:1::227]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1xBt2c-0000000223g-29Er for pgsql-bugs@lists.postgresql.org; Wed, 30 Sep 2026 12:04:07 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Message-ID:Date:Reply-To:Cc:From:To:Subject: Content-Transfer-Encoding:MIME-Version:Content-Type:Sender:Content-ID: Content-Description:In-Reply-To:References; bh=hwLm0uzXs1wY0zgx0adhqnXsTuxoRrNRaIcc0yOG3VY=; b=X7mP6R5Rg8Sz4VB2B5AyzBZha9 MGGvZej8GfJPtzGKEXd79WbCPikI0A2IPLFTDfS2lSXnPWfWHiRMyD0aJihnGVlZZ/B/yjkKeKYuX veXwg3V6JS6ijHwZhe+JjCISqYGUFVk222MpgFzsfL0f2DJDjrrfInqs5tFNA64aRZk2yZyFfZ3l3 mlOwGQfTnYR4u+9JwKTDe6iTYdJsxCTyEcoIIHeBKhxcwt2+zPoKafKp1xwz7kwRjxK/CCwyFN5x3 VKVJIikhZKhHITsuI4MLbhoOKVFHZtreNg+eKxCbmawbmUJjy/65slsJ/DitS6N076Xg/TiqNA26j 1plvX2HQ==; Received: from wrigleys.postgresql.org ([2a02:16a8:dc51::60]) by mahout.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1xBt2b-000uk0-0B for pgsql-bugs@lists.postgresql.org; Wed, 30 Sep 2026 12:04:06 +0000 Received: from localhost ([127.0.0.1] helo=wrigleys.postgresql.org) by wrigleys.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1xBt2Z-0000000HW5h-1NQa for pgsql-bugs@lists.postgresql.org; Wed, 30 Sep 2026 12:04:03 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19734: NOT IN type resolution differs for outer Vars, producing different query results To: pgsql-bugs@lists.postgresql.org From: PG Bug reporting form Cc: anncalla@163.com Reply-To: anncalla@163.com, pgsql-bugs@lists.postgresql.org Date: Wed, 30 Sep 2026 12:03:21 +0000 Message-ID: <19734-049ac05dfb08ac4b@postgresql.org> X-Auto-Response-Suppress: All Auto-Submitted: auto-generated List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk The following bug has been logged on the website: Bug reference: 19734 Logged by: Ann Calla Email address: anncalla@163.com PostgreSQL version: 18.6 Operating system: Ubuntu 24.04 x86_64 Description: =20 I found a case where moving the same NOT IN predicate into a correlated EXISTS subquery changes the query result. Minimal reproducer: SELECT 'INNER_JOIN' AS q, COUNT(*) AS n FROM (VALUES (-969514295)) a(x) JOIN (VALUES (1)) b(y) ON x::real NOT IN (x, 0.7); SELECT 'EXISTS' AS q, COUNT(*) AS n FROM (VALUES (-969514295)) a(x) WHERE EXISTS ( SELECT 1 FROM (VALUES (1)) b(y) WHERE x::real NOT IN (x, 0.7) ); Actual result: q | n ------------+--- INNER_JOIN | 1 q | n --------+--- EXISTS | 0 I expected both queries to return the same count. b contains exactly one row, and its column y is not referenced by the predicate. The condition applied to the row from a is the same in both cases: x::real NOT IN (x, 0.7) The difference appears to happen during parsing/type resolution rather than because of the data itself. In the first query, x is a Var of the current query level. In the correlated subquery, it is an outer Var. This appears to cause NOT IN to be represented/resolved differently, with the correlated form potentially using a ScalarArrayOpExpr. This may be related to how transformAExprIn() distinguishes current-level Vars from outer Vars. The value -969514295 makes the difference observable because conversion to real loses precision. No tables, indexes, extensions, custom types, or non-default configuration are required to reproduce the issue.