Obtaining a more consistent view definition when a UNION subquerycontains undecorated constants

Поиск
Список
Период
Сортировка
От Jimmy Yih
Тема Obtaining a more consistent view definition when a UNION subquerycontains undecorated constants
Дата
Msg-id CAOMx_OBi4YGirtugHBQeuK2NL7SpqwxenUW+jQ7AhDGL0DPhjw@mail.gmail.com
обсуждение исходный текст
Ответы Re: Obtaining a more consistent view definition when a UNION subquery contains undecorated constants  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
Hello,

A colleague and I were playing around with dumping views and found an inconsistency for a view definition involving subqueries and undecorated constants in a UNION.  When we took that view definition and restored it, dumping the view gave different syntax again.  Although the slightly different view definitions were semantically the same, it was weird to see the syntax difference.

Our view SQL where 'bar' constant is not decorated:

CREATE VIEW fooview AS SELECT t.a FROM (SELECT 1 AS a, 'foo'::text AS baz UNION SELECT 0 AS a, 'bar')t;
// view definition from pg_get_viewdef()
 SELECT t.a
   FROM ( SELECT 1 AS a,
            'foo'::text AS baz
        UNION
         SELECT 0 AS a,
            'bar'::text) t;

Note that the type decorator is appended to 'bar' in the normal fashion.

Then taking the above view definition, and creating a view,

CREATE VIEW fooview AS SELECT t.a FROM (SELECT 1 AS a, 'foo'::text AS baz UNION SELECT 0 AS a, 'bar'::text)t;
// view definition from pg_get_viewdef()
 SELECT t.a
   FROM ( SELECT 1 AS a,
            'foo'::text AS baz
        UNION
         SELECT 0 AS a,
            'bar'::text AS text) t;

results in a view definition that has the alias 'AS text' appended to 'bar'::text.

Contrast this to creating a view without the subquery:

CREATE OR REPLACE VIEW fooview AS SELECT 1 AS a, 'foo'::text AS baz UNION SELECT 0 AS a, 'bar';
// view definition from pg_get_viewdef()
 SELECT 1 AS a,
    'foo'::text AS baz
UNION
 SELECT 0 AS a,
    'bar'::text AS baz;

We see that this view will use the view's tuple descriptor to name the columns.

Looking at the internal code (mostly get_from_clause_item() function), we saw that when a subquery is used, there is no tuple descriptor passed to get_query_def() function. Because of this, get_target_list() uses the resnames obtained from the pg_rewrite entry's ev_action field.  However, it seems to be fairly simple to construct a dummy tuple descriptor from the ev_action to pass down the call stack so that the column names will be consistent when deparsing both T_A_Const and T_TypeCast parse tree nodes involving a UNION.  Attached is a patch that demonstrates this.

Running with the attached patch, it seems to work pretty well:

postgres=# CREATE VIEW fooview AS SELECT t.a FROM (SELECT 1 AS a, 'foo'::text AS baz UNION SELECT 0 AS a, 'bar')t;
postgres=# select pg_get_viewdef('fooview');
           pg_get_viewdef
------------------------------------
  SELECT t.a
    FROM ( SELECT 1 AS a,
             'foo'::text AS baz
         UNION
          SELECT 0 AS a,
             'bar'::text AS baz) t;
(1 row)

postgres=# CREATE VIEW fooview AS SELECT t.a FROM (SELECT 1 AS a, 'foo'::text AS baz UNION SELECT 0 AS a, 'bar'::text)t;
postgres=# select pg_get_viewdef('fooview');
           pg_get_viewdef
------------------------------------
  SELECT t.a
    FROM ( SELECT 1 AS a,
             'foo'::text AS baz
         UNION
          SELECT 0 AS a,
             'bar'::text AS baz) t;
(1 row)

Nested subqueries also work with the patch.  We're not sure how this could break.

Is this an acceptable change that should be pursued?

Regards,
Jimmy Yih and Jim Doty
Вложения

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Thomas Munro
Дата:
Сообщение: Re: Collation versioning
Следующее
От: Stephen Frost
Дата:
Сообщение: Re: [PATCH] Include application_name in "connection authorized" logmessage