Give hint to use ref table for unsupported fkeys between citus local & ref (#4501)

pull/4387/head
Onur Tirtir 2021-01-13 15:33:46 +03:00 committed by GitHub
parent 724d56f949
commit 1299895e71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 6 deletions

View File

@ -46,6 +46,11 @@
((x) == FKCONSTR_ACTION_NOACTION || (x) == FKCONSTR_ACTION_RESTRICT) ((x) == FKCONSTR_ACTION_NOACTION || (x) == FKCONSTR_ACTION_RESTRICT)
#define USE_CREATE_REFERENCE_TABLE_HINT \
"You could use SELECT create_reference_table('%s') " \
"to replicate the referenced table to all nodes"
typedef bool (*CheckRelationFunc)(Oid); typedef bool (*CheckRelationFunc)(Oid);
@ -57,7 +62,8 @@ static void EnsureSupportedFKeyBetweenCitusLocalAndRefTable(Form_pg_constraint
char char
referencingReplicationModel, referencingReplicationModel,
char char
referencedReplicationModel); referencedReplicationModel,
Oid referencedTableId);
static bool HeapTupleOfForeignConstraintIncludesColumn(HeapTuple heapTuple, static bool HeapTupleOfForeignConstraintIncludesColumn(HeapTuple heapTuple,
Oid relationId, Oid relationId,
int pgConstraintKey, int pgConstraintKey,
@ -167,8 +173,7 @@ ErrorIfUnsupportedForeignConstraintExists(Relation relation, char referencingDis
errdetail("To enforce foreign keys, the referencing and " errdetail("To enforce foreign keys, the referencing and "
"referenced rows need to be stored on the same " "referenced rows need to be stored on the same "
"node."), "node."),
errhint("You could use SELECT create_reference_table('%s') " errhint(USE_CREATE_REFERENCE_TABLE_HINT,
"to replicate the referenced table to all nodes",
referencedTableName))); referencedTableName)));
} }
@ -201,7 +206,8 @@ ErrorIfUnsupportedForeignConstraintExists(Relation relation, char referencingDis
{ {
EnsureSupportedFKeyBetweenCitusLocalAndRefTable(constraintForm, EnsureSupportedFKeyBetweenCitusLocalAndRefTable(constraintForm,
referencingReplicationModel, referencingReplicationModel,
referencedReplicationModel); referencedReplicationModel,
referencedTableId);
ReleaseSysCache(heapTuple); ReleaseSysCache(heapTuple);
continue; continue;
@ -304,7 +310,8 @@ ErrorIfUnsupportedForeignConstraintExists(Relation relation, char referencingDis
static void static void
EnsureSupportedFKeyBetweenCitusLocalAndRefTable(Form_pg_constraint fKeyConstraintForm, EnsureSupportedFKeyBetweenCitusLocalAndRefTable(Form_pg_constraint fKeyConstraintForm,
char referencingReplicationModel, char referencingReplicationModel,
char referencedReplicationModel) char referencedReplicationModel,
Oid referencedTableId)
{ {
bool referencingIsReferenceTable = bool referencingIsReferenceTable =
(referencingReplicationModel == REPLICATION_MODEL_2PC); (referencingReplicationModel == REPLICATION_MODEL_2PC);
@ -324,11 +331,14 @@ EnsureSupportedFKeyBetweenCitusLocalAndRefTable(Form_pg_constraint fKeyConstrain
if (!(BehaviorIsRestrictOrNoAction(fKeyConstraintForm->confdeltype) && if (!(BehaviorIsRestrictOrNoAction(fKeyConstraintForm->confdeltype) &&
BehaviorIsRestrictOrNoAction(fKeyConstraintForm->confupdtype))) BehaviorIsRestrictOrNoAction(fKeyConstraintForm->confupdtype)))
{ {
char *referencedTableName = get_rel_name(referencedTableId);
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot define foreign key constraint, " errmsg("cannot define foreign key constraint, "
"foreign keys from reference tables to " "foreign keys from reference tables to "
"citus local tables can only be defined " "citus local tables can only be defined "
"with NO ACTION or RESTRICT behaviors"))); "with NO ACTION or RESTRICT behaviors"),
errhint(USE_CREATE_REFERENCE_TABLE_HINT,
referencedTableName)));
} }
} }
} }