Introduce UDFs for fixing partitioned table constraint names

pull/4410/head
Hanefi Önaldı 2021-01-28 16:59:27 +03:00 committed by Hanefi Önaldı
parent 92cf49b7e9
commit cab17afce9
24 changed files with 514 additions and 17 deletions

View File

@ -67,3 +67,6 @@ DROP FUNCTION pg_catalog.master_create_worker_shards(text, integer, integer);
DROP FUNCTION pg_catalog.mark_tables_colocated(regclass, regclass[]); DROP FUNCTION pg_catalog.mark_tables_colocated(regclass, regclass[]);
#include "udfs/citus_shard_sizes/10.0-1.sql" #include "udfs/citus_shard_sizes/10.0-1.sql"
#include "udfs/citus_shards/10.0-1.sql" #include "udfs/citus_shards/10.0-1.sql"
#include "udfs/fix_pre_citus10_partitioned_table_constraint_names/10.0-1.sql"
#include "udfs/worker_fix_pre_citus10_partitioned_table_constraint_names/10.0-1.sql"

View File

@ -108,3 +108,7 @@ DROP FUNCTION pg_catalog.remove_local_tables_from_metadata();
#include "../udfs/create_citus_local_table/9.5-1.sql" #include "../udfs/create_citus_local_table/9.5-1.sql"
DROP VIEW pg_catalog.citus_shards CASCADE; DROP VIEW pg_catalog.citus_shards CASCADE;
DROP FUNCTION pg_catalog.citus_shard_sizes(OUT table_name text, OUT size bigint); DROP FUNCTION pg_catalog.citus_shard_sizes(OUT table_name text, OUT size bigint);
DROP FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names();
DROP FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names(regclass);
DROP FUNCTION pg_catalog.worker_fix_pre_citus10_partitioned_table_constraint_names(regclass,bigint,text);

View File

@ -0,0 +1,29 @@
CREATE FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names(table_name regclass)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$fix_pre_citus10_partitioned_table_constraint_names$$;
COMMENT ON FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names(table_name regclass)
IS 'fix constraint names on partition shards';
CREATE OR REPLACE FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names()
RETURNS SETOF regclass
LANGUAGE plpgsql
AS $$
DECLARE
oid regclass;
BEGIN
FOR oid IN SELECT c.oid
FROM pg_dist_partition p
JOIN pg_class c ON p.logicalrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.relkind = 'p'
ORDER BY n.nspname, c.relname
LOOP
EXECUTE 'SELECT fix_pre_citus10_partitioned_table_constraint_names( ' || quote_literal(oid) || ' )';
RETURN NEXT oid;
END LOOP;
RETURN;
END;
$$;
COMMENT ON FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names()
IS 'fix constraint names on all partition shards';

View File

@ -0,0 +1,29 @@
CREATE FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names(table_name regclass)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$fix_pre_citus10_partitioned_table_constraint_names$$;
COMMENT ON FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names(table_name regclass)
IS 'fix constraint names on partition shards';
CREATE OR REPLACE FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names()
RETURNS SETOF regclass
LANGUAGE plpgsql
AS $$
DECLARE
oid regclass;
BEGIN
FOR oid IN SELECT c.oid
FROM pg_dist_partition p
JOIN pg_class c ON p.logicalrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE c.relkind = 'p'
ORDER BY n.nspname, c.relname
LOOP
EXECUTE 'SELECT fix_pre_citus10_partitioned_table_constraint_names( ' || quote_literal(oid) || ' )';
RETURN NEXT oid;
END LOOP;
RETURN;
END;
$$;
COMMENT ON FUNCTION pg_catalog.fix_pre_citus10_partitioned_table_constraint_names()
IS 'fix constraint names on all partition shards';

View File

@ -0,0 +1,10 @@
CREATE FUNCTION pg_catalog.worker_fix_pre_citus10_partitioned_table_constraint_names(table_name regclass,
shardid bigint,
constraint_name text)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$worker_fix_pre_citus10_partitioned_table_constraint_names$$;
COMMENT ON FUNCTION pg_catalog.worker_fix_pre_citus10_partitioned_table_constraint_names(table_name regclass,
shardid bigint,
constraint_name text)
IS 'fix constraint names on partition shards on worker nodes';

View File

@ -0,0 +1,10 @@
CREATE FUNCTION pg_catalog.worker_fix_pre_citus10_partitioned_table_constraint_names(table_name regclass,
shardid bigint,
constraint_name text)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$worker_fix_pre_citus10_partitioned_table_constraint_names$$;
COMMENT ON FUNCTION pg_catalog.worker_fix_pre_citus10_partitioned_table_constraint_names(table_name regclass,
shardid bigint,
constraint_name text)
IS 'fix constraint names on partition shards on worker nodes';

View File

@ -14,13 +14,22 @@
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/partition.h" #include "catalog/partition.h"
#include "catalog/pg_class.h" #include "catalog/pg_class.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "common/string.h"
#include "distributed/citus_nodes.h"
#include "distributed/adaptive_executor.h"
#include "distributed/citus_ruleutils.h" #include "distributed/citus_ruleutils.h"
#include "distributed/colocation_utils.h" #include "distributed/colocation_utils.h"
#include "distributed/commands.h"
#include "distributed/coordinator_protocol.h"
#include "distributed/deparse_shard_query.h"
#include "distributed/listutils.h" #include "distributed/listutils.h"
#include "distributed/metadata_utility.h" #include "distributed/metadata_utility.h"
#include "distributed/coordinator_protocol.h"
#include "distributed/multi_partitioning_utils.h" #include "distributed/multi_partitioning_utils.h"
#include "distributed/multi_physical_planner.h"
#include "distributed/relay_utility.h"
#include "distributed/resource_lock.h"
#include "distributed/shardinterval_utils.h" #include "distributed/shardinterval_utils.h"
#include "distributed/version_compat.h" #include "distributed/version_compat.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
@ -37,6 +46,267 @@
static char * PartitionBound(Oid partitionId); static char * PartitionBound(Oid partitionId);
static Relation try_relation_open_nolock(Oid relationId); static Relation try_relation_open_nolock(Oid relationId);
static List * CreateFixPartitionConstraintsTaskList(Oid relationId);
static List * WorkerFixPartitionConstraintCommandList(Oid relationId, uint64 shardId,
List *checkConstraintList);
static List * CheckConstraintNameListForRelation(Oid relationId);
static bool RelationHasConstraint(Oid relationId, char *constraintName);
static char * RenameConstraintCommand(Oid relationId, char *constraintName,
char *newConstraintName);
PG_FUNCTION_INFO_V1(fix_pre_citus10_partitioned_table_constraint_names);
PG_FUNCTION_INFO_V1(worker_fix_pre_citus10_partitioned_table_constraint_names);
/*
* fix_pre_citus10_partitioned_table_constraint_names fixes the constraint names of
* partitioned table shards on workers.
*
* Constraint names for partitioned table shards should have shardId suffixes if and only
* if they are unique or foreign key constraints. We mistakenly appended shardIds to
* constraint names on ALTER TABLE dist_part_table ADD CONSTRAINT .. queries prior to
* Citus 10. fix_pre_citus10_partitioned_table_constraint_names determines if this is the
* case, and renames constraints back to their original names on shards.
*/
Datum
fix_pre_citus10_partitioned_table_constraint_names(PG_FUNCTION_ARGS)
{
Oid relationId = PG_GETARG_OID(0);
EnsureCoordinator();
if (!PartitionedTable(relationId))
{
ereport(ERROR, (errmsg("could not fix partition constraints: "
"relation does not exist or is not partitioned")));
}
if (!IsCitusTable(relationId))
{
ereport(ERROR, (errmsg("fix_pre_citus10_partitioned_table_constraint_names can "
"only be called for distributed partitioned tables")));
}
List *taskList = CreateFixPartitionConstraintsTaskList(relationId);
bool localExecutionSupported = true;
ExecuteUtilityTaskList(taskList, localExecutionSupported);
PG_RETURN_VOID();
}
/*
* worker_fix_pre_citus10_partitioned_table_constraint_names fixes the constraint names on a worker given a shell
* table name and shard id.
*/
Datum
worker_fix_pre_citus10_partitioned_table_constraint_names(PG_FUNCTION_ARGS)
{
Oid relationId = PG_GETARG_OID(0);
int64 shardId = PG_GETARG_INT32(1);
text *constraintNameText = PG_GETARG_TEXT_P(2);
if (!PartitionedTable(relationId))
{
ereport(ERROR, (errmsg("could not fix partition constraints: "
"relation does not exist or is not partitioned")));
}
char *constraintName = text_to_cstring(constraintNameText);
char *shardIdAppendedConstraintName = pstrdup(constraintName);
AppendShardIdToName(&shardIdAppendedConstraintName, shardId);
/* if shardId was appended to the constraint name, rename back to original */
if (RelationHasConstraint(relationId, shardIdAppendedConstraintName))
{
char *renameConstraintDDLCommand =
RenameConstraintCommand(relationId, shardIdAppendedConstraintName,
constraintName);
ExecuteAndLogUtilityCommand(renameConstraintDDLCommand);
}
PG_RETURN_VOID();
}
/*
* CreateFixPartitionConstraintsTaskList goes over all the partitions of a distributed
* partitioned table, and creates the list of tasks to execute
* worker_fix_pre_citus10_partitioned_table_constraint_names UDF on worker nodes.
*/
static List *
CreateFixPartitionConstraintsTaskList(Oid relationId)
{
List *taskList = NIL;
/* enumerate the tasks when putting them to the taskList */
int taskId = 1;
List *checkConstraintList = CheckConstraintNameListForRelation(relationId);
/* early exit if the relation does not have any check constraints */
if (checkConstraintList == NIL)
{
return NIL;
}
List *shardIntervalList = LoadShardIntervalList(relationId);
/* lock metadata before getting placement lists */
LockShardListMetadata(shardIntervalList, ShareLock);
ShardInterval *shardInterval = NULL;
foreach_ptr(shardInterval, shardIntervalList)
{
uint64 shardId = shardInterval->shardId;
List *queryStringList = WorkerFixPartitionConstraintCommandList(relationId,
shardId,
checkConstraintList);
Task *task = CitusMakeNode(Task);
task->jobId = INVALID_JOB_ID;
task->taskId = taskId++;
task->taskType = DDL_TASK;
SetTaskQueryStringList(task, queryStringList);
task->dependentTaskList = NULL;
task->replicationModel = REPLICATION_MODEL_INVALID;
task->anchorShardId = shardId;
task->taskPlacementList = ActiveShardPlacementList(shardId);
taskList = lappend(taskList, task);
}
return taskList;
}
/*
* CheckConstraintNameListForRelation returns a list of names of CHECK constraints
* for a relation.
*/
static List *
CheckConstraintNameListForRelation(Oid relationId)
{
List *constraintNameList = NIL;
int scanKeyCount = 2;
ScanKeyData scanKey[2];
Relation pgConstraint = table_open(ConstraintRelationId, AccessShareLock);
ScanKeyInit(&scanKey[0], Anum_pg_constraint_conrelid,
BTEqualStrategyNumber, F_OIDEQ, relationId);
ScanKeyInit(&scanKey[1], Anum_pg_constraint_contype,
BTEqualStrategyNumber, F_CHAREQ, CONSTRAINT_CHECK);
bool useIndex = false;
SysScanDesc scanDescriptor = systable_beginscan(pgConstraint, InvalidOid, useIndex,
NULL, scanKeyCount, scanKey);
HeapTuple heapTuple = systable_getnext(scanDescriptor);
while (HeapTupleIsValid(heapTuple))
{
Form_pg_constraint constraintForm = (Form_pg_constraint) GETSTRUCT(heapTuple);
char *constraintName = NameStr(constraintForm->conname);
constraintNameList = lappend(constraintNameList, pstrdup(constraintName));
heapTuple = systable_getnext(scanDescriptor);
}
systable_endscan(scanDescriptor);
table_close(pgConstraint, NoLock);
return constraintNameList;
}
/*
* WorkerFixPartitionConstraintCommandList creates a list of queries that will fix
* all check constraint names of a shard.
*/
static List *
WorkerFixPartitionConstraintCommandList(Oid relationId, uint64 shardId,
List *checkConstraintList)
{
List *commandList = NIL;
Oid schemaId = get_rel_namespace(relationId);
char *schemaName = get_namespace_name(schemaId);
char *relationName = get_rel_name(relationId);
char *shardRelationName = pstrdup(relationName);
/* build shard relation name */
AppendShardIdToName(&shardRelationName, shardId);
char *quotedShardName = quote_qualified_identifier(schemaName, shardRelationName);
char *constraintName = NULL;
foreach_ptr(constraintName, checkConstraintList)
{
StringInfo shardQueryString = makeStringInfo();
appendStringInfo(shardQueryString,
"SELECT worker_fix_pre_citus10_partitioned_table_constraint_names(%s::regclass, "
UINT64_FORMAT ", %s::text)",
quote_literal_cstr(quotedShardName), shardId,
quote_literal_cstr(constraintName));
commandList = lappend(commandList, shardQueryString->data);
}
return commandList;
}
/*
* RelationHasConstraint checks if a relation has a constraint with a given name.
*/
static bool
RelationHasConstraint(Oid relationId, char *constraintName)
{
bool found = false;
int scanKeyCount = 2;
ScanKeyData scanKey[2];
Relation pgConstraint = table_open(ConstraintRelationId, AccessShareLock);
ScanKeyInit(&scanKey[0], Anum_pg_constraint_conrelid,
BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relationId));
ScanKeyInit(&scanKey[1], Anum_pg_constraint_conname,
BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(constraintName));
bool useIndex = false;
SysScanDesc scanDescriptor = systable_beginscan(pgConstraint, InvalidOid, useIndex,
NULL, scanKeyCount, scanKey);
HeapTuple heapTuple = systable_getnext(scanDescriptor);
if (HeapTupleIsValid(heapTuple))
{
found = true;
}
systable_endscan(scanDescriptor);
table_close(pgConstraint, NoLock);
return found;
}
/*
* RenameConstraintCommand creates the query string that will rename a constraint
*/
static char *
RenameConstraintCommand(Oid relationId, char *constraintName, char *newConstraintName)
{
char *qualifiedRelationName = generate_qualified_relation_name(relationId);
const char *quotedConstraintName = quote_identifier(constraintName);
const char *quotedNewConstraintName = quote_identifier(newConstraintName);
StringInfo renameCommand = makeStringInfo();
appendStringInfo(renameCommand, "ALTER TABLE %s RENAME CONSTRAINT %s TO %s",
qualifiedRelationName, quotedConstraintName,
quotedNewConstraintName);
return renameCommand->data;
}
/* /*
* Returns true if the given relation is a partitioned table. * Returns true if the given relation is a partitioned table.

View File

@ -25,6 +25,8 @@ extern char * GenerateDetachPartitionCommand(Oid partitionTableId);
extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval); extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval);
extern char * GenerateAlterTableAttachPartitionCommand(Oid partitionTableId); extern char * GenerateAlterTableAttachPartitionCommand(Oid partitionTableId);
extern char * GeneratePartitioningInformation(Oid tableId); extern char * GeneratePartitioningInformation(Oid tableId);
extern void FixPartitionConstraintsOnWorkers(Oid relationId);
extern void FixLocalPartitionConstraints(Oid relationId, int64 shardId);
#endif /* MULTI_PARTITIONING_UTILS_H_ */ #endif /* MULTI_PARTITIONING_UTILS_H_ */

View File

@ -1,4 +1,5 @@
# this schedule is to be run only on coordinators # this schedule is to be run only on coordinators
test: upgrade_basic_after test: upgrade_basic_after
test: upgrade_partition_constraints_after
test: upgrade_pg_dist_object_test_after test: upgrade_pg_dist_object_test_after

View File

@ -1,4 +1,5 @@
# this schedule is to be run on only coordinators # this schedule is to be run on only coordinators
test: upgrade_basic_before test: upgrade_basic_before
test: upgrade_partition_constraints_before
test: upgrade_pg_dist_object_test_before test: upgrade_pg_dist_object_test_before

View File

@ -204,3 +204,6 @@ s/ERROR: cannot append to shardId [0-9]+/ERROR: cannot append to shardId xxxxx
# hide warning/hint message that we get when executing create_citus_local_table # hide warning/hint message that we get when executing create_citus_local_table
/local tables that are added to metadata but not chained with reference tables via foreign keys might be automatically converted back to postgres tables$/d /local tables that are added to metadata but not chained with reference tables via foreign keys might be automatically converted back to postgres tables$/d
/Consider setting citus.enable_local_reference_table_foreign_keys to 'off' to disable this behavior$/d /Consider setting citus.enable_local_reference_table_foreign_keys to 'off' to disable this behavior$/d
# normalize partitioned table shard constraint name errors for upgrade_partition_constraints_(before|after)
s/^(ERROR: child table is missing constraint "\w+)_([0-9])+"/\1_xxxxxx"/g

View File

@ -448,7 +448,7 @@ SELECT * FROM print_extension_changes();
--------------------------------------------------------------------- ---------------------------------------------------------------------
function citus_total_relation_size(regclass) | function citus_total_relation_size(regclass) |
function create_citus_local_table(regclass) | function create_citus_local_table(regclass) |
function mark_tables_colocated(regclass, regclass[]) | function mark_tables_colocated(regclass,regclass[]) |
function master_conninfo_cache_invalidate() | function master_conninfo_cache_invalidate() |
function master_create_distributed_table(regclass,text,citus.distribution_type) | function master_create_distributed_table(regclass,text,citus.distribution_type) |
function master_create_worker_shards(text,integer,integer) | function master_create_worker_shards(text,integer,integer) |
@ -496,11 +496,14 @@ SELECT * FROM print_extension_changes();
| function citus_update_shard_statistics(bigint) | function citus_update_shard_statistics(bigint)
| function citus_update_table_statistics(regclass) | function citus_update_table_statistics(regclass)
| function columnar.columnar_handler(internal) | function columnar.columnar_handler(internal)
| function fix_pre_citus10_partitioned_table_constraint_names()
| function fix_pre_citus10_partitioned_table_constraint_names(regclass)
| function notify_constraint_dropped() | function notify_constraint_dropped()
| function remove_local_tables_from_metadata() | function remove_local_tables_from_metadata()
| function time_partition_range(regclass) | function time_partition_range(regclass)
| function undistribute_table(regclass,boolean) | function undistribute_table(regclass,boolean)
| function worker_change_sequence_dependency(regclass,regclass,regclass) | function worker_change_sequence_dependency(regclass,regclass,regclass)
| function worker_fix_pre_citus10_partitioned_table_constraint_names(regclass,bigint,text)
| schema columnar | schema columnar
| sequence columnar.storageid_seq | sequence columnar.storageid_seq
| table columnar.chunk | table columnar.chunk
@ -509,7 +512,7 @@ SELECT * FROM print_extension_changes();
| view citus_shards | view citus_shards
| view citus_tables | view citus_tables
| view time_partitions | view time_partitions
(63 rows) (66 rows)
DROP TABLE prev_objects, extension_diff; DROP TABLE prev_objects, extension_diff;
-- show running version -- show running version

View File

@ -448,7 +448,7 @@ SELECT * FROM print_extension_changes();
--------------------------------------------------------------------- ---------------------------------------------------------------------
function citus_total_relation_size(regclass) | function citus_total_relation_size(regclass) |
function create_citus_local_table(regclass) | function create_citus_local_table(regclass) |
function mark_tables_colocated(regclass, regclass[]) | function mark_tables_colocated(regclass,regclass[]) |
function master_conninfo_cache_invalidate() | function master_conninfo_cache_invalidate() |
function master_create_distributed_table(regclass,text,citus.distribution_type) | function master_create_distributed_table(regclass,text,citus.distribution_type) |
function master_create_worker_shards(text,integer,integer) | function master_create_worker_shards(text,integer,integer) |
@ -492,11 +492,14 @@ SELECT * FROM print_extension_changes();
| function citus_update_node(integer,text,integer,boolean,integer) | function citus_update_node(integer,text,integer,boolean,integer)
| function citus_update_shard_statistics(bigint) | function citus_update_shard_statistics(bigint)
| function citus_update_table_statistics(regclass) | function citus_update_table_statistics(regclass)
| function fix_pre_citus10_partitioned_table_constraint_names()
| function fix_pre_citus10_partitioned_table_constraint_names(regclass)
| function notify_constraint_dropped() | function notify_constraint_dropped()
| function remove_local_tables_from_metadata() | function remove_local_tables_from_metadata()
| function time_partition_range(regclass) | function time_partition_range(regclass)
| function undistribute_table(regclass,boolean) | function undistribute_table(regclass,boolean)
| function worker_change_sequence_dependency(regclass,regclass,regclass) | function worker_change_sequence_dependency(regclass,regclass,regclass)
| function worker_fix_pre_citus10_partitioned_table_constraint_names(regclass,bigint,text)
| schema columnar | schema columnar
| sequence columnar.storageid_seq | sequence columnar.storageid_seq
| table columnar.chunk | table columnar.chunk
@ -505,7 +508,7 @@ SELECT * FROM print_extension_changes();
| view citus_shards | view citus_shards
| view citus_tables | view citus_tables
| view time_partitions | view time_partitions
(59 rows) (62 rows)
DROP TABLE prev_objects, extension_diff; DROP TABLE prev_objects, extension_diff;
-- show running version -- show running version

View File

@ -1988,6 +1988,28 @@ CREATE TABLE IF NOT EXISTS partition_of_other_table PARTITION OF partitioning_te
NOTICE: relation "partition_of_other_table" already exists, skipping NOTICE: relation "partition_of_other_table" already exists, skipping
ALTER TABLE another_table DETACH PARTITION partition_of_other_table; ALTER TABLE another_table DETACH PARTITION partition_of_other_table;
DROP TABLE another_table, partition_of_other_table; DROP TABLE another_table, partition_of_other_table;
-- test fix_pre_citus10_partitioned_table_constraint_names udf
SELECT fix_pre_citus10_partitioned_table_constraint_names('partitioning_test');
fix_pre_citus10_partitioned_table_constraint_names
---------------------------------------------------------------------
(1 row)
SELECT fix_pre_citus10_partitioned_table_constraint_names();
fix_pre_citus10_partitioned_table_constraint_names
---------------------------------------------------------------------
partitioning_test
"schema-test"
public.partitioning_hash_join_test
public.partitioning_hash_test
public.partitioning_test_failure
(5 rows)
-- the following should fail
SELECT fix_pre_citus10_partitioned_table_constraint_names('public.non_distributed_partitioned_table');
ERROR: fix_pre_citus10_partitioned_table_constraint_names can only be called for distributed partitioned tables
SELECT fix_pre_citus10_partitioned_table_constraint_names('reference_table');
ERROR: could not fix partition constraints: relation does not exist or is not partitioned
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008; ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008;
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009; ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009;
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010; ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010;

View File

@ -276,7 +276,7 @@ SELECT public.generate_partition_information('partition_child_1_schema.child_1')
ERROR: "child_1" is not a parent table ERROR: "child_1" is not a parent table
SELECT public.print_partitions('partition_child_1_schema.child_1'); SELECT public.print_partitions('partition_child_1_schema.child_1');
ERROR: "child_1" is not a parent table ERROR: "child_1" is not a parent table
-- now pring the partitions -- now print the partitions
SELECT public.print_partitions('parent_table'); SELECT public.print_partitions('parent_table');
print_partitions print_partitions
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -112,6 +112,8 @@ ORDER BY 1;
function dump_global_wait_edges() function dump_global_wait_edges()
function dump_local_wait_edges() function dump_local_wait_edges()
function fetch_intermediate_results(text[],text,integer) function fetch_intermediate_results(text[],text,integer)
function fix_pre_citus10_partitioned_table_constraint_names()
function fix_pre_citus10_partitioned_table_constraint_names(regclass)
function get_all_active_transactions() function get_all_active_transactions()
function get_colocated_shard_array(bigint) function get_colocated_shard_array(bigint)
function get_colocated_table_array(regclass) function get_colocated_table_array(regclass)
@ -188,6 +190,7 @@ ORDER BY 1;
function worker_drop_distributed_table(text) function worker_drop_distributed_table(text)
function worker_fetch_foreign_file(text,text,bigint,text[],integer[]) function worker_fetch_foreign_file(text,text,bigint,text[],integer[])
function worker_fetch_partition_file(bigint,integer,integer,integer,text,integer) function worker_fetch_partition_file(bigint,integer,integer,integer,text,integer)
function worker_fix_pre_citus10_partitioned_table_constraint_names(regclass,bigint,text)
function worker_hash("any") function worker_hash("any")
function worker_hash_partition_table(bigint,integer,text,text,oid,anyarray) function worker_hash_partition_table(bigint,integer,text,text,oid,anyarray)
function worker_last_saved_explain_analyze() function worker_last_saved_explain_analyze()
@ -238,5 +241,5 @@ ORDER BY 1;
view citus_worker_stat_activity view citus_worker_stat_activity
view pg_dist_shard_placement view pg_dist_shard_placement
view time_partitions view time_partitions
(222 rows) (225 rows)

View File

@ -108,6 +108,8 @@ ORDER BY 1;
function dump_global_wait_edges() function dump_global_wait_edges()
function dump_local_wait_edges() function dump_local_wait_edges()
function fetch_intermediate_results(text[],text,integer) function fetch_intermediate_results(text[],text,integer)
function fix_pre_citus10_partitioned_table_constraint_names()
function fix_pre_citus10_partitioned_table_constraint_names(regclass)
function get_all_active_transactions() function get_all_active_transactions()
function get_colocated_shard_array(bigint) function get_colocated_shard_array(bigint)
function get_colocated_table_array(regclass) function get_colocated_table_array(regclass)
@ -184,6 +186,7 @@ ORDER BY 1;
function worker_drop_distributed_table(text) function worker_drop_distributed_table(text)
function worker_fetch_foreign_file(text,text,bigint,text[],integer[]) function worker_fetch_foreign_file(text,text,bigint,text[],integer[])
function worker_fetch_partition_file(bigint,integer,integer,integer,text,integer) function worker_fetch_partition_file(bigint,integer,integer,integer,text,integer)
function worker_fix_pre_citus10_partitioned_table_constraint_names(regclass,bigint,text)
function worker_hash("any") function worker_hash("any")
function worker_hash_partition_table(bigint,integer,text,text,oid,anyarray) function worker_hash_partition_table(bigint,integer,text,text,oid,anyarray)
function worker_last_saved_explain_analyze() function worker_last_saved_explain_analyze()
@ -234,5 +237,5 @@ ORDER BY 1;
view citus_worker_stat_activity view citus_worker_stat_activity
view pg_dist_shard_placement view pg_dist_shard_placement
view time_partitions view time_partitions
(218 rows) (221 rows)

View File

@ -0,0 +1,19 @@
-- test cases for #3970
SET search_path = test_3970;
--5. add a partition
-- This command will fail as the child table has a wrong constraint name
CREATE TABLE part_table_p202009 PARTITION OF part_table FOR VALUES FROM ('2020-09-01 00:00:00') TO ('2020-10-01 00:00:00');
ERROR: child table is missing constraint "ck_01234567890123456789012345678901234567890123_8478db72_xxxxxx"
CONTEXT: while executing command on localhost:xxxxx
-- fix constraint names on partitioned table shards
SELECT fix_pre_citus10_partitioned_table_constraint_names('part_table'::regclass);
fix_pre_citus10_partitioned_table_constraint_names
---------------------------------------------------------------------
(1 row)
--5. add a partition
CREATE TABLE part_table_p202009 PARTITION OF part_table FOR VALUES FROM ('2020-09-01 00:00:00') TO ('2020-10-01 00:00:00');
RESET search_path;
DROP SCHEMA test_3970 CASCADE;
NOTICE: drop cascades to table test_3970.part_table

View File

@ -0,0 +1,30 @@
-- test cases for #3970
CREATE SCHEMA test_3970;
SET search_path = test_3970;
--1. create a partitioned table
CREATE TABLE part_table (
work_ymdt timestamp without time zone NOT NULL,
seq bigint NOT NULL,
my_seq bigint NOT NULL,
work_memo character varying(150),
CONSTRAINT work_memo_check CHECK ((octet_length((work_memo)::text) <= 150))
)
PARTITION BY RANGE (work_ymdt);
--2. perform create_distributed_table
SELECT create_distributed_table('part_table', 'seq');
create_distributed_table
---------------------------------------------------------------------
(1 row)
--3. add a partition
CREATE TABLE part_table_p202008 PARTITION OF part_table FOR VALUES FROM ('2020-08-01 00:00:00') TO ('2020-09-01 00:00:00');
--4. add a check constraint
ALTER TABLE part_table ADD CONSTRAINT my_seq CHECK (my_seq > 0);
--5. add a partition
-- This command will fail as the child table has a wrong constraint name
CREATE TABLE part_table_p202009 PARTITION OF part_table FOR VALUES FROM ('2020-09-01 00:00:00') TO ('2020-10-01 00:00:00');
ERROR: child table is missing constraint "my_seq_xxxxxx"
CONTEXT: while executing command on localhost:xxxxx
-- Add another constraint with a long name that will get truncated with a hash
ALTER TABLE part_table ADD CONSTRAINT ck_012345678901234567890123456789012345678901234567890123456789 CHECK (my_seq > 0);

View File

@ -62,7 +62,7 @@ test: ensure_no_intermediate_data_leak
# ---------- # ----------
# Tests for partitioning support # Tests for partitioning support
# ---------- # ----------
test: multi_partitioning_utils multi_partitioning replicated_partitioned_table test: multi_partitioning_utils multi_partitioning partitioning_issue_3970 replicated_partitioned_table
# ---------- # ----------
# Tests for foreign data wrapper support # Tests for foreign data wrapper support

View File

@ -1177,6 +1177,14 @@ CREATE TABLE IF NOT EXISTS partition_of_other_table PARTITION OF partitioning_te
ALTER TABLE another_table DETACH PARTITION partition_of_other_table; ALTER TABLE another_table DETACH PARTITION partition_of_other_table;
DROP TABLE another_table, partition_of_other_table; DROP TABLE another_table, partition_of_other_table;
-- test fix_pre_citus10_partitioned_table_constraint_names udf
SELECT fix_pre_citus10_partitioned_table_constraint_names('partitioning_test');
SELECT fix_pre_citus10_partitioned_table_constraint_names();
-- the following should fail
SELECT fix_pre_citus10_partitioned_table_constraint_names('public.non_distributed_partitioned_table');
SELECT fix_pre_citus10_partitioned_table_constraint_names('reference_table');
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008; ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008;
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009; ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009;
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010; ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010;

View File

@ -183,7 +183,7 @@ SELECT public.generate_alter_table_attach_partition_command('parent_table');
SELECT public.generate_partition_information('partition_child_1_schema.child_1'); SELECT public.generate_partition_information('partition_child_1_schema.child_1');
SELECT public.print_partitions('partition_child_1_schema.child_1'); SELECT public.print_partitions('partition_child_1_schema.child_1');
-- now pring the partitions -- now print the partitions
SELECT public.print_partitions('parent_table'); SELECT public.print_partitions('parent_table');
SET search_path = 'public'; SET search_path = 'public';

View File

@ -0,0 +1,15 @@
-- test cases for #3970
SET search_path = test_3970;
--5. add a partition
-- This command will fail as the child table has a wrong constraint name
CREATE TABLE part_table_p202009 PARTITION OF part_table FOR VALUES FROM ('2020-09-01 00:00:00') TO ('2020-10-01 00:00:00');
-- fix constraint names on partitioned table shards
SELECT fix_pre_citus10_partitioned_table_constraint_names('part_table'::regclass);
--5. add a partition
CREATE TABLE part_table_p202009 PARTITION OF part_table FOR VALUES FROM ('2020-09-01 00:00:00') TO ('2020-10-01 00:00:00');
RESET search_path;
DROP SCHEMA test_3970 CASCADE;

View File

@ -0,0 +1,29 @@
-- test cases for #3970
CREATE SCHEMA test_3970;
SET search_path = test_3970;
--1. create a partitioned table
CREATE TABLE part_table (
work_ymdt timestamp without time zone NOT NULL,
seq bigint NOT NULL,
my_seq bigint NOT NULL,
work_memo character varying(150),
CONSTRAINT work_memo_check CHECK ((octet_length((work_memo)::text) <= 150))
)
PARTITION BY RANGE (work_ymdt);
--2. perform create_distributed_table
SELECT create_distributed_table('part_table', 'seq');
--3. add a partition
CREATE TABLE part_table_p202008 PARTITION OF part_table FOR VALUES FROM ('2020-08-01 00:00:00') TO ('2020-09-01 00:00:00');
--4. add a check constraint
ALTER TABLE part_table ADD CONSTRAINT my_seq CHECK (my_seq > 0);
--5. add a partition
-- This command will fail as the child table has a wrong constraint name
CREATE TABLE part_table_p202009 PARTITION OF part_table FOR VALUES FROM ('2020-09-01 00:00:00') TO ('2020-10-01 00:00:00');
-- Add another constraint with a long name that will get truncated with a hash
ALTER TABLE part_table ADD CONSTRAINT ck_012345678901234567890123456789012345678901234567890123456789 CHECK (my_seq > 0);