Re: Attribute of type record has wrong type error with MERGE ... WHEN NOT MATCHED BY SOURCE THEN DELETE

From: Tender Wang <tndrwang(at)gmail(dot)com>
To: Duncan Sands <duncan(dot)sands(at)deepbluecap(dot)com>
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: Attribute of type record has wrong type error with MERGE ... WHEN NOT MATCHED BY SOURCE THEN DELETE
Date: 2025-03-10 13:46:36
Message-ID: CAHewXNmuO70GHqZev500b9cGXRbHzU9cDsn2tMWqhv6bXWJ5qQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Duncan Sands <duncan(dot)sands(at)deepbluecap(dot)com> 于2025年3月10日周一 18:43写道:

> Postgresql version 17.4 (Ubuntu 17.4-1.pgdg24.10+2) on x86_64-pc-linux-gnu
>
> To reproduce, execute the statements in the attached file cr.sql. I get:
>
> duncan=> \i cr.sql
> CREATE TABLE
> CREATE TABLE
> CREATE VIEW
> CREATE TABLE
> COPY 1
> COPY 2
> COPY 1
> psql:cr.sql:42: ERROR: attribute 2 of type record has wrong type
> DETAIL: Table has type _country_or_region, but query expects record.
>
> I attribute it to the "WHEN NOT MATCHED BY SOURCE THEN DELETE" part of the
> MERGE
> as it doesn't happen if that part is left off.

When the query has NOT MATCHED BY SOURCE, commit d7d297f84 add "src IS NOT
NULL" join condition.
In this case, the src is view(e.g. subquery), so in makeWholeRowVar(), it
will call below code:
result = makeVar(varno,
InvalidAttrNumber,
RECORDOID,
-1,
InvalidOid,
varlevelsup);

the vartype is RECORDOID, but te reltype of src is not RECORDOID, so
$SUBJECT error reports.

I add the below codes to makeWholeRowVar() default branch:

if (rte->relkind == RELKIND_VIEW)
toid = get_rel_type_id(rte->relid);
else
toid = RECORDOID;

It can work.

--
Thanks,
Tender Wang

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2025-03-10 14:23:47 Re: Window Functions with identical PARTITION BY and ORDER BY clauses evaluated separately
Previous Message PG Bug reporting form 2025-03-10 13:22:21 BUG #18838: Missing characters in replication slot when bytea_output is set to "escape"