v2-0000-cover-letter.patch

application/octet-stream

Filename: v2-0000-cover-letter.patch
Type: application/octet-stream
Part: 5
Message: Re: Schema-qualify the equality operator when deparsing NULLIF/IS DISTINCT FROM
From b0cdce84f7825651a6bda1a371bcc2458311545f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Pasternak?= <michal.dtz@gmail.com>
Date: Tue, 7 Jul 2026 15:09:36 +0200
Subject: [PATCH v2 0/5] Schema-qualifiable operator syntax for
 implicit-operator constructs (was: Schema-qualify the equality
 operator when deparsing NULLIF/IS DISTINCT FROM)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Several SQL constructs resolve an operator by unqualified name at parse
time and provide no place in their syntax to write a schema-qualified
operator name: IS [NOT] DISTINCT FROM, NULLIF, simple CASE, row
comparisons, and ANY/ALL subquery comparisons -- the classes Tom
cataloged in 10492.1531515255@sss.pgh.pa.us -- plus JOIN USING /
NATURAL JOIN.  When such a construct ends up bound to an operator that
is not reachable through the search_path in effect at reload time
(typically pg_dump's restricted search_path), the dumped definition
either fails to restore or, worse, silently reparses with a different
operator.

This series gives each construct an optional OPERATOR() decoration,
one construct per patch.  The parser always accepts the decoration;
ruleutils.c emits it only when reparsing the undecorated form would
not resolve the very same operator OID(s).  Post-analysis expression
trees and executor nodes are untouched.

  0001: a IS [NOT] DISTINCT OPERATOR(s.=) FROM b and
        NULLIF(a, b USING OPERATOR(s.=))
  0002: JOIN ... USING (a, b) OPERATOR (s.=, s.=), one operator per
        USING column; NATURAL JOIN deparses via the same path
  0003: ROW(a, b) OPERATOR(s.<, s.<) ROW(c, d), generalizing the
        existing single-name decoration to a per-column list
  0004: (a, b) OPERATOR(op1, op2) ANY (SELECT ...), likewise for
        ANY/ALL and row-op-subquery sublinks; fixes today's silent
        operator swap when a multi-column IN is dumped and reloaded
  0005: CASE x WHEN y USING OPERATOR(s.=) THEN ..., per WHEN arm

The whole series weighs in at 22 files changed, 2366 insertions(+),
90 deletions(-), of which about 1530 lines are regression tests and
expected output and about 165 lines are documentation.

Michał Pasternak (5):
  Allow schema-qualifying the operator in IS DISTINCT FROM/NULLIF
  Allow schema-qualifying the operators of JOIN USING
  Allow per-column operator lists in row comparisons
  Allow per-column operator lists in ANY/ALL subquery comparisons
  Allow schema-qualifying the comparison operator of a simple CASE

 contrib/hstore/expected/hstore.out            |  88 ++
 contrib/hstore/sql/hstore.sql                 |  43 +
 doc/src/sgml/func/func-comparison.sgml        |  23 +-
 doc/src/sgml/func/func-comparisons.sgml       |  19 +
 doc/src/sgml/func/func-conditional.sgml       |  39 +-
 doc/src/sgml/func/func-subquery.sgml          |  40 +
 doc/src/sgml/queries.sgml                     |  12 +
 doc/src/sgml/ref/select.sgml                  |  18 +-
 doc/src/sgml/syntax.sgml                      |  20 +
 src/backend/commands/define.c                 |   5 +
 src/backend/parser/gram.y                     | 103 +-
 src/backend/parser/parse_clause.c             |  55 +-
 src/backend/parser/parse_expr.c               | 134 ++-
 src/backend/parser/parse_oper.c               |  22 +
 src/backend/utils/adt/ruleutils.c             | 380 +++++++-
 src/include/catalog/catversion.h              |   2 +-
 src/include/nodes/parsenodes.h                |   9 +-
 src/include/nodes/primnodes.h                 |  25 +-
 src/include/parser/parse_oper.h               |  20 +
 .../regress/expected/operator_qualify.out     | 893 ++++++++++++++++++
 src/test/regress/parallel_schedule            |   5 +-
 src/test/regress/sql/operator_qualify.sql     | 501 ++++++++++
 22 files changed, 2366 insertions(+), 90 deletions(-)
 create mode 100644 src/test/regress/expected/operator_qualify.out
 create mode 100644 src/test/regress/sql/operator_qualify.sql

-- 
2.54.0