mirror of https://github.com/citusdata/citus.git
Adds citus.enable_local_reference_table_foreign_keys
When enabled any foreign keys between local tables and reference tables supported by converting the local table to a citus local table. When the coordinator is not in the metadata, the logic is disabled as foreign keys are not allowed in this configuration.pull/4480/head
parent
ed58a404d5
commit
30d0a65f40
|
@ -42,8 +42,13 @@
|
|||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
/* controlled via GUC, should be accessed via GetEnableLocalReferenceForeignKeys() */
|
||||
bool EnableLocalReferenceForeignKeys = true;
|
||||
|
||||
|
||||
/* Local functions forward declarations for unsupported command checks */
|
||||
static void PostprocessCreateTableStmtForeignKeys(CreateStmt *createStatement);
|
||||
static bool ShouldEnableLocalReferenceForeignKeys(void);
|
||||
static void PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement,
|
||||
const char *queryString);
|
||||
static bool AlterTableDefinesFKeyBetweenPostgresAndNonDistTable(
|
||||
|
@ -84,6 +89,7 @@ static void SetInterShardDDLTaskRelationShardList(Task *task,
|
|||
ShardInterval *leftShardInterval,
|
||||
ShardInterval *rightShardInterval);
|
||||
|
||||
|
||||
/*
|
||||
* We need to run some of the commands sequentially if there is a foreign constraint
|
||||
* from/to reference table.
|
||||
|
@ -194,6 +200,14 @@ PostprocessCreateTableStmt(CreateStmt *createStatement, const char *queryString)
|
|||
static void
|
||||
PostprocessCreateTableStmtForeignKeys(CreateStmt *createStatement)
|
||||
{
|
||||
if (!ShouldEnableLocalReferenceForeignKeys())
|
||||
{
|
||||
/*
|
||||
* Either the user disabled foreign keys from/to local/reference tables
|
||||
* or the coordinator is not in the metadata */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Relation must exist and it is already locked as standard process utility
|
||||
* is already executed.
|
||||
|
@ -227,6 +241,25 @@ PostprocessCreateTableStmtForeignKeys(CreateStmt *createStatement)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* ShouldEnableLocalReferenceForeignKeys is a wrapper around getting the GUC
|
||||
* EnableLocalReferenceForeignKeys. If the coordinator is not added
|
||||
* to the metadata, the function returns false. Else, the function returns
|
||||
* the value set by the user
|
||||
*
|
||||
*/
|
||||
static bool
|
||||
ShouldEnableLocalReferenceForeignKeys(void)
|
||||
{
|
||||
if (!EnableLocalReferenceForeignKeys)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CoordinatorAddedAsWorkerNode();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PostprocessCreateTableStmtPartitionOf processes CREATE TABLE ... PARTITION OF
|
||||
* statements and it checks if user creates the table as a partition of a distributed
|
||||
|
@ -412,8 +445,8 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
|||
leftRelationId = IndexGetRelation(leftRelationId, missingOk);
|
||||
}
|
||||
|
||||
if (processUtilityContext != PROCESS_UTILITY_SUBCOMMAND &&
|
||||
CoordinatorAddedAsWorkerNode() &&
|
||||
if (ShouldEnableLocalReferenceForeignKeys() &&
|
||||
processUtilityContext != PROCESS_UTILITY_SUBCOMMAND &&
|
||||
AlterTableDefinesFKeyBetweenPostgresAndNonDistTable(alterTableStatement))
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -585,6 +585,18 @@ RegisterCitusConfigVariables(void)
|
|||
GUC_STANDARD,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
DefineCustomBoolVariable(
|
||||
"citus.enable_local_reference_table_foreign_keys",
|
||||
gettext_noop("Enables foreign keys from/to local tables"),
|
||||
gettext_noop("When enabled, foreign keys between local tables and reference "
|
||||
"tables supported."),
|
||||
&EnableLocalReferenceForeignKeys,
|
||||
true,
|
||||
PGC_USERSET,
|
||||
GUC_STANDARD,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
|
||||
DefineCustomBoolVariable(
|
||||
"citus.enable_single_hash_repartition_joins",
|
||||
gettext_noop("Enables single hash repartitioning between hash "
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#include "tcop/dest.h"
|
||||
#include "tcop/utility.h"
|
||||
|
||||
|
||||
/* controlled via GUC, should be accessed via EnableLocalReferenceForeignKeys() */
|
||||
extern bool EnableLocalReferenceForeignKeys;
|
||||
|
||||
|
||||
/*
|
||||
* DistributeObjectOps specifies handlers for node/object type pairs.
|
||||
* Instances of this type should all be declared in deparse.c.
|
||||
|
|
|
@ -391,6 +391,28 @@ BEGIN;
|
|||
reference_table_1 | n | t
|
||||
(8 rows)
|
||||
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
-- disable foreign keys to reference tables
|
||||
SET LOCAL citus.enable_local_reference_table_foreign_keys TO false;
|
||||
CREATE TABLE local_table_6 (col_1 INT PRIMARY KEY);
|
||||
ALTER TABLE local_table_2 ADD CONSTRAINT fkey_11 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_1) ON DELETE CASCADE;
|
||||
CREATE TABLE local_table_5 (
|
||||
col_1 INT UNIQUE REFERENCES local_table_6(col_1),
|
||||
col_2 INT REFERENCES local_table_3(col_1),
|
||||
FOREIGN KEY (col_1) REFERENCES local_table_5(col_1),
|
||||
FOREIGN KEY (col_1) REFERENCES reference_table_1(col_1));
|
||||
-- Now show none of local_table_5 & 6 to should be converted to citus local tables
|
||||
-- as it is disabled
|
||||
SELECT logicalrelid::text AS tablename, partmethod, repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid::text IN (SELECT tablename FROM pg_tables WHERE schemaname='fkeys_between_local_ref')
|
||||
ORDER BY tablename;
|
||||
tablename | partmethod | repmodel
|
||||
---------------------------------------------------------------------
|
||||
distributed_table | h | c
|
||||
reference_table_1 | n | t
|
||||
(2 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- this errors out as we don't support creating citus local
|
||||
-- tables from partitioned tables
|
||||
|
|
|
@ -285,6 +285,26 @@ BEGIN;
|
|||
ORDER BY tablename;
|
||||
ROLLBACK;
|
||||
|
||||
BEGIN;
|
||||
-- disable foreign keys to reference tables
|
||||
SET LOCAL citus.enable_local_reference_table_foreign_keys TO false;
|
||||
CREATE TABLE local_table_6 (col_1 INT PRIMARY KEY);
|
||||
|
||||
ALTER TABLE local_table_2 ADD CONSTRAINT fkey_11 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_1) ON DELETE CASCADE;
|
||||
|
||||
CREATE TABLE local_table_5 (
|
||||
col_1 INT UNIQUE REFERENCES local_table_6(col_1),
|
||||
col_2 INT REFERENCES local_table_3(col_1),
|
||||
FOREIGN KEY (col_1) REFERENCES local_table_5(col_1),
|
||||
FOREIGN KEY (col_1) REFERENCES reference_table_1(col_1));
|
||||
|
||||
-- Now show none of local_table_5 & 6 to should be converted to citus local tables
|
||||
-- as it is disabled
|
||||
SELECT logicalrelid::text AS tablename, partmethod, repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid::text IN (SELECT tablename FROM pg_tables WHERE schemaname='fkeys_between_local_ref')
|
||||
ORDER BY tablename;
|
||||
ROLLBACK;
|
||||
|
||||
-- this errors out as we don't support creating citus local
|
||||
-- tables from partitioned tables
|
||||
CREATE TABLE part_local_table (col_1 INT REFERENCES reference_table_1(col_1)) PARTITION BY RANGE (col_1);
|
||||
|
|
Loading…
Reference in New Issue