Re: BUG #17404: CREATE OR REPLACE VIEW does not properly change the COLLATION of an existing field. - Mailing list pgsql-bugs

From Japin Li
Subject Re: BUG #17404: CREATE OR REPLACE VIEW does not properly change the COLLATION of an existing field.
Date
Msg-id MEYP282MB1669A5A4CA2A9A12A86986D2B6349@MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM
Whole thread Raw
In response to Re: BUG #17404: CREATE OR REPLACE VIEW does not properly change the COLLATION of an existing field.  (Japin Li <japinli@hotmail.com>)
List pgsql-bugs
On Tue, 15 Feb 2022 at 23:42, Japin Li <japinli@hotmail.com> wrote:
> On Tue, 15 Feb 2022 at 16:51, PG Bug reporting form <noreply@postgresql.org> wrote:
>> 3 STEPS TO REPRODUCE : 
>> ========================
>> create TABLE my_table (my_text TEXT);
>> create VIEW my_view AS SELECT my_text COLLATE "C" FROM my_table;
>> create OR REPLACE view my_view AS SELECT my_text COLLATE "en_US.utf8" FROM
>> my_table;
>>
>> EXPECTED RESULT :
>> ===================
>> The COLLATION of "my_view"."my_text" should have been changed to
>> "en_US.utf8".  
>> - OR -
>> I should have got an error message telling me that it is not possible.
>>
>> OBSERVED RESULT : 
>> ===================
>> Nothing (it silently fails).
>>
>> select table_schema, table_name, column_name, collation_name from
>> information_schema.columns where collation_name is not null and
>> table_name='my_view';
>> clearly shows that the COLLATION has not been changed as requested. 
>>
>> What the doc says about CREATE OR REPLACE VIEW :
>> ============================================= 
>> "The new query must generate the same columns that were generated by the
>> existing view query (that is, the same column names in the same order and
>> with the *same data types*), but it may add additional columns to the end of
>> the list. 
>> *The calculations giving rise to the output columns may be completely
>> different*."
>>
>> It doesn't say wether the COLLATION is considered being part of the "data
>> types" or not, i.e. it doesn't say wether it's possible to change the
>> COLLATION of an existing field or not.
>> My tests (under Postgres v. 12.4) trying to do so showed that postgres says
>> nothing and seems to accept the SQL statement, but nothing is changed in the
>> database (it silently fails). From the user perspective, I consider such a
>> silent failure the WORST situation possible : I would prefer either 1) to
>> get an error message saying that it's not possible to change the COLLATION
>> of an existing field - OR even better - 2) to actually change the COLLATION
>> of the existing field, as requested.
>>
>> For this reason, I have also reported a documentation issue.
>
> I find the checkViewTupleDesc() function do not check the collation[1].  So it
> will not update the collation of columns.
>

Sorry for unfinished content.

After checkViewtupledesc() checking, DefineVirtualRelation() only insert the new
attributes for the view, and do not touch the old attributes, so the collation
have no chance to change[2].

[2]
        /*
         * If new attributes have been added, we must add pg_attribute entries
         * for them.  It is convenient (although overkill) to use the ALTER
         * TABLE ADD COLUMN infrastructure for this.
         *
         * Note that we must do this before updating the query for the view,
         * since the rules system requires that the correct view columns be in
         * place when defining the new rules.
         *
         * Also note that ALTER TABLE doesn't run parse transformation on
         * AT_AddColumnToView commands.  The ColumnDef we supply must be ready
         * to execute as-is.
         */
        if (list_length(attrList) > rel->rd_att->natts)
        {
            ListCell   *c;
            int         skip = rel->rd_att->natts;

            foreach(c, attrList)
            {
                if (skip > 0)
                {
                    skip--;
                    continue;
                }
                atcmd = makeNode(AlterTableCmd);
                atcmd->subtype = AT_AddColumnToView;
                atcmd->def = (Node *) lfirst(c);
                atcmds = lappend(atcmds, atcmd);
            }

            /* EventTriggerAlterTableStart called by ProcessUtilitySlow */
            AlterTableInternal(viewOid, atcmds, true);

            /* Make the new view columns visible */
            CommandCounterIncrement();
        }

-- 
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.



pgsql-bugs by date:

Previous
From: Japin Li
Date:
Subject: Re: BUG #17404: CREATE OR REPLACE VIEW does not properly change the COLLATION of an existing field.
Next
From: Tom Lane
Date:
Subject: Re: BUG #17404: CREATE OR REPLACE VIEW does not properly change the COLLATION of an existing field.