Fix matview access method change issue (#4959)

* Fix matview access method change issue

* Use pg function get_am_name

* Split view generation command into pieces
improveErrorMessage
Ahmet Gedemenli 2021-05-07 15:47:24 +03:00 committed by GitHub
parent 6b1904d37a
commit 8cb505d6e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 5 deletions

View File

@ -34,6 +34,7 @@
#include "catalog/pg_am.h" #include "catalog/pg_am.h"
#include "columnar/columnar.h" #include "columnar/columnar.h"
#include "columnar/columnar_tableam.h" #include "columnar/columnar_tableam.h"
#include "commands/defrem.h"
#include "distributed/colocation_utils.h" #include "distributed/colocation_utils.h"
#include "distributed/commands.h" #include "distributed/commands.h"
#include "distributed/commands/utility_hook.h" #include "distributed/commands/utility_hook.h"
@ -199,6 +200,7 @@ static char * CreateWorkerChangeSequenceDependencyCommand(char *sequenceSchemaNa
char *sourceName, char *sourceName,
char *targetSchemaName, char *targetSchemaName,
char *targetName); char *targetName);
static char * GetAccessMethodForMatViewIfExists(Oid viewOid);
static bool WillRecreateForeignKeyToReferenceTable(Oid relationId, static bool WillRecreateForeignKeyToReferenceTable(Oid relationId,
CascadeToColocatedOption cascadeOption); CascadeToColocatedOption cascadeOption);
static void WarningsForDroppingForeignKeysWithDistributedTables(Oid relationId); static void WarningsForDroppingForeignKeysWithDistributedTables(Oid relationId);
@ -1126,13 +1128,28 @@ GetViewCreationCommandsOfTable(Oid relationId)
char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName); char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName);
bool isMatView = get_rel_relkind(viewOid) == RELKIND_MATVIEW; bool isMatView = get_rel_relkind(viewOid) == RELKIND_MATVIEW;
appendStringInfo(query, /* here we need to get the access method of the view to recreate it */
"CREATE %s VIEW %s AS %s", char *accessMethodName = GetAccessMethodForMatViewIfExists(viewOid);
isMatView ? "MATERIALIZED" : "",
qualifiedViewName, appendStringInfoString(query, "CREATE ");
viewDefinition);
if (isMatView)
{
appendStringInfoString(query, "MATERIALIZED ");
}
appendStringInfo(query, "VIEW %s ", qualifiedViewName);
if (accessMethodName)
{
appendStringInfo(query, "USING %s ", accessMethodName);
}
appendStringInfo(query, "AS %s", viewDefinition);
commands = lappend(commands, makeTableDDLCommandString(query->data)); commands = lappend(commands, makeTableDDLCommandString(query->data));
} }
return commands; return commands;
} }
@ -1517,6 +1534,32 @@ CreateWorkerChangeSequenceDependencyCommand(char *sequenceSchemaName, char *sequ
} }
/*
* GetAccessMethodForMatViewIfExists returns if there's an access method
* set to the view with the given oid. Returns NULL otherwise.
*/
static char *
GetAccessMethodForMatViewIfExists(Oid viewOid)
{
char *accessMethodName = NULL;
Relation relation = try_relation_open(viewOid, AccessShareLock);
if (relation == NULL)
{
ereport(ERROR, (errmsg("cannot complete operation "
"because no such view exists")));
}
Oid accessMethodOid = relation->rd_rel->relam;
if (OidIsValid(accessMethodOid))
{
accessMethodName = get_am_name(accessMethodOid);
}
relation_close(relation, NoLock);
return accessMethodName;
}
/* /*
* WillRecreateForeignKeyToReferenceTable checks if the table of relationId has any foreign * WillRecreateForeignKeyToReferenceTable checks if the table of relationId has any foreign
* key to a reference table, if conversion will be cascaded to colocated table this function * key to a reference table, if conversion will be cascaded to colocated table this function

View File

@ -917,5 +917,32 @@ NOTICE: renaming the new table to alter_distributed_table.partition_lengths_123
(1 row) (1 row)
-- verify that alter_distributed_table doesn't change the access methods for the views on the table
CREATE TABLE test_am_matview(a int);
SELECT create_distributed_table('test_am_matview' ,'a', colocate_with:='none');
create_distributed_table
---------------------------------------------------------------------
(1 row)
CREATE MATERIALIZED VIEW test_mat_view_am USING COLUMNAR AS SELECT count(*), a FROM test_am_matview GROUP BY a ;
SELECT alter_distributed_table('test_am_matview', shard_count:= 52);
NOTICE: creating a new table for alter_distributed_table.test_am_matview
NOTICE: moving the data of alter_distributed_table.test_am_matview
NOTICE: dropping the old alter_distributed_table.test_am_matview
NOTICE: drop cascades to materialized view test_mat_view_am
CONTEXT: SQL statement "DROP TABLE alter_distributed_table.test_am_matview CASCADE"
NOTICE: renaming the new table to alter_distributed_table.test_am_matview
alter_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT amname FROM pg_am WHERE oid IN (SELECT relam FROM pg_class WHERE relname ='test_mat_view_am');
amname
---------------------------------------------------------------------
columnar
(1 row)
SET client_min_messages TO WARNING; SET client_min_messages TO WARNING;
DROP SCHEMA alter_distributed_table CASCADE; DROP SCHEMA alter_distributed_table CASCADE;

View File

@ -308,5 +308,12 @@ ALTER TABLE partition_lengths RENAME TO partition_lengths_1234567890123456789012
-- verify alter_distributed_table works with long partitioned table names -- verify alter_distributed_table works with long partitioned table names
SELECT alter_distributed_table('partition_lengths_12345678901234567890123456789012345678901234567890', shard_count := 17, cascade_to_colocated := false); SELECT alter_distributed_table('partition_lengths_12345678901234567890123456789012345678901234567890', shard_count := 17, cascade_to_colocated := false);
-- verify that alter_distributed_table doesn't change the access methods for the views on the table
CREATE TABLE test_am_matview(a int);
SELECT create_distributed_table('test_am_matview' ,'a', colocate_with:='none');
CREATE MATERIALIZED VIEW test_mat_view_am USING COLUMNAR AS SELECT count(*), a FROM test_am_matview GROUP BY a ;
SELECT alter_distributed_table('test_am_matview', shard_count:= 52);
SELECT amname FROM pg_am WHERE oid IN (SELECT relam FROM pg_class WHERE relname ='test_mat_view_am');
SET client_min_messages TO WARNING; SET client_min_messages TO WARNING;
DROP SCHEMA alter_distributed_table CASCADE; DROP SCHEMA alter_distributed_table CASCADE;