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 1wbC2q-002Mb1-0U for pgsql-hackers@arkaria.postgresql.org; Sun, 21 Jun 2026 06:52:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wbC2n-002cZK-2W for pgsql-hackers@arkaria.postgresql.org; Sun, 21 Jun 2026 06:52:37 +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.96) (envelope-from ) id 1wbC2n-002cZC-1A for pgsql-hackers@lists.postgresql.org; Sun, 21 Jun 2026 06:52:37 +0000 Received: from mail-ed1-x531.google.com ([2a00:1450:4864:20::531]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wbC2l-00000001P8G-0mfn for pgsql-hackers@postgresql.org; Sun, 21 Jun 2026 06:52:36 +0000 Received: by mail-ed1-x531.google.com with SMTP id 4fb4d7f45d1cf-693c51a8a19so4947180a12.3 for ; Sat, 20 Jun 2026 23:52:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1782024752; cv=none; d=google.com; s=arc-20240605; b=jU3KdyTN36VGw/2vBZBoKFdk9e/t1eZaaSUHWy+Bo78GnQs7ndk8xYln581WTaP21d faynTk/dqieDjoneOq7owiGbyGcVfhdyDLYI3IuUlEHqQUhBMXwbe726Ps/9PrXljbT2 nk2+T12NJUQXKz+n6d0qN4tDVGY89ZnTG1q46b7bX69+IYrVWaCGt/R94VZiwZX/s5ng efQs/IDUsVnWSnVWgWL4Rs0uDUXhI8Vq9agFyXmHxPFlX9XghUx7BrYKpVPVrrCm1aNt Q9I9XdQsFA8bTPZRRFxr0X6nVtQa/1q40+Y+FvB3cos/zZsjRv9tikbSe2lLzOy0wxy6 hg8A== 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=s3/NSP/8wPQ6Sef38SLCX/Mmb/GUKiESKLgIfK2KPsQ=; fh=fDabDMV4fMB7naXNNHc3ul5FlnHHZ+rHdnxS47v9jbA=; b=eqR2pvNRwLsRLCT7si3qr579CKBrE5PF1t0hdMRlRZqEQGlW2O5bhEFUM8ubqvPeDP QgAZdGUuz4FFDFapadmdLyTWVB+qvcMyFpcSNagunp7wvY3FJ2XEa9PMNrLyntgrIuBQ J0mR0J2uTnT2RLvs+osAGrkDa96AeSSx/jeFAMwha6gUfTrO0cHYIEaKzU7imB+ub/91 QE/MMjnJ2/3Gwx5z/ui4+FKRzFyqJoCKU980nufkud5UD1a6mVLeSRY7Gm6uLDMNbBKk 1K6BjX6wmLcDtaVctoQt0zHl7U7OVbzoq62Hmozjjyjhv/sr7wLiaDsLst8iizRQsVQn nOMQ==; 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=1782024752; x=1782629552; 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=s3/NSP/8wPQ6Sef38SLCX/Mmb/GUKiESKLgIfK2KPsQ=; b=Mclzoirg2ZLGEfj1AwtGEMP+wDdfnTfPIfcxOygzPrcsLkU4nn6jTEq233DoJ2GW7C UhUTuTjn5R8qIcV4+e0bWTVGjilyHcJlRZkznysPF6m77AcD7NnHQ7Gxn0ZyJWPjctUJ fhRal6a5Pddb9ZCl+U3wgMZ+YEWBxLeqDwzlERRaD6pmPZgDiLoT+PCso++QYvXxiPXB mBIktGoeMfIPF4gXWed40uqyrdyPh/swlr8rclQVx/WBE6XpwCC0eKNpdCa7YbCf+2BT sWh07DRspUrRHhlSAoiOrnolYWDYV7jw1ITWXufx2ZIJVaI351sT/aP8aXPEAJNJzuZl BULw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782024752; x=1782629552; 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=s3/NSP/8wPQ6Sef38SLCX/Mmb/GUKiESKLgIfK2KPsQ=; b=nu+23fLjP2AK/KgWBb6wWqo5rEAdb9cEOURyn0gtEXsmKTgWmf/iHYDcK7RY4V2nro mqxNRS1Dd3LbUh5o2/sLkGPtI/UmMdRZ//63FXbQLB3RVOjdb3+Tk0qUMj+ec3hPV8Cl crhAJz1LQcOug0HkcWnHFnoPASH1PoRRv9kPA/6uU1E6cTHUXnUvErtfruPImaYrBAZ9 xGQEe5zwyVa4MJZiLwWkLYJCc9HXP8Y7dtsgcgp7WRBBhCS2ErunRugTh2R7v3rIc17N HIqBLsvVTReRq4p2pKWJ0t1kH0sPK//GIbOsLOorXet77nnIwedxsAhNe2LNCH7sahUB DEKA== X-Forwarded-Encrypted: i=1; AFNElJ9DAYkLWT+6tqB6Mzf6dNgNdilmyqxCc5lbH80+SDU0afn+J2yWNrSkWNg2MqsH2pGoTH/WbS3xi3tgKVIC@postgresql.org X-Gm-Message-State: AOJu0YxfCMDao9g2rWvJnUbWbHaLXv6CK60Q/HhRMlEdjv6oC7hIj/gt ebUlvsvD10Vaobs/zXM+Z5sFSN+O9P9aKPfohieDGVpW95O9OslOtCl9TKyTJYkPY6AsZQ23UbV ph7hqUlFunsqGqQHHB8pdsa1cKmu9Y8g= X-Gm-Gg: AfdE7cnyotEDXGDN8sBmSQ+tZZ++SYLbvBRMXESJGsR5e4bWgJKCE2+FhoeDXnO7PF3 8MpOTDxptT0cV3e4vjnuR5io4cHNuyABmhNL8cL5GFuGYymywiliHw4yzl/7csXbGoZTDHfAd5y kKaRdOHZvSsBhyOfutiB2mpqn8x0zk2v1b9E+z+tlcLr/jBw2Xh2jHzoYbUmJksTHVs7jCtuA0K qnPNKoZGiALbOLUGdpPAdcjZ+cTmB+KfOA3O22rHcE6m5Cz6Wsg58z4VtbEWTOxc+FBw476P1v3 MBqAy5JvinCGZz4j4McEX9iYZy0qeEuF8JUm81sb1Q4jkU2W5hA+CI9XgfyAe3jYpuuqH0pL7Wz nqz0GaNjWUr0= X-Received: by 2002:a17:907:3f89:b0:bf0:550:d9f with SMTP id a640c23a62f3a-c0b743ac8e1mr415804266b.31.1782024751968; Sat, 20 Jun 2026 23:52:31 -0700 (PDT) MIME-Version: 1.0 References: <20260620.121719.209332541992434500.ishii@postgresql.org> In-Reply-To: <20260620.121719.209332541992434500.ishii@postgresql.org> Reply-To: assam258@gmail.com From: Henson Choi Date: Sun, 21 Jun 2026 15:52:20 +0900 X-Gm-Features: AVVi8Cf7I9yr2o8j56ShSMWrNj42lpLUElK8wxlUSGgjU6mnjPrfjVQQekctaV4 Message-ID: Subject: Re: Row pattern recognition To: jian.universality@gmail.com Cc: Tatsuo Ishii , 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="0000000000005277130654bdf86a" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000005277130654bdf86a Content-Type: text/plain; charset="UTF-8" > CREATE TABLE stock (company TEXT, tdate DATE, price INTEGER); > CREATE TEMP TABLE stock (company TEXT, tdate DATE, price INTEGER); > SELECT count(*) over w FROM stock WINDOW w AS ( ROWS BETWEEN CURRENT > ROW AND UNBOUNDED FOLLOWING PATTERN (A) DEFINE A AS > pg_temp.stock.price > 0 ); > SELECT count(*) over w FROM stock WINDOW w AS ( ROWS BETWEEN CURRENT > ROW AND UNBOUNDED FOLLOWING PATTERN (A) DEFINE A AS public.stock.price >> 0 ); > SELECT count(*) over w FROM stock WINDOW w AS ( ROWS BETWEEN CURRENT > ROW AND UNBOUNDED FOLLOWING PATTERN (A) DEFINE A AS stock.price > 0 ); > > The error messages for the above 3 SELECT queries are different. > (pg_temp.stock.price, public.stock.price, stock.price) mean the same > thing: column reference, > Should we try to make the error messages consistent? Tatsuo has already covered this one, and I'm with him: I'd keep the three as they are. They come from three different paths -- a schema-qualified reference rejected inside DEFINE, a public.stock that simply isn't the FROM-clause relation, and a range-variable qualification -- so a single message can't describe all three accurately. It's worth saying why beyond "different paths". In the standard a row pattern variable is itself a range variable -- ISO/IEC 19075-5 4.10 has them "used to qualify column references" in MEASURES and DEFINE -- so a qualified name such as A.price denotes the price column at the rows mapped to pattern variable A. That notation collides directly with table/range-variable qualification: A.price and stock.price are spelled identically, and a one-component qualifier is ambiguous between a pattern variable and a relation. Sorting out that ambiguity is precisely what separates the three paths above, which is the other reason I'd keep them distinct rather than fold them into one message now. We don't implement pattern-variable-qualified references yet -- today an unqualified column is implicitly the universal row pattern variable, and that is all DEFINE and MEASURES accept. I'd like to design and build that qualifier support once this commit lands; since it sits right on top of the name resolution you're raising here, I'd genuinely welcome your help with both the design and the implementation, if you're interested. > "Range variable qualified expression" is non-standard that may confuse users. > To improve clarity and consistency, let's align this with the > established error pattern: > > ERROR: invalid reference to FROM-clause entry for table "the_table" "invalid reference to FROM-clause entry for table" only fits the middle case (public.stock); routing (1) and (3) through it would misdescribe them. On the wording, "range variable qualified" is not really non-standard -- it is the standard's own framing, the same one above: a row pattern variable is a range variable, and DEFINE qualification is exactly where that distinction becomes load-bearing once qualifier resolution lands. A generic FROM-clause message would erase the very difference we will need to surface then, so I'd keep the dedicated wording rather than fold it in. > What do you all think about renaming validateRPRPatternVarCount to > preprocessRPRPattern? Agreed the name is too narrow -- besides checking the count against RPR_VARID_MAX, the function collects the unique PATTERN variable names into p_rpr_pattern_vars (the list transformColumnRef uses to spot a pattern-variable qualifier, and for now to reject A.price). preprocessRPRPattern feels too broad, though. Rather than pin a name down now, I'd leave some room: the function's role will shift as the qualifier work lands, so I'll work out a fitting name as I write that patch. > The attached v48-0001 mainly replaces PG_INT32_MAX with > RPR_QUANTITY_INF, but it also includes other changes. > See the commit message for detail. Behavior-neutral and a clear improvement; I'll take it. I'll go through the details closely and fold in any fixups as I write the patch. > The attached v48-0002 patch is more about miscellaneous refactoring. > [...] > Refactor buildRPRPattern to accept a WindowClause pointer directly. > [...] > collectDefineVariables is not needed [...] Also removed tryUnwrapSingleChild > [...] > Slightly adjust variable limits error message. Also good. The helper inlining and the WindowClause signature both read as clear wins; I'll sort out the variable-limit message wording and the rest of the small details as I fold it. Thanks again for the careful work. Best regards, Henson --0000000000005277130654bdf86a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
> CREATE TABLE stock (company TEXT, tdate DATE, price I= NTEGER);
> CREATE TEMP TABLE stock (company TEXT, tdate DATE, price I= NTEGER);
> SELECT count(*) over w FROM stock WINDOW w AS ( ROWS BETWE= EN CURRENT
> ROW AND UNBOUNDED FOLLOWING PATTERN (A) DEFINE A AS
&= gt; pg_temp.stock.price > 0 );
> SELECT count(*) over w FROM stock= WINDOW w AS ( ROWS BETWEEN CURRENT
> ROW AND UNBOUNDED FOLLOWING PAT= TERN (A) DEFINE A AS public.stock.price
>> 0 );
> SELECT cou= nt(*) over w FROM stock WINDOW w AS ( ROWS BETWEEN CURRENT
> ROW AND = UNBOUNDED FOLLOWING PATTERN (A) DEFINE A AS stock.price > 0 );
>> The error messages for the above 3 SELECT queries are different.
= > (pg_temp.stock.price, public.stock.price, stock.price) mean the same> thing: column reference,
> Should we try to make the error mes= sages consistent?

Tatsuo has already covered this one, and I'm w= ith him: I'd keep the three
as they are.=C2=A0 They come from three = different paths -- a schema-qualified
reference rejected inside DEFINE, = a public.stock that simply isn't the
FROM-clause relation, and a ran= ge-variable qualification -- so a single
message can't describe all = three accurately.

It's worth saying why beyond "different p= aths".=C2=A0 In the standard a row
pattern variable is itself a ran= ge variable -- ISO/IEC 19075-5 4.10 has them
"used to qualify colum= n references" in MEASURES and DEFINE -- so a qualified
name
such= as A.price denotes the price column at the rows mapped to pattern
varia= ble A.=C2=A0 That notation collides directly with table/range-variable
q= ualification: A.price and stock.price are spelled identically, and a
one= -component qualifier is ambiguous between a pattern variable and a
relat= ion.=C2=A0 Sorting out that ambiguity is precisely what separates the three=
paths above, which is the other reason I'd keep them distinct rathe= r than
fold them into one message now.

We don't implement pat= tern-variable-qualified references yet -- today an
unqualified column is= implicitly the universal row pattern variable, and
that is all DEFINE a= nd MEASURES accept.=C2=A0 I'd like to design and build that
qualifie= r support once this commit lands; since it sits right on top of the
name= resolution you're raising here, I'd genuinely welcome your help wi= th
both the design and the implementation, if you're interested.
=
> "Range variable qualified expression" is non-standard th= at may confuse users.
> To improve clarity and consistency, let's= align this with the
> established error pattern:
>
> ERR= OR: invalid reference to FROM-clause entry for table "the_table"<= br>
"invalid reference to FROM-clause entry for table" only fi= ts the middle
case (public.stock); routing (1) and (3) through it would = misdescribe them.
On the wording, "range variable qualified" i= s not really non-standard -- it
is the standard's own framing, the s= ame one above: a row pattern variable
is a range variable, and DEFINE qu= alification is exactly where that
distinction becomes load-bearing once = qualifier resolution lands.=C2=A0 A generic
FROM-clause message would er= ase the very difference we will need to surface
then, so I'd keep th= e dedicated wording rather than fold it in.

> What do you all thi= nk about renaming validateRPRPatternVarCount to
> preprocessRPRPatter= n?

Agreed the name is too narrow -- besides checking the count again= st
RPR_VARID_MAX, the function collects the unique PATTERN variable name= s into
p_rpr_pattern_vars (the list transformColumnRef uses to spot apattern-variable qualifier, and for now to reject A.price). =C2=A0preproce= ssRPRPattern
feels too broad, though.=C2=A0 Rather than pin a name down = now, I'd leave some
room: the function's role will shift as the = qualifier work lands, so I'll
work out a fitting name as I write tha= t patch.

> The attached v48-0001 mainly replaces PG_INT32_MAX wit= h
> RPR_QUANTITY_INF, but it also includes other changes.
> See= the commit message for detail.

Behavior-neutral and a clear improve= ment; I'll take it.=C2=A0 I'll go through the
details closely an= d fold in any fixups as I write the patch.

> The attached v48-000= 2 patch is more about miscellaneous refactoring.
> [...]
> Refa= ctor buildRPRPattern to accept a WindowClause pointer directly.
> [..= .]
> collectDefineVariables is not needed [...] Also removed tryUnwra= pSingleChild
> [...]
> Slightly adjust variable limits error me= ssage.

Also good.=C2=A0 The helper inlining and the WindowClause sig= nature both read as
clear wins; I'll sort out the variable-limit mes= sage wording and the rest of
the small details as I fold it.

Than= ks again for the careful work.

Best regards,
Henson
--0000000000005277130654bdf86a--