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.96) (envelope-from ) id 1w0UAQ-001wnM-0v for pgsql-hackers@arkaria.postgresql.org; Thu, 12 Mar 2026 00:44:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w0UAO-00Cheu-2P for pgsql-hackers@arkaria.postgresql.org; Thu, 12 Mar 2026 00:44:45 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w0UAO-00Chem-1Q for pgsql-hackers@lists.postgresql.org; Thu, 12 Mar 2026 00:44:44 +0000 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w0UAM-00000002Dnb-35pq for pgsql-hackers@postgresql.org; Thu, 12 Mar 2026 00:44:44 +0000 Received: by mail-pg1-x531.google.com with SMTP id 41be03b00d2f7-c70f91776fcso175846a12.0 for ; Wed, 11 Mar 2026 17:44:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1773276280; cv=none; d=google.com; s=arc-20240605; b=FdPvaiw/J5nsihdGb5cL9U7Yfe2xNykVaXOdOqkHNaNzoQkZzO7MdW6agvBjF9xp5E BLGeC1E/sea8RI7eXii4vGpz8jih3NfQBjrpjO9/RYiA7D6bidO8mRge7NG2r262hWQ5 x4lwHmvVwiyvamJiRvBhcR7nc2FJWx4+PJTRIwRNZ/kTWYhgyJthxyojRDYijiPXHSBi UIqs0Q5qb+6q6oJP9JCbDmqcVmeuxB+GpFKA5GVcCW7ZTQ36Qlcp92n4+BHBrzlLEYqb nv4LlQ4kTghXJ1rjG7YjtTxEdYphqOuBd0JOzXXpudWnlmg/Ji1YW46dUWnSIK3tXrhC vO2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:dkim-signature; bh=hkfxIjz4EN8GXgmFfVdYuGpMTF224S1cDmrA7nMFbQc=; fh=9A+6BXz7AddaGikfcWzR7c5UqohKyoCYtV9/0xZQ2u0=; b=SSn7OcFIJ4RdEoOxZPwd/Br36rWP3w32dbSBLdnQTPWXlFNJX+iwGDj+b44xcTT1MN bSq9xA1NrROwoCGmoYSBnuRq/zLTTW1k1EdzHEtHKTZeK7PBnayJuJpHofctVpex3+uN qZ3PxdwS+j+H1uWr+ns36OuZBkBFsA9LpqQh5lqVwO2GLJsbtfTBkTFGrS0JBmETMYih SiwEdqKDIkpJhY6r6reaqDMuAskz29gpCbzA89chMN7MNBRddd4r3i5La+kHP+xHH0Ir iLT/u+HBk3yn4u7pW2XRJJoPS6aKyMVl1+1wqmR1VHJaQGAdaSme8LeZONV/h8Q6eeh9 9exA==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773276280; x=1773881080; darn=postgresql.org; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=hkfxIjz4EN8GXgmFfVdYuGpMTF224S1cDmrA7nMFbQc=; b=RyVNy2D29vjSUzD5x6boXaask2a92Fs9YIumWU2Iqnxlw10R+g9YxJUgpa+d1wvsJ7 JHmbToZ456gjpqpqScXHKio2AAiWthyZX+mpwVcTYkvAJg1HPNIecqQ/O1A7fBhQHVOP izx7vWCSvlBQzhKIg3+zf+b5Ect4rGZZP73dHw9JXH2fs4Kssakh6YjIHuLbuI8Kj7Jd S9WBrcgVAAVpTolLg+ZBXxjOCMoDoICQZ9b9IW4ELNDPW+B9oD0KBCO2kIXHVKekEx0a kQvXYIlOmE1VPG9pO0/alewbS+3aG2SLhih/f3EvXwEuHXudpTBrJfUrUGwvj7LZvi35 /VvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773276280; x=1773881080; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=hkfxIjz4EN8GXgmFfVdYuGpMTF224S1cDmrA7nMFbQc=; b=DreLEQghryN38w5cZHuIROOVcDrbAIcgNPgv5cf3/u+Lu1urrNUIcaLakNiDacYxB+ ZJUHgmFwQyo316jZrkhjQyoJT9PSYY/7j1RRBnvvrlZq43D/ZKXJAE0xcnauCk2RO+aR xMhOs1H1LATt0IPo0YocpEypRjYUw49Uddr28HF2XCKRqKV9GGjH/vF4Kt4X/0qJAwl6 zalvN6inFQPdVdfJDHEl7+XrbRDl+8TYumwWQ8q7xE2aUwws2TnYwkJ+fD8kD16ddQOR xHKkBPp1LiltF2UqKERuTMtymu75tWy5kDDR5higN7W409JSJk+F9UREJ/D3XZoHZdsR 25ng== X-Forwarded-Encrypted: i=1; AJvYcCUttzj7AP5uGm72dkBlxArlGkhBWoC9XqeQ8Oz4GXynkU6Nr/ClkjqgUQbuXUCHl45rW201hG8Hsvew3D47@postgresql.org X-Gm-Message-State: AOJu0YxDgHPOPNthMeeAKbSZNJ7VPhb+zhoGQd9xwl1Rsp+wKvQtESon Ldr82gTWXC3iPJPbWR8lAoJuBzn4EekTrO29tupsh6qFRCVRzV4TVUzSSxOEBhQHrgUBgZ5LZSh 265I5G1oo2R1RFb5V2s1If3fXNNVE1h4= X-Gm-Gg: ATEYQzxG78PQ4mQxm3sFcAosdP9lU6hk8PnTR20vXahv4cPQlpuqawLyESDkzGj1aFA ig1dJrtdbDwcno7PFBBd4+K48s9jCjxe7HybNPySxeusThG+7Y/EXZB7U4vUBYOO48UMhv1e4FW QzIfKg6VOX34jbSzOTQ0wvCyprLAwRT8zWwF0+3sDaymfyUoBjnY/pqudj7BCPDQrsxG03uYME8 KKUAKlHxev6rXL2r5D1yqVPvezzwXq0clKT7xNMW+u+Oqler5n0dOxOzSmKrXEsCUMR+BD57zJU F8UW+p2HElGgcTg7qNwYm7eljdJk/6XrUEAywE8= X-Received: by 2002:a17:902:ea11:b0:2ae:b991:a46f with SMTP id d9443c01a7336-2aeb991a868mr18366095ad.42.1773276280380; Wed, 11 Mar 2026 17:44:40 -0700 (PDT) MIME-Version: 1.0 References: <20260302.141823.129040280886273031.ishii@postgresql.org> <20260312.092125.2016894123875469735.ishii@postgresql.org> In-Reply-To: <20260312.092125.2016894123875469735.ishii@postgresql.org> Reply-To: assam258@gmail.com From: Henson Choi Date: Thu, 12 Mar 2026 09:44:29 +0900 X-Gm-Features: AaiRm526mCo1ptB5hoQooiNjbaCHuxZGI6BbHbdjo-w1bnlNuRmcgZjb9uKzEh8 Message-ID: Subject: Re: Row pattern recognition To: Tatsuo Ishii Cc: zsolt.parragi@percona.com, vik@postgresfriends.org, er@xs4all.nl, jacob.champion@enterprisedb.com, david.g.johnston@gmail.com, peter@eisentraut.org, pgsql-hackers@postgresql.org Content-Type: multipart/alternative; boundary="000000000000c7e06a064cc90ecb" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000c7e06a064cc90ecb Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Tatsuo, Sorry about the empty reply =E2=80=94 sent it by accident. Yeah, current patch needs to be fixed. Question is, the output of the > expression of DEFINE clause must be a strict boolean or, it is allowed > to accept an expression coercive to boolean? > > If we prefer the former, we should use exprType() instead. > Good question. Both the SQL standard and PostgreSQL's existing behavior point toward allowing coercion. In the SQL standard (ISO/IEC 19075-5), DEFINE specifies a "Boolean condition" for each pattern variable. The standard does not suggest a stricter type requirement on DEFINE than on other boolean contexts like WHERE or HAVING. PostgreSQL's WHERE clause already accepts implicit casts to boolean via coerce_to_boolean(). You can verify this with Zsolt's setup: CREATE TYPE truthyint AS (v int); CREATE FUNCTION truthyint_to_bool(truthyint) RETURNS boolean AS $$ SELECT ($1).v <> 0; $$ LANGUAGE SQL IMMUTABLE STRICT; CREATE CAST (truthyint AS boolean) WITH FUNCTION truthyint_to_bool(truthyint) AS ASSIGNMENT; CREATE TABLE test_coerce (id serial, val truthyint); INSERT INTO test_coerce VALUES (1, ROW(1)), (2, ROW(0)), (3, ROW(5)), (4, ROW(0)); SELECT id, val FROM test_coerce WHERE val ORDER BY id; -- returns rows 1 and 3 (where val casts to true) As Zsolt noted, the same query works correctly with an actual boolean column. The issue is specifically that the implicit cast is not being applied. All other boolean contexts in the parser (WHERE, HAVING, JOIN/ON, WHEN, etc.) use coerce_to_boolean() and assign the result back. I think DEFINE should be consistent with these =E2=80=94 it would be surprising if `DEFINE A AS val` rejected a type that `WHERE val` accepts. Regards, Henson --000000000000c7e06a064cc90ecb Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Tatsuo,

Sorry about the empty reply =E2=80=94 sent it by acciden= t.

Yeah, current patch needs to be fixed. Question is, the output of the
expression of DEFINE clause must be a strict boolean or, it is allowed
to accept an expression coercive to boolean?

If we prefer the former, we should use exprType() instead.
=

Good question. Both the SQL standard and PostgreSQL's ex= isting
behavior point toward allowing coercion.

In the SQL standa= rd (ISO/IEC 19075-5), DEFINE specifies a "Boolean
condition" f= or each pattern variable. The standard does not suggest
a stricter type = requirement on DEFINE than on other boolean contexts
like WHERE or HAVIN= G.

PostgreSQL's WHERE clause already accepts implicit casts to b= oolean
via coerce_to_boolean(). You can verify this with Zsolt's set= up:

=C2=A0 =C2=A0 CREATE TYPE truthyint AS = (v int);
=C2=A0 =C2=A0 CREATE FUNCTION truthyint_to_bool(truthyint) RETU= RNS boolean AS $$
=C2=A0 =C2=A0 =C2=A0 SELECT ($1).v <> 0;
=C2= =A0 =C2=A0 $$ LANGUAGE SQL IMMUTABLE STRICT;
=C2=A0 =C2=A0 CREATE CAST (= truthyint AS boolean)
=C2=A0 =C2=A0 =C2=A0 WITH FUNCTION truthyint_to_bo= ol(truthyint)
=C2=A0 =C2=A0 =C2=A0 AS ASSIGNMENT;

=C2=A0 =C2=A0 C= REATE TABLE test_coerce (id serial, val truthyint);
=C2=A0 =C2=A0 INSERT= INTO test_coerce VALUES
=C2=A0 =C2=A0 =C2=A0 (1, ROW(1)), (2, ROW(0)), = (3, ROW(5)), (4, ROW(0));

=C2=A0 =C2=A0 SELECT id, val FROM test_coe= rce WHERE val ORDER BY id;
=C2=A0 =C2=A0 -- returns rows 1 and 3 (where = val casts to true)

As Zsolt noted, the same query works corre= ctly with an actual
boolean column. The issue is specifically that the i= mplicit cast
is not being applied.

All other boolean contexts in = the parser (WHERE, HAVING, JOIN/ON,
WHEN, etc.) use coerce_to_boolean() = and assign the result back.
I think DEFINE should be consistent with the= se =E2=80=94 it would be
surprising if `DEFINE A AS val` rejected a type= that `WHERE val`
accepts.

Regards,
Henson
=C2=A0
--000000000000c7e06a064cc90ecb--