mirror of https://github.com/citusdata/citus.git
Fix matview access method change issue (#4959)
* Fix matview access method change issue * Use pg function get_am_name * Split view generation command into piecesimproveErrorMessage
parent
6b1904d37a
commit
8cb505d6e1
|
@ -34,6 +34,7 @@
|
|||
#include "catalog/pg_am.h"
|
||||
#include "columnar/columnar.h"
|
||||
#include "columnar/columnar_tableam.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "distributed/colocation_utils.h"
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
|
@ -199,6 +200,7 @@ static char * CreateWorkerChangeSequenceDependencyCommand(char *sequenceSchemaNa
|
|||
char *sourceName,
|
||||
char *targetSchemaName,
|
||||
char *targetName);
|
||||
static char * GetAccessMethodForMatViewIfExists(Oid viewOid);
|
||||
static bool WillRecreateForeignKeyToReferenceTable(Oid relationId,
|
||||
CascadeToColocatedOption cascadeOption);
|
||||
static void WarningsForDroppingForeignKeysWithDistributedTables(Oid relationId);
|
||||
|
@ -1126,13 +1128,28 @@ GetViewCreationCommandsOfTable(Oid relationId)
|
|||
char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName);
|
||||
bool isMatView = get_rel_relkind(viewOid) == RELKIND_MATVIEW;
|
||||
|
||||
appendStringInfo(query,
|
||||
"CREATE %s VIEW %s AS %s",
|
||||
isMatView ? "MATERIALIZED" : "",
|
||||
qualifiedViewName,
|
||||
viewDefinition);
|
||||
/* here we need to get the access method of the view to recreate it */
|
||||
char *accessMethodName = GetAccessMethodForMatViewIfExists(viewOid);
|
||||
|
||||
appendStringInfoString(query, "CREATE ");
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
* key to a reference table, if conversion will be cascaded to colocated table this function
|
||||
|
|
|
@ -917,5 +917,32 @@ NOTICE: renaming the new table to alter_distributed_table.partition_lengths_123
|
|||
|
||||
(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;
|
||||
DROP SCHEMA alter_distributed_table CASCADE;
|
||||
|
|
|
@ -308,5 +308,12 @@ ALTER TABLE partition_lengths RENAME TO partition_lengths_1234567890123456789012
|
|||
-- verify alter_distributed_table works with long partitioned table names
|
||||
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;
|
||||
DROP SCHEMA alter_distributed_table CASCADE;
|
||||
|
|
Loading…
Reference in New Issue