diff options
| author | Tom Lane | 2016-06-27 19:57:21 +0000 |
|---|---|---|
| committer | Tom Lane | 2016-06-27 19:57:21 +0000 |
| commit | 17bfef80ee24f2204e66eb28277fddecdad64318 (patch) | |
| tree | 2e80e3fc801b4b44140b2bc482bbdcb2ee998779 /src/test | |
| parent | 28f294afdb522110d78f55905d031fbf1341911a (diff) | |
Fix CREATE MATVIEW/CREATE TABLE AS ... WITH NO DATA to not plan the query.
Previously, these commands always planned the given query and went through
executor startup before deciding not to actually run the query if WITH NO
DATA is specified. This behavior is problematic for pg_dump because it
may cause errors to be raised that we would rather not see before a
REFRESH MATERIALIZED VIEW command is issued. See for example bug #13907
from Marian Krucina. This change is not sufficient to fix that particular
bug, because we also need to tweak pg_dump to issue the REFRESH later,
but it's a necessary step on the way.
A user-visible side effect of doing things this way is that the returned
command tag for WITH NO DATA cases will now be "CREATE MATERIALIZED VIEW"
or "CREATE TABLE AS", not "SELECT 0". We could preserve the old behavior
but it would take more code, and arguably that was just an implementation
artifact not intended behavior anyhow.
In 9.5 and HEAD, also get rid of the static variable CreateAsReladdr, which
was trouble waiting to happen; there is not any prohibition on nested
CREATE commands.
Back-patch to 9.3 where CREATE MATERIALIZED VIEW was introduced.
Michael Paquier and Tom Lane
Report: <20160202161407.2778.24659@wrigleys.postgresql.org>
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/matview.out | 59 | ||||
| -rw-r--r-- | src/test/regress/expected/select_into.out | 38 | ||||
| -rw-r--r-- | src/test/regress/sql/matview.sql | 35 | ||||
| -rw-r--r-- | src/test/regress/sql/select_into.sql | 19 |
4 files changed, 132 insertions, 19 deletions
diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out index fb01d9956e7..2284e364ebf 100644 --- a/src/test/regress/expected/matview.out +++ b/src/test/regress/expected/matview.out @@ -392,26 +392,65 @@ CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1 DROP MATERIALIZED VIEW mv1 CASCADE; NOTICE: drop cascades to materialized view mv2 -- make sure that column names are handled correctly -CREATE TABLE v (i int, j int); -CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v; -ALTER TABLE v RENAME COLUMN i TO x; -INSERT INTO v values (1, 2); -CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii); -REFRESH MATERIALIZED VIEW mv_v; -SELECT * FROM v; +CREATE TABLE mvtest_v (i int, j int); +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj, kk) AS SELECT i, j FROM mvtest_v; -- error +ERROR: too many column names were specified +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj) AS SELECT i, j FROM mvtest_v; -- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_2 (ii) AS SELECT i, j FROM mvtest_v; -- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj, kk) AS SELECT i, j FROM mvtest_v WITH NO DATA; -- error +ERROR: too many column names were specified +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj) AS SELECT i, j FROM mvtest_v WITH NO DATA; -- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_4 (ii) AS SELECT i, j FROM mvtest_v WITH NO DATA; -- ok +ALTER TABLE mvtest_v RENAME COLUMN i TO x; +INSERT INTO mvtest_v values (1, 2); +CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v (ii); +REFRESH MATERIALIZED VIEW mvtest_mv_v; +REFRESH MATERIALIZED VIEW mvtest_mv_v_2; +REFRESH MATERIALIZED VIEW mvtest_mv_v_3; +REFRESH MATERIALIZED VIEW mvtest_mv_v_4; +SELECT * FROM mvtest_v; x | j ---+--- 1 | 2 (1 row) -SELECT * FROM mv_v; +SELECT * FROM mvtest_mv_v; ii | jj ----+---- 1 | 2 (1 row) -DROP TABLE v CASCADE; -NOTICE: drop cascades to materialized view mv_v +SELECT * FROM mvtest_mv_v_2; + ii | j +----+--- + 1 | 2 +(1 row) + +SELECT * FROM mvtest_mv_v_3; + ii | jj +----+---- + 1 | 2 +(1 row) + +SELECT * FROM mvtest_mv_v_4; + ii | j +----+--- + 1 | 2 +(1 row) + +DROP TABLE mvtest_v CASCADE; +NOTICE: drop cascades to 4 other objects +DETAIL: drop cascades to materialized view mvtest_mv_v +drop cascades to materialized view mvtest_mv_v_2 +drop cascades to materialized view mvtest_mv_v_3 +drop cascades to materialized view mvtest_mv_v_4 +-- make sure that create WITH NO DATA does not plan the query (bug #13907) +create materialized view mvtest_error as select 1/0 as x; -- fail +ERROR: division by zero +create materialized view mvtest_error as select 1/0 as x with no data; +refresh materialized view mvtest_error; -- fail here +ERROR: division by zero +drop materialized view mvtest_error; -- make sure that matview rows can be referenced as source rows (bug #9398) CREATE TABLE v AS SELECT generate_series(1,10) AS a; CREATE MATERIALIZED VIEW mv_v AS SELECT a FROM v WHERE a <= 5; diff --git a/src/test/regress/expected/select_into.out b/src/test/regress/expected/select_into.out index 9d3f04758e9..6be8129f831 100644 --- a/src/test/regress/expected/select_into.out +++ b/src/test/regress/expected/select_into.out @@ -50,6 +50,44 @@ DETAIL: drop cascades to table selinto_schema.tmp1 drop cascades to table selinto_schema.tmp2 drop cascades to table selinto_schema.tmp3 DROP USER selinto_user; +-- Tests for WITH NO DATA and column name consistency +CREATE TABLE ctas_base (i int, j int); +INSERT INTO ctas_base VALUES (1, 2); +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base; -- Error +ERROR: too many column names were specified +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base WITH NO DATA; -- Error +ERROR: too many column names were specified +CREATE TABLE ctas_nodata (ii, jj) AS SELECT i, j FROM ctas_base; -- OK +CREATE TABLE ctas_nodata_2 (ii, jj) AS SELECT i, j FROM ctas_base WITH NO DATA; -- OK +CREATE TABLE ctas_nodata_3 (ii) AS SELECT i, j FROM ctas_base; -- OK +CREATE TABLE ctas_nodata_4 (ii) AS SELECT i, j FROM ctas_base WITH NO DATA; -- OK +SELECT * FROM ctas_nodata; + ii | jj +----+---- + 1 | 2 +(1 row) + +SELECT * FROM ctas_nodata_2; + ii | jj +----+---- +(0 rows) + +SELECT * FROM ctas_nodata_3; + ii | j +----+--- + 1 | 2 +(1 row) + +SELECT * FROM ctas_nodata_4; + ii | j +----+--- +(0 rows) + +DROP TABLE ctas_base; +DROP TABLE ctas_nodata; +DROP TABLE ctas_nodata_2; +DROP TABLE ctas_nodata_3; +DROP TABLE ctas_nodata_4; -- -- CREATE TABLE AS/SELECT INTO as last command in a SQL function -- have been known to cause problems diff --git a/src/test/regress/sql/matview.sql b/src/test/regress/sql/matview.sql index e9af757d609..280c4bb400e 100644 --- a/src/test/regress/sql/matview.sql +++ b/src/test/regress/sql/matview.sql @@ -132,15 +132,32 @@ CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1 DROP MATERIALIZED VIEW mv1 CASCADE; -- make sure that column names are handled correctly -CREATE TABLE v (i int, j int); -CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v; -ALTER TABLE v RENAME COLUMN i TO x; -INSERT INTO v values (1, 2); -CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii); -REFRESH MATERIALIZED VIEW mv_v; -SELECT * FROM v; -SELECT * FROM mv_v; -DROP TABLE v CASCADE; +CREATE TABLE mvtest_v (i int, j int); +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj, kk) AS SELECT i, j FROM mvtest_v; -- error +CREATE MATERIALIZED VIEW mvtest_mv_v (ii, jj) AS SELECT i, j FROM mvtest_v; -- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_2 (ii) AS SELECT i, j FROM mvtest_v; -- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj, kk) AS SELECT i, j FROM mvtest_v WITH NO DATA; -- error +CREATE MATERIALIZED VIEW mvtest_mv_v_3 (ii, jj) AS SELECT i, j FROM mvtest_v WITH NO DATA; -- ok +CREATE MATERIALIZED VIEW mvtest_mv_v_4 (ii) AS SELECT i, j FROM mvtest_v WITH NO DATA; -- ok +ALTER TABLE mvtest_v RENAME COLUMN i TO x; +INSERT INTO mvtest_v values (1, 2); +CREATE UNIQUE INDEX mvtest_mv_v_ii ON mvtest_mv_v (ii); +REFRESH MATERIALIZED VIEW mvtest_mv_v; +REFRESH MATERIALIZED VIEW mvtest_mv_v_2; +REFRESH MATERIALIZED VIEW mvtest_mv_v_3; +REFRESH MATERIALIZED VIEW mvtest_mv_v_4; +SELECT * FROM mvtest_v; +SELECT * FROM mvtest_mv_v; +SELECT * FROM mvtest_mv_v_2; +SELECT * FROM mvtest_mv_v_3; +SELECT * FROM mvtest_mv_v_4; +DROP TABLE mvtest_v CASCADE; + +-- make sure that create WITH NO DATA does not plan the query (bug #13907) +create materialized view mvtest_error as select 1/0 as x; -- fail +create materialized view mvtest_error as select 1/0 as x with no data; +refresh materialized view mvtest_error; -- fail here +drop materialized view mvtest_error; -- make sure that matview rows can be referenced as source rows (bug #9398) CREATE TABLE v AS SELECT generate_series(1,10) AS a; diff --git a/src/test/regress/sql/select_into.sql b/src/test/regress/sql/select_into.sql index 4d1cc86556b..571ebe68a4c 100644 --- a/src/test/regress/sql/select_into.sql +++ b/src/test/regress/sql/select_into.sql @@ -53,6 +53,25 @@ RESET SESSION AUTHORIZATION; DROP SCHEMA selinto_schema CASCADE; DROP USER selinto_user; +-- Tests for WITH NO DATA and column name consistency +CREATE TABLE ctas_base (i int, j int); +INSERT INTO ctas_base VALUES (1, 2); +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base; -- Error +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base WITH NO DATA; -- Error +CREATE TABLE ctas_nodata (ii, jj) AS SELECT i, j FROM ctas_base; -- OK +CREATE TABLE ctas_nodata_2 (ii, jj) AS SELECT i, j FROM ctas_base WITH NO DATA; -- OK +CREATE TABLE ctas_nodata_3 (ii) AS SELECT i, j FROM ctas_base; -- OK +CREATE TABLE ctas_nodata_4 (ii) AS SELECT i, j FROM ctas_base WITH NO DATA; -- OK +SELECT * FROM ctas_nodata; +SELECT * FROM ctas_nodata_2; +SELECT * FROM ctas_nodata_3; +SELECT * FROM ctas_nodata_4; +DROP TABLE ctas_base; +DROP TABLE ctas_nodata; +DROP TABLE ctas_nodata_2; +DROP TABLE ctas_nodata_3; +DROP TABLE ctas_nodata_4; + -- -- CREATE TABLE AS/SELECT INTO as last command in a SQL function -- have been known to cause problems |
