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 1wStjM-000BIl-1l for pgsql-hackers@arkaria.postgresql.org; Fri, 29 May 2026 09:42:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wStjJ-002AQH-1v for pgsql-hackers@arkaria.postgresql.org; Fri, 29 May 2026 09:42:13 +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 1wStjJ-002AQ5-0h for pgsql-hackers@lists.postgresql.org; Fri, 29 May 2026 09:42:13 +0000 Received: from mail-ej1-x635.google.com ([2a00:1450:4864:20::635]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wStjH-000000007Cm-1ldX for pgsql-hackers@postgresql.org; Fri, 29 May 2026 09:42:13 +0000 Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-bd85ebb368fso2038577166b.1 for ; Fri, 29 May 2026 02:42:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1780047726; cv=none; d=google.com; s=arc-20240605; b=kHiT2Inp0mm80B8pNb7Rr6gMtTwMqHeS/tLv6zFxmH62V+m5M3rl8LU5ZorD29TrkL GGzdkvu+qSviA4UMrM3Q/7hmzt2yz/vvTHGcoxuLaUZNXp3pK7EyE2D2WWqWM5auDnbS egsiFp8I/X0coNCyAJzx+YNqeG+nSc7VhAOXGRZJh3PWrgOzbQvpRY3dRVt53LKIR8eX QaZk2lf61iNldnKxALeGHZsu93ak0PU9areSAQACGAGb5tqpKL9w9W0CmeIFGZjJjcPV n/SfpgEBLt9jVRB+r1p9nC86RAOiDh6sqU5dZpl9xJ/deR0yh0KI2mV4EZI35EX/Gc05 BepA== 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=WSzlT/k8q74BFEPxq7usNScIeMr4sD1Lvx3J3lkwxVI=; fh=iK5eC2WVfgZWGCsKAW4ja/7qff8PSUjVD7YRH2cy3j8=; b=Kg1PBhnM8jIkuZqJlkWmSXT/aqqOX+cHkl8B89OlEpnD5akZVujnjKknCmwBartb6x G/LRn77GUMAiM18ZqnbbiJMcnyuikpV5j5OdCGTUFOZAFZMTS3ny1zejZGA1GAHTvzqK Wfl6fp4m9uG/wFXe1FdBa4v9medsC9ARVxsJIZVhgDD8sqzM0lzBauMs75+FyyVGt4Z+ CDb18uOaEqKyeWax4UkNHqW2kVatfWH3eJa7vifQv6Ak6g6A1Q4dQA/LvRVH7NTaWT5d bp6dO//BSbrVdPBnqy/ItaTNlt62ut2Pgol7y/1wW91bgkBLHWM3i5U3jj1TAcZCXSzR cmnA==; 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=20251104; t=1780047726; x=1780652526; 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=WSzlT/k8q74BFEPxq7usNScIeMr4sD1Lvx3J3lkwxVI=; b=NVoVSIAt+NXdXPRTu8/ZP6KvdXLE3JUfSMQLMHRlP/u88ZloWiSimVwgCc6gIPCKrM cOrjYbhdna7zEPdTI8HCH6JHpBeWCYCIy6UW1cIYDquAlqDQn/pn/GreMUNwUOoE/N/u Pvlxj5+k1bC0smQ58gjcLw2eeVe4nnSEvxYStaGte2chLItOGNyRDE3AfBLsDKTYVoE+ qpGbdK3WFZyck3DxvpGhxKMSC9T0k31s2xESzmaY/w9S40hZUbS6wa9e7X11ZvTgJkKX akVeYhi182P+JNpAsX7iIZepr6F5zJUTf5uv2dWcq9eaSz4B/5lqDc8XKW8c9KERl6gK BwxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780047726; x=1780652526; 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=WSzlT/k8q74BFEPxq7usNScIeMr4sD1Lvx3J3lkwxVI=; b=rCLhQETCHxYV4lB7/j2An04rZVxbHuI1JBXenel4cWh5PlujM9wqD+8y6UXeFC3zMZ 5p1zDYi9Sq/BACnRle4OENVvcAzFx59hpi9OD2OgS5/h3tmd38YBXO4NWhMD8gWjBgl7 dRM9l5jhhAKA7rqb6oGrxTWamH/7Lybrm2l5l2aAGpA8qZsHSFWQRR1Q2yVmwlEVHCWM ji8f3kuKRKwpv1pz7VbaJPd1bpYc/zQmnHpKOgHJgnUzS5qnLupP9+KbVG4FY9kIVi7K LQQd4JmhYhVSQfYHuwxIbffHUfMu4klejGcNQYk5U+WGiWY3044FUOfAWats/y61CoFH 4lNQ== X-Forwarded-Encrypted: i=1; AFNElJ8CpY2pasPUaqpybpIwrlTdew3Mlr+lS9P5gLhM2NAuKUmqrB/VZfEFe6H638C/DTt3sD16h5bQLWYqSppF@postgresql.org X-Gm-Message-State: AOJu0Yw63qsrLRlVcpNv6f8NCgpA2d+rrQstavCa7leY1O13TGET8HUF w3a2I31Llk6uIv5QmpJizfWJ+96qKcpk0vtiTTTZbi6q24YImeOgi09TzCLg4b0ddPOEROuykbD CqXPwbApxAPG5zLgLucVG0DTwOfDZ66g= X-Gm-Gg: Acq92OG1k3xsC+TCOVFexux/reCFjh9B9BWQlYB3hyFWQTLtLT12z4ZM05a3hJCCCRK ukR/tZZHNuxZq3RYe7MkBH3EN8HigwZ5Fn9k3Pa/W4yCzKnPvLIPpoya4SXRb7BVUMCwsxe2buJ 0yTPJmZlruMTp55Nw3qDfYSoT/aHqKwy5a2faXRjudcl93cACNE5mE3adKSTL1xxS2hCWbBMDma UJ9WvYYIHUNcwt/x+56+3+/6GOyOD0OiEbYLMIxqKZAom2O5Uop1stZLU3/OO9GRMwNDkSpy2oi 0vYaE6hyKmHdAgcDgO3zfECRK7XV5u4fTi9FoVyMky6C4FUHGBU= X-Received: by 2002:a17:907:60ca:b0:bd8:f771:ea9a with SMTP id a640c23a62f3a-be9cb9cb1f1mr108111466b.41.1780047725324; Fri, 29 May 2026 02:42:05 -0700 (PDT) MIME-Version: 1.0 References: <20260502.140304.670813149418899420.ishii@postgresql.org> <20260505.090124.365339750969814137.ishii@postgresql.org> <20260517.190023.159085681032648582.ishii@postgresql.org> In-Reply-To: Reply-To: assam258@gmail.com From: Henson Choi Date: Fri, 29 May 2026 18:41:52 +0900 X-Gm-Features: AVHnY4KEkkmBYiBMO0L9SCkNqTiCo8pk9A5WjfIF8vWAplFmRMkmWl8rppDO8aw Message-ID: Subject: Re: Row pattern recognition To: jian he , Tatsuo Ishii Cc: zsolt.parragi@percona.com, sjjang112233@gmail.com, vik@postgresfriends.org, er@xs4all.nl, jacob.champion@enterprisedb.com, david.g.johnston@gmail.com, peter@eisentraut.org, li.evan.chao@gmail.com, pgsql-hackers@postgresql.org Content-Type: multipart/alternative; boundary="00000000000059ecd80652f1a8bf" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000059ecd80652f1a8bf Content-Type: text/plain; charset="UTF-8" Hi Jian, Tatsuo, Jian, your review keeps paying off beyond the items themselves. Working through the ExecRPRProcessRow refactor you proposed -- dropping hasLimitedFrame and fixing the "endOffsetValue != 0" Datum-vs-0 comparison -- and writing the offset-0 regression test it calls for sent me back to the standard, where I hit a conformance reading I'd value both of your judgments on. The case is the single-row full window frame. It has two spellings, semantically identical -- both make the full window frame exactly the current row: ROWS BETWEEN CURRENT ROW AND CURRENT ROW ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING PostgreSQL accepts both today (rpr_base tests the 0 FOLLOWING form with PATTERN (A)). But I'm no longer sure either is sanctioned by Subclause 6.10.2, "ROWS BETWEEN CURRENT ROW AND", which reads (paraphrasing ISO/IEC 19075-5): "When performing row pattern recognition in a window, only two options are allowed for specifying the window frame extent: - ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING - ROWS BETWEEN CURRENT ROW AND offset FOLLOWING ... [the offset] shall be a positive integer ..." Two things put the single-row frame outside a literal reading, and they hit both spellings equally: - CURRENT ROW as the *end* bound is not one of the two listed options; and - the offset form requires a *positive integer*, and 0 is not positive -- so AND 0 FOLLOWING is no better sanctioned than AND CURRENT ROW. The two spellings therefore stand or fall together: they denote the same one-row frame, and neither is literally among 6.10.2's options. (README.rpr X-4 already follows the strict line -- it lists only "UNBOUNDED FOLLOWING or n FOLLOWING".) Either way the behavior is unambiguous: a single-row search space, so the pattern can only ever map the current row. That makes it a degenerate, WHERE-like use rather than real row-pattern matching -- which one might read as benign (so allow) or as pointless (so reject), so it doesn't settle the question for me. This is, in effect, a borderline, harmless standard violation: it sits just outside 6.10.2 as written, yet is well-defined, runs cleanly, and leaves every conforming frame unchanged. So, concretely, the choice: (a) Allow it -- accept both spellings and document the degenerate frame as a deliberate extension; or (b) Forbid it -- follow 6.10.2 to the letter ("only two options" and a "positive integer" offset) and reject both spellings in transformRPR(). Which reading do you take? Tatsuo, as co-author your call carries it; Jian, I'd value yours too, since you were just in this code. This isn't blocking. The implementation accepts offset 0 today, so for now my regression test exercises it (via the 0 FOLLOWING spelling, as rpr_base already does); if the answer is (b), that test and the existing one become error tests together. Thanks, Henson --00000000000059ecd80652f1a8bf Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Jian, Tatsuo,

Jian, your review keeps paying off= beyond the items themselves.=C2=A0 Working
through the ExecRPRProcessRo= w refactor you proposed -- dropping
hasLimitedFrame and fixing the "= ;endOffsetValue !=3D 0" Datum-vs-0
comparison -- and writing the of= fset-0 regression test it calls for sent
me back to the standard, where = I hit a conformance reading I'd value both
of your judgments on.
=
The case is the single-row full window frame.=C2=A0 It has two spelling= s,
semantically identical -- both make the full window frame exactly the=
current row:

=C2=A0 =C2=A0 ROWS BETWEEN CURRENT ROW AND CURRENT = ROW
=C2=A0 =C2=A0 ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING

Postgr= eSQL accepts both today (rpr_base tests the 0 FOLLOWING form with
PATTER= N (A)).=C2=A0 But I'm no longer sure either is sanctioned by Subclause<= br>6.10.2, "ROWS BETWEEN CURRENT ROW AND", which reads (paraphras= ing
ISO/IEC 19075-5):

=C2=A0 "When performing row pattern re= cognition in a window, only two options
=C2=A0 =C2=A0are allowed for spe= cifying the window frame extent:
=C2=A0 =C2=A0 =C2=A0- ROWS BETWEEN CURR= ENT ROW AND UNBOUNDED FOLLOWING
=C2=A0 =C2=A0 =C2=A0- ROWS BETWEEN CURRE= NT ROW AND offset FOLLOWING ... [the offset]
=C2=A0 =C2=A0 =C2=A0 =C2=A0= shall be a positive integer ..."

Two things put the single-row = frame outside a literal reading, and they
hit both spellings equally:
=C2=A0 - CURRENT ROW as the *end* bound is not one of the two listed o= ptions;
=C2=A0 =C2=A0 and

=C2=A0 - the offset form requires a *po= sitive integer*, and 0 is not positive
=C2=A0 =C2=A0 -- so AND 0 FOLLOWI= NG is no better sanctioned than AND CURRENT ROW.

The two spellings t= herefore stand or fall together: they denote the same
one-row frame, and= neither is literally among 6.10.2's options.
(README.rpr X-4 alread= y follows the strict line -- it lists only
"UNBOUNDED FOLLOWING or = n FOLLOWING".)

Either way the behavior is unambiguous: a single= -row search space, so the
pattern can only ever map the current row.=C2= =A0 That makes it a degenerate,
WHERE-like use rather than real row-patt= ern matching -- which one might
read as benign (so allow) or as pointles= s (so reject), so it doesn't
settle the question for me.

This= is, in effect, a borderline, harmless standard violation: it sits
just = outside 6.10.2 as written, yet is well-defined, runs cleanly, and
leaves= every conforming frame unchanged.

So, concretely, the choice:
=C2=A0 (a) Allow it -- accept both spellings and document the degenerate<= br>=C2=A0 =C2=A0 =C2=A0 frame as a deliberate extension; or

=C2=A0 (= b) Forbid it -- follow 6.10.2 to the letter ("only two options" a= nd a
=C2=A0 =C2=A0 =C2=A0 "positive integer" offset) and rejec= t both spellings in
=C2=A0 =C2=A0 =C2=A0 transformRPR().

Which re= ading do you take?=C2=A0 Tatsuo, as co-author your call carries it;
Jian= , I'd value yours too, since you were just in this code.

This is= n't blocking.=C2=A0 The implementation accepts offset 0 today, so fornow my regression test exercises it (via the 0 FOLLOWING spelling, as
= rpr_base already does); if the answer is (b), that test and the existingone become error tests together.

Thanks,
Henson
--00000000000059ecd80652f1a8bf--