Re: [DEPARSE] Operators on ROW() constructors read back as row comparisons

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: assam258(at)gmail(dot)com
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [DEPARSE] Operators on ROW() constructors read back as row comparisons
Date: 2026-10-20 20:22:10
Message-ID: 1391711.1792527730@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Henson Choi <assam258(at)gmail(dot)com> writes:
> The parser reads "ROW(..) op ROW(..)" as a column-by-column row
> comparison, and "ROW(..) op (SELECT ..)" as a row comparison sublink
> (transformAExprOp). Casting a ROW() to record makes the record
> operator apply, but the cast does nothing and leaves no trace in the
> tree.

Indeed. I think this is a parser bug and you're trying to band-aid
around it in the wrong place. get_rule_expr() would already do the
right thing if the RowExpr had row_format == COERCE_EXPLICIT_CAST,
but it does not, which seems like it could fool more things than
only deparsing. I'd blame that on coerce_type(), which silently
does nothing if the expression already has the right type; but
it should also worry about whether the expression is correctly
labeled as to coercion format. So roughly speaking, I think
we want something that's like hide_coercion_node() but can install
a cformat other than COERCE_IMPLICIT_CAST, and then invoke that
in the coerce_type() paths that don't build a new node.

It might be easier to move the existing coerce_type() logic into
a new subroutine, and then make coerce_type() be a wrapper that
calls that subroutine and then fixes up the coercion format.
Not sure about that part.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Haibo Yan 2026-10-20 20:38:32 Re: [PATCH] Fix grouping-set nulling of variable-free grouping expressions
Previous Message Iliia Khaprov 2026-10-20 20:18:17 [PATCH] Prevent overflow of datatotal in DecodeXLogRecord