From e244e9ffb6ea09577f7f8fdfec94490abf56cb42 Mon Sep 17 00:00:00 2001 From: Burak Velioglu Date: Wed, 15 Jun 2022 17:41:12 +0300 Subject: [PATCH] Fix dropping temporary view without specifying the explicit schema name (#6003) --- src/backend/distributed/commands/view.c | 3 +- .../distributed/deparser/qualify_view_stmt.c | 31 ++++++++++++------- .../regress/expected/view_propagation.out | 29 ++++++++++++++++- src/test/regress/sql/view_propagation.sql | 22 ++++++++++++- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/src/backend/distributed/commands/view.c b/src/backend/distributed/commands/view.c index 554741310..adae0c84e 100644 --- a/src/backend/distributed/commands/view.c +++ b/src/backend/distributed/commands/view.c @@ -439,7 +439,8 @@ AlterViewOwnerCommand(Oid viewOid) bool IsViewDistributed(Oid viewOid) { - Assert(get_rel_relkind(viewOid) == RELKIND_VIEW); + Assert(get_rel_relkind(viewOid) == RELKIND_VIEW || + get_rel_relkind(viewOid) == RELKIND_MATVIEW); ObjectAddress viewAddress = { 0 }; ObjectAddressSet(viewAddress, RelationRelationId, viewOid); diff --git a/src/backend/distributed/deparser/qualify_view_stmt.c b/src/backend/distributed/deparser/qualify_view_stmt.c index b787bf9b7..1f450d50a 100644 --- a/src/backend/distributed/deparser/qualify_view_stmt.c +++ b/src/backend/distributed/deparser/qualify_view_stmt.c @@ -34,22 +34,31 @@ QualifyDropViewStmt(Node *node) { char *viewName = NULL; char *schemaName = NULL; + List *viewNameToAdd = possiblyQualifiedViewName; DeconstructQualifiedName(possiblyQualifiedViewName, &schemaName, &viewName); if (schemaName == NULL) { - char *objname = NULL; - Oid schemaOid = QualifiedNameGetCreationNamespace(possiblyQualifiedViewName, - &objname); - schemaName = get_namespace_name(schemaOid); - List *qualifiedViewName = list_make2(makeString(schemaName), - makeString(viewName)); - qualifiedViewNames = lappend(qualifiedViewNames, qualifiedViewName); - } - else - { - qualifiedViewNames = lappend(qualifiedViewNames, possiblyQualifiedViewName); + RangeVar *viewRangeVar = makeRangeVarFromNameList(possiblyQualifiedViewName); + Oid viewOid = RangeVarGetRelid(viewRangeVar, AccessExclusiveLock, + stmt->missing_ok); + + /* + * If DROP VIEW IF EXISTS called and the view doesn't exist, oid can be invalid. + * Do not try to qualify it. + */ + if (OidIsValid(viewOid)) + { + Oid schemaOid = get_rel_namespace(viewOid); + schemaName = get_namespace_name(schemaOid); + + List *qualifiedViewName = list_make2(makeString(schemaName), + makeString(viewName)); + viewNameToAdd = qualifiedViewName; + } } + + qualifiedViewNames = lappend(qualifiedViewNames, viewNameToAdd); } stmt->objects = qualifiedViewNames; diff --git a/src/test/regress/expected/view_propagation.out b/src/test/regress/expected/view_propagation.out index 4ad3d5be9..2c59a945b 100644 --- a/src/test/regress/expected/view_propagation.out +++ b/src/test/regress/expected/view_propagation.out @@ -792,6 +792,33 @@ SELECT run_command_on_workers($$SELECT count(*) FROM v_test_2$$); (localhost,57638,f,"ERROR: relation ""v_test_2"" does not exist") (2 rows) +-- create and drop temporary view +CREATE TEMPORARY VIEW temp_view_to_drop AS SELECT 1; +WARNING: "view temp_view_to_drop" has dependency on unsupported object "schema pg_temp_xxx" +DETAIL: "view temp_view_to_drop" will be created only locally +DROP VIEW temp_view_to_drop; +-- drop non-existent view +DROP VIEW IF EXISTS drop_the_nonexistent_view; +NOTICE: view "drop_the_nonexistent_view" does not exist, skipping +DROP VIEW IF EXISTS non_exist_view_schema.view_to_drop; +NOTICE: schema "non_exist_view_schema" does not exist, skipping +-- Check materialized view just for sanity +CREATE MATERIALIZED VIEW materialized_view_to_test AS SELECT 1; +DROP VIEW materialized_view_to_test; +ERROR: "materialized_view_to_test" is not a view +HINT: Use DROP MATERIALIZED VIEW to remove a materialized view. +DROP MATERIALIZED VIEW materialized_view_to_test; +CREATE SCHEMA axx; +create materialized view axx.temp_view_to_drop AS SELECT 1; +DROP VIEW axx.temp_view_to_drop; +ERROR: "temp_view_to_drop" is not a view +HINT: Use DROP MATERIALIZED VIEW to remove a materialized view. +DROP VIEW IF EXISTS axx.temp_view_to_drop; +ERROR: "temp_view_to_drop" is not a view +HINT: Use DROP MATERIALIZED VIEW to remove a materialized view. +DROP MATERIALIZED VIEW IF EXISTS axx.temp_view_to_drop; +DROP MATERIALIZED VIEW IF EXISTS axx.temp_view_to_drop; +NOTICE: materialized view "temp_view_to_drop" does not exist, skipping SET client_min_messages TO ERROR; DROP SCHEMA view_prop_schema_inner CASCADE; -DROP SCHEMA view_prop_schema CASCADE; +DROP SCHEMA view_prop_schema, axx CASCADE; diff --git a/src/test/regress/sql/view_propagation.sql b/src/test/regress/sql/view_propagation.sql index 2af9de21c..0090d870c 100644 --- a/src/test/regress/sql/view_propagation.sql +++ b/src/test/regress/sql/view_propagation.sql @@ -442,6 +442,26 @@ SELECT create_distributed_table('employees','employee_id'); SELECT run_command_on_workers($$SELECT count(*) FROM v_test_1$$); SELECT run_command_on_workers($$SELECT count(*) FROM v_test_2$$); +-- create and drop temporary view +CREATE TEMPORARY VIEW temp_view_to_drop AS SELECT 1; +DROP VIEW temp_view_to_drop; + +-- drop non-existent view +DROP VIEW IF EXISTS drop_the_nonexistent_view; +DROP VIEW IF EXISTS non_exist_view_schema.view_to_drop; + +-- Check materialized view just for sanity +CREATE MATERIALIZED VIEW materialized_view_to_test AS SELECT 1; +DROP VIEW materialized_view_to_test; +DROP MATERIALIZED VIEW materialized_view_to_test; + +CREATE SCHEMA axx; +create materialized view axx.temp_view_to_drop AS SELECT 1; +DROP VIEW axx.temp_view_to_drop; +DROP VIEW IF EXISTS axx.temp_view_to_drop; +DROP MATERIALIZED VIEW IF EXISTS axx.temp_view_to_drop; +DROP MATERIALIZED VIEW IF EXISTS axx.temp_view_to_drop; + SET client_min_messages TO ERROR; DROP SCHEMA view_prop_schema_inner CASCADE; -DROP SCHEMA view_prop_schema CASCADE; +DROP SCHEMA view_prop_schema, axx CASCADE;