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 "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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue