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 1wXXc8-003Jzj-24 for pgsql-hackers@arkaria.postgresql.org; Thu, 11 Jun 2026 05:06:00 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wXXc7-00EKHj-13 for pgsql-hackers@arkaria.postgresql.org; Thu, 11 Jun 2026 05:05:59 +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 1wXXc6-00EKHa-3D for pgsql-hackers@lists.postgresql.org; Thu, 11 Jun 2026 05:05:59 +0000 Received: from mail-ej1-x62f.google.com ([2a00:1450:4864:20::62f]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wXXc4-00000002Sp8-38pY for pgsql-hackers@postgresql.org; Thu, 11 Jun 2026 05:05:58 +0000 Received: by mail-ej1-x62f.google.com with SMTP id a640c23a62f3a-beeba001887so1001129966b.3 for ; Wed, 10 Jun 2026 22:05:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781154355; cv=none; d=google.com; s=arc-20240605; b=gX5OvN8P87uXK4FihvwFtrybbNj3nUwjFEVxq25echJ+cYrqm8SUmXTFbqpk7CluEU DiyQ1ukVdabu+1/1KXyI0BQQbLzk7387Qfgpz0oL3WH8EBZeJ1IUdG62YdlU5/LdOjvG /9CDSOB8htZpmvcSlbY3fPtlaqHwowzB+din+eK3kO72VCS+39WNYw/rIKwWvOqaba8O SIYBkO9wFEbqcoHm6KZDplBTKucejZFCe+KZoCrRPTECxjsASb6YWnnTBJQx5ciBRUNT BaEa1iAlcs+zBp+gV8AnLWEScjlirgSjjhBR32ubTZn5SF1M1ELzxuP7tecw97OuIBma eunA== 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=CVQOKWpzLbPCqprOrKko3sD2NhEZAgPeAQ0yHruLSEw=; fh=4ba9bBzLR2hCh61Zkv4F1yyZ8RzJ/YEiVKhu3hxpLzo=; b=atzkL5w5j65CkXDZZPii70cC5PjOmxoiDracy7ATrmLz/W6aKJdzr2zlnBEx1zAe+/ taepdi0+AKw/FHB2r3hXWYVYv6i93O5weYHReZ4tJNooTLJcaTgqmdjBQ5e9TquFki+D FL3Z2UrNv9gDXJcj+FBRGNCoVS62ommVJZJiukQ0ku9fIBhaSsBol4tVJYaej7WAX+68 99WCqILI7mb+AEblO4/plQ8oG7Tyc+J+7apykdmS+dckXBRCqSyXKi2BS7BEhQnQVC4J PMj/cn8mRom+vmGE8r8RNxp03iUgt6/stw0b2wCUvyQFeSqVEiC87UbMMsDV1EhTOE/i 0BFQ==; 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=1781154355; x=1781759155; 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=CVQOKWpzLbPCqprOrKko3sD2NhEZAgPeAQ0yHruLSEw=; b=PpMFNWGRHaK7lwlW8BCOURD5dsI23aVgDzYUWrLFOZ3aQ8EM+bDpKY5MN/x8lLIPMS 3oEck6GP1nU9VJHd0VAZiIoGyVNawp8UVg8N0NJHE+/R0+UQ0EDayRgHCzf5mNMn7SYw /nx899SBlAmjd9kqqResnNZn2iIcXt+4nC760eE7B+6avPRhQM3pFErQwS5l+tj1TJWq ZUdL/k9NWoiXZUTw0kDRAFOr76IyUct1TWEUIuWddZIh1j0KhhpdlNr9fLtAFqQG1DUi QnPMht0Z/YTCJaGTpM1JdVkRcPHR70YjsWF8va9s08kk9DjQnFSJB7ymBWjgT6LtyGCf jsHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781154355; x=1781759155; 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=CVQOKWpzLbPCqprOrKko3sD2NhEZAgPeAQ0yHruLSEw=; b=kiJqZKgCmN6oAn2qBD/sOHZyD7Vo20Z6l8sNEBGyHINvzOn30Py5PgeHVDN5F2lItF hMRAy8WnxWNEvITaLhVnL0ccRqNyN3uTtU/hRBz+G817NAPvlEP4fJFxMbJl7/gv242E /n1ULRPP43tybFqx/y4jlPokBOECrHaqtVnASGnqBkCCdfgKNv8zy7kP7/iOOSOxZW+j uFNweYAwoOpe0vlqj4uqUqHBmPM8xlentp7MRLHCYHHDf2N4DUIWVy6NS8LsytZTgKfd cP8SYinLQvDvnSG0UAIvhaUbThO6A+YmA1IV9plS3Zg8eDe+aJQj1jJgqxdGIQqxkuil wp2A== X-Forwarded-Encrypted: i=1; AFNElJ8oI1Jy/3tkEionVnqOHMqsNlSaBIdSEPAl0f4Yg3sTcnLPX4ngLp3uybZG25NlueRnNBG74RbNLSVpHKbv@postgresql.org X-Gm-Message-State: AOJu0YxA6soFBw18zcEdhjwe8ixW4uo+5A6QbWKGHREaq+jNWBMXBlul +Q3DH8poWA6bcqpn1bLRHerj/maDRlygXGhRc3TMzVoOj4Yz9hRMT8cIRPgEzQO4h4auH3G0CPo eLFCRTxdzVIXY7gEsgkHv6GL9UflmIY4= X-Gm-Gg: Acq92OGXRiAm/h/uOpruRQrM6tIEsVkXQssqAUXEHhBqCfzxXTF9kZ70AylLYb7tTaK m70I7CcW+jnE20v+T9jX7FR/mI5E1/KA0mnja0oZmSJdtt7MESKdZ5WMB1Mt1D/FRqbSmIEo+HX pwxQP2XnVdWdFpqVXM9XLvEaFRKFA0hMyZlKBqO9NGM1H5MgyQRHMn9hyrO5Nu+3Rl8UZaLuF1e SYnxC761vcibTbcnwv+wWZsx5QoeDSnQTtL7Ft8kM9uPmY9hZfvG0xa0LgfR9wGF9eYrXO6Gzr4 77yICfo3PgQtagBMSUYtmiq2Ntryswme2QJs/2zmXsMXetLoNY5gcToPQpnb2VAqfsLsYabl59I tZxH1w3y5rhxkf9DVcYap78nylKfURfgF X-Received: by 2002:a17:906:c10b:b0:bec:2d9f:2aa7 with SMTP id a640c23a62f3a-bfc87c0eef8mr39468766b.24.1781154354755; Wed, 10 Jun 2026 22:05:54 -0700 (PDT) MIME-Version: 1.0 References: <20260604.132108.405136284364833955.ishii@postgresql.org> <20260609.171307.1883356507067957349.ishii@postgresql.org> In-Reply-To: Reply-To: assam258@gmail.com From: Henson Choi Date: Thu, 11 Jun 2026 14:05:42 +0900 X-Gm-Features: AVVi8Cfw0xC2WQVPH6oS-E_qdCqUlSMTAAmOVQv9bTyTD1Fs34m3uI75rp7MymY 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="0000000000009afd3d0653f350a5" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000009afd3d0653f350a5 Content-Type: text/plain; charset="UTF-8" Hi Jian, On Wed, Jun 10, 2026 jian he wrote: > SELECT first_value(1); > ERROR: window function first_value requires an OVER clause > LINE 1: SELECT first_value(1); > ^ > > select prosrc, prokind, proname from pg_proc > where proname = 'prev' or proname = 'first' or proname = 'last' or > proname = 'next'; > > I am wondering, why the above query result functions not marked as > window function in catalog? The short answer is that no catalog marking can fix this, because prokind does not take part in name resolution. func_get_detail() picks the candidate by name/arguments/search_path first, and prokind (window or not) is only inspected afterwards. So marking the placeholders as window functions would leave all three collisions in place: next(10) still ambiguous against public.next(numeric), an exact-signature public.prev(integer) still silently winning inside DEFINE, and the deparsed bare PREV( still rebinding under an ordinary search_path. The deeper reason is that whether these names are navigation operations depends on a context the catalog cannot see -- are we inside a DEFINE clause or not? Any approach that goes through the catalog, under any prokind, resolves the name before it can know whether it is even a navigation operation. So the only thing that actually works is to not rely on the catalog at all: inside a DEFINE clause, recognize these names before any catalog lookup and substitute the navigation operation directly. Concretely I plan to drop the eight catalog entries (OIDs 8126-8133) and, inside DEFINE, intercept an unqualified prev/next/first/last by name in ParseFuncOrColumn -- ahead of func_get_detail() -- binding it to the navigation operation with no fallback to function resolution. Outside DEFINE the names then resolve as ordinary identifiers (a same-name user function just works), and a schema-qualified call inside DEFINE (public.prev(...)) still reaches the user function as the explicit escape hatch. This is also what Oracle does -- there is no catalog object for the navigation operations there at all. Thanks for the pointer -- the first_value comparison is what made it clear that the robustness comes from context, not from prokind. Henson --0000000000009afd3d0653f350a5 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Jian,

On Wed, Jun 10, 2026 jian he <jian.universality@gmail.com>= wrote:
> SELECT first_value(1);
> ERROR: =C2=A0window function= first_value requires an OVER clause
> LINE 1: SELECT first_value(1);=
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^
>> select prosrc, prokind, proname from pg_proc
> where proname = =3D 'prev' or proname =3D 'first' or proname =C2=A0=3D '= ;last' or
> proname =3D 'next';
>
> I am wond= ering, why the above query result functions not marked as
> window fu= nction in catalog?

The short answer is that no catalog marking can f= ix this, because prokind
does not take part in name resolution. =C2=A0fu= nc_get_detail() picks the
candidate by name/arguments/search_path first,= and prokind (window or not)
is only inspected afterwards.=C2=A0 So mark= ing the placeholders as window
functions would leave all three collision= s in place: next(10) still
ambiguous against public.next(numeric), an ex= act-signature
public.prev(integer) still silently winning inside DEFINE,= and the
deparsed bare PREV( still rebinding under an ordinary search_pa= th.

The deeper reason is that whether these names are navigation ope= rations
depends on a context the catalog cannot see -- are we inside a D= EFINE
clause or not?=C2=A0 Any approach that goes through the catalog, u= nder any
prokind, resolves the name before it can know whether it is eve= n a
navigation operation.

So the only thing that actually works i= s to not rely on the catalog at all:
inside a DEFINE clause, recognize t= hese names before any catalog lookup and
substitute the navigation opera= tion directly.=C2=A0 Concretely I plan to drop
the eight catalog entries= (OIDs 8126-8133) and, inside DEFINE, intercept an
unqualified prev/next= /first/last by name in ParseFuncOrColumn -- ahead of
func_get_detail() -= - binding it to the navigation operation with no
fallback to function re= solution.=C2=A0 Outside DEFINE the names then resolve as
ordinary identi= fiers (a same-name user function just works), and a
schema-qualified cal= l inside DEFINE (public.prev(...)) still reaches the
user function as th= e explicit escape hatch.=C2=A0 This is also what Oracle does
-- there is= no catalog object for the navigation operations there at all.

Thank= s for the pointer -- the first_value comparison is what made it clear
th= at the robustness comes from context, not from prokind.

Henson
--0000000000009afd3d0653f350a5--