Unsafe use of relation->rd_options without checking its type - Mailing list pgsql-hackers

From Tom Lane
Subject Unsafe use of relation->rd_options without checking its type
Date
Msg-id 26681.1477940227@sss.pgh.pa.us
Whole thread Raw
Responses Re: Unsafe use of relation->rd_options without checking its type  (Peter Geoghegan <pg@heroku.com>)
Re: Unsafe use of relation->rd_options without checking its type  (neha khatri <nehakhatri5@gmail.com>)
Re: Unsafe use of relation->rd_options without checking its type  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
I looked into bug#14397.  The submitter was discourteous enough not to
provide an in-line example, but here it is:

CREATE TABLE IF NOT EXISTS TEST_1 (
ID       SERIAL PRIMARY KEY,
C1       BYTEA,
C2       TEXT NOT NULL,
C3       BOOLEAN NOT NULL DEFAULT FALSE,
CONSTRAINT TEST_1_unique_idx UNIQUE(C1, C2)

create or replace view test as select * from test_1 with cascaded check option;

insert into test (c1, c2, c3) values (decode('MTIzAAE=', 'base64'),
'text', true) on conflict (c1, c2) do update set c3=excluded.c3;

ERROR:  ON CONFLICT is not supported on table "test" used as a catalog table
LINE 1: ...lues (decode('MTIzAAE=', 'base64'), 'text', true) on conflic...
             ^ 

The reason for the error is that transformOnConflictArbiter applies
RelationIsUsedAsCatalogTable() to something that it doesn't know to
be a plain relation --- it's a view in this case.  And that macro
blindly assumes that relation->rd_options is a StdRdOptions struct,
when in this case it's actually a ViewOptions struct.

Now that I've seen this I wonder which other uses of rd_options are
potentially broken.  RelationIsUsedAsCatalogTable() is hardly the
only macro that is assuming with little justification that it's
applied to the right kind of reloptions.

We could band-aid this by having the RelationIsUsedAsCatalogTable()
macro check relation->relkind, but I'm inclined to think that the
right fix going forward is to insist that StdRdOptions, ViewOptions,
and the other in-memory representations of reloptions ought to be
self-identifying somehow.  We could add a field to them similar to
nodeTag, but one of the things that was envisioned to begin with
is relation types that have StdRdOptions as the first part of a
larger struct.  I'm not sure how to make that work with a tag.

Thoughts?
        regards, tom lane



pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: Query regarding selectDumpableExtension()
Next
From: Peter Geoghegan
Date:
Subject: Re: Unsafe use of relation->rd_options without checking its type