Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: make view descriptors depend on table/columns by IDs #15388

Closed
wants to merge 2 commits into from

Commits on Aug 2, 2017

  1. sql: re-vamp the view dependency analysis

    Prior to this patch, view dependency analysis during CREATE VIEW was
    broken because it would only check dependencies after plan
    optimization, i.e. possibly after some dependency were lost. For
    example, with the queries:
    
    ```sql
    CREATE VIEW v AS SELECT k FROM (SELECT k,v FROM kv) -- loses dependency on kv.v
    CREATE VIEW v AS SELECT k,v FROM kv WHERE FALSE -- loses dependency on kv
    ```
    
    This patch addresses the issue as follows:
    
    - the dependencies are now collected during the initial construction
      of the query plan, before any optimization are applied. This way we
      ensure the dependency tracking is complete.
    - a migration is implemented that will fix any view descriptor and
      corresponding dependency information that was populated prior to
      this fix.
    knz committed Aug 2, 2017
    Configuration menu
    Copy the full SHA
    83f873c View commit details
    Browse the repository at this point in the history
  2. sql: make view descriptors depend on table/columns by IDs

    This patch does what it says on the label: the descriptor still
    contains a valid SQL query, but with all table names rewritten to use
    numeric table references. These are hidden initially, until
    the referenced tables gets a new schema.
    
    For example:
    ```
     CREATE TABLE kv(k INT PRIMARY KEY, v INT);
     CREATE VIEW vx AS SELECT v AS x FROM kv;
     SHOW CREATE VIEW vx;
     +------+-----------------------------------------+
     | View |           CreateView                    |
     +------+-----------------------------------------+
     | vx   | CREATE VIEW vx AS SELECT v AS x FROM kv |
     +------+-----------------------------------------+
     (1 row)
     ALTER TABLE kv ADD COLUMN d INT;
     SHOW CREATE VIEW vx;
     +------+--------------------------------------------------------------+
     | View |                          CreateView                          |
     +------+--------------------------------------------------------------+
     | vx   | CREATE VIEW vx AS SELECT v AS x FROM [64(1, 2) AS kv (k, v)] |
     +------+--------------------------------------------------------------+
     (1 row)
    ```
    
    A side effect of this patch is that view definitions can now use star
    expansion, i.e. `CREATE VIEW kv_alias AS SELECT * FROM kv` is now
    possible and valid. (And there was much rejoicing.)
    
    Another side effect, visible in the example above, is that `SHOW
    CREATE VIEW` now reveals the structural dependency (showing both the
    ID and the original table name) when the table's name or column
    definitions change.
    
    This may or may not be desirable from a UX perspective, however anyone
    wishing to improve upon this will take note that if the column list in
    the table descriptor was altered after the view was created (e.g. to
    add new columns, rename columns or remove columns not depended on by
    the view), there is no valid way to print out the view definition
    using valid SQL but without using the table reference syntax. Consider
    the example above: suppose column "v" was renamed to "w"; trying to
    print out as `create view vx as select v as x from kv` would be
    invalid because then column "v" would have disappeared; then suppose
    "v" was renamed to "w" and a new unrelated column "v" was added,
    trying `create view vx as select v as x from kv as kv(v)` would be
    invalid as well because the new column `v` is unrelated to the one the
    view was intended to depend on. Due to these obstacles, it is
    advisable to let the numeric table reference show up in the output of
    `SHOW CREATE VIEW` and document this behavior.
    
    Although it would be correct to do so for newly-created clusters, this
    patch does *not* lift the restriction on ALTER that prevents it from
    renaming tables or columns depended on by views. This change would be
    correct on new clusters because once the guarantee is enforced that
    all view descriptors depend on table/columns by IDs, renaming becomes
    possible (renaming preserves the ID); however, for previously created
    clusters there may exist already some view descriptors containing
    by-name table references, and allowing those to be renamed would be
    unsound. The proper approach is to completement this patch by a
    cluster migration which rewrites all existing view descriptors. This
    work is left to a subsequent commit.
    
    A last improvement brought by this PR is that column renames are now
    properly visible in pg_catalog:
    
    ```sql
    > CREATE VIEW v (x) AS SELECT k FROM kv
    > SELECT definition FROM pg_catalog.pg_views WHERE viewname = 'v'
    SELECT k AS x FROM (SELECT k FROM kv)
    ```
    knz committed Aug 2, 2017
    Configuration menu
    Copy the full SHA
    ba28022 View commit details
    Browse the repository at this point in the history