public inbox for [email protected]  
help / color / mirror / Atom feed
From: Henson Choi <[email protected]>
To: jian he <[email protected]>
To: Tatsuo Ishii <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Subject: Re: Row pattern recognition
Date: Fri, 19 Jun 2026 09:43:10 +0900
Message-ID: <CAAAe_zAe8CRN-ggNhcP7b-ALiRrHxKTXBWbNVMhdW_QoO=1c4Q@mail.gmail.com> (raw)
In-Reply-To: <CACJufxH_Z5aaYEir3=GHoZu-0pKzQdScu85LgCm1C8n=oQo=4Q@mail.gmail.com>
References: <CACJufxFAQhbOD9EVCTAy-VwDbG4446N10GsxCcgdpFnjHO1Efw@mail.gmail.com>
	<CACJufxG6rKfd0WtsVZgzcoh8vOEwo_8UDWkuOd888ATavNv_uw@mail.gmail.com>
	<CAAAe_zDfrGSTqhgy8vOC1K6mzDsqVJGEmMy5N84G6=5EJT6--g@mail.gmail.com>
	<[email protected]>
	<CACJufxH_Z5aaYEir3=GHoZu-0pKzQdScu85LgCm1C8n=oQo=4Q@mail.gmail.com>

Hi Jian,

> ParseFuncOrColumn cleanly handles (f).prev by translating it to prev(f)
as a
> regular function call. However, if a dedicated window navigation function
> exists, this translation creates ambiguity -- it becomes unclear whether
> prev(f) is window navigation or a normal function call.

Agreed, and that is the reason I would rather not have a dedicated
navigation function at all.  With navigation handled purely as syntax,
(f).prev never has to compete with it: attribute notation just falls
through to an ordinary function (prev(f)), the same inside and outside a
DEFINE clause.  That is Tatsuo's and my preferred option (a), so I will
settle on it.

> Cases with additional dots (e.g., public.prev(arg)) should also be treated
> as normal function calls, IMHO.

Yes.  A schema-qualified name is the explicit escape hatch to an ordinary
function; navigation is recognized only for an unqualified, single-element
name.

> As a result, only prev(arg) and prev(arg, offset) are recognized as
special
> window navigation syntax, despite being visually identical to a function
> call.

Right -- that is exactly the surface I want to land on: the dotless
prev(...)/next(...)/first(...)/last(...) forms are navigation, everything
else is an ordinary function.

> Summary:
> Dedicated window navigation functions should be removed entirely.  Window
> navigation should be limited to a single syntactic form (no dots) -- one
> that *looks* like a function call but is parsed as syntax.

That is the direction I will take the tree.  So the three of us have
converged.

> This is not unprecedented; there are many existing cases where something
> appears to be a function call but is actually a syntax form, for example:
>
> SELECT json_object('{}');
>  json_object
> -------------
>  {}
> (1 row)
>
> SELECT public.json_object('{}');
> ERROR:  function public.json_object(unknown) does not exist
> LINE 1: SELECT public.json_object('{}');
>                ^
>
> So I think in the DEFINE context, it makes sense for some form that looks
> like a function call to actually be syntax.

The json_object parallel is exact at the user-visible level, but I want to
flag that the implementation has to differ underneath -- and that is
actually why navigation is not done the json_object way.

json_object can live in the grammar because two constraints do not apply to
it:

  - No context restriction.  JSON_OBJECT means the same thing wherever a
    value expression is allowed, so a single keyword production in the
    shared a_expr grammar is enough.

  - The name is safe to reserve.  Making json_object a keyword costs almost
    nobody an identifier.

Row pattern navigation has both constraints:

  - It must mean navigation *only* inside DEFINE; everywhere else
    prev/next/first/last are ordinary names.  bison is LALR(1) and
    context-free, so a production cannot be conditioned on "are we inside
    DEFINE"; a_expr is shared by SELECT lists, WHERE, etc.  And a row
    pattern definition is "ColId AS a_expr", so navigation can appear
    anywhere a value expression can.  Special-casing it in the grammar
    would mean duplicating the whole a_expr tree into a second DEFINE-only
    expression grammar (or resorting to lexer feedback), which is not worth
    it.

  - The names are common.  prev/next/first/last (especially next, first,
    last) are everyday column and function names; reserving them globally
    would break existing queries.

So the plan is the opposite of a grammar keyword: parse navigation as an
ordinary FuncCall and reinterpret it in parse analysis, gated on
p_expr_kind == EXPR_KIND_RPR_DEFINE and an unqualified, single-element
name.  That keeps one expression grammar, leaves the names free everywhere
else, and confines the special meaning to exactly the DEFINE context -- the
same "looks like a function call, parsed as syntax" behavior you described,
reached by a lighter path that does not grow the keyword list.

Thanks,
Henson


view thread (136+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Row pattern recognition
  In-Reply-To: <CAAAe_zAe8CRN-ggNhcP7b-ALiRrHxKTXBWbNVMhdW_QoO=1c4Q@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox