Check table existence in EnsureRelationKindSupported

pull/4246/head
Marco Slot 2020-10-15 12:00:44 +02:00
parent b5a3526c07
commit 31858c8a29
7 changed files with 59 additions and 0 deletions

View File

@ -112,6 +112,7 @@ static void EnsureLocalTableEmptyIfNecessary(Oid relationId, char distributionMe
static bool ShouldLocalTableBeEmpty(Oid relationId, char distributionMethod, bool
viaDeprecatedAPI);
static void EnsureCitusTableCanBeCreated(Oid relationOid);
static void EnsureRelationExists(Oid relationId);
static bool LocalTableEmpty(Oid tableId);
static void CopyLocalDataIntoShards(Oid relationId);
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
@ -323,6 +324,7 @@ undistribute_table(PG_FUNCTION_ARGS)
CheckCitusVersion(ERROR);
EnsureCoordinator();
EnsureRelationExists(relationId);
EnsureTableOwner(relationId);
UndistributeTable(relationId);
@ -341,6 +343,7 @@ static void
EnsureCitusTableCanBeCreated(Oid relationOid)
{
EnsureCoordinator();
EnsureRelationExists(relationOid);
EnsureTableOwner(relationOid);
/*
@ -352,6 +355,22 @@ EnsureCitusTableCanBeCreated(Oid relationOid)
}
/*
* EnsureRelationExists does a basic check on whether the OID belongs to
* an existing relation.
*/
static void
EnsureRelationExists(Oid relationId)
{
if (!RelationExists(relationId))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("relation with OID %d does not exist",
relationId)));
}
}
/*
* CreateDistributedTable creates distributed table in the given configuration.
* This functions contains all necessary logic to create distributed tables. It

View File

@ -478,6 +478,12 @@ void
EnsureRelationKindSupported(Oid relationId)
{
char relationKind = get_rel_relkind(relationId);
if (!relationKind)
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("relation with OID %d does not exist",
relationId)));
}
bool supportedRelationKind = RegularTable(relationId) ||
relationKind == RELKIND_FOREIGN_TABLE;

View File

@ -4262,6 +4262,24 @@ CachedRelationNamespaceLookup(const char *relationName, Oid relnamespace,
}
/*
* RelationExists returns whether a relation with the given OID exists.
*/
bool
RelationExists(Oid relationId)
{
HeapTuple relTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relationId));
bool relationExists = HeapTupleIsValid(relTuple);
if (relationExists)
{
ReleaseSysCache(relTuple);
}
return relationExists;
}
/*
* Register a relcache invalidation for a non-shared relation.
*

View File

@ -189,6 +189,7 @@ extern bool MajorVersionsCompatible(char *leftVersion, char *rightVersion);
extern void ErrorIfInconsistentShardIntervals(CitusTableCacheEntry *cacheEntry);
extern void EnsureModificationsCanRun(void);
extern char LookupDistributionMethod(Oid distributionMethodOid);
extern bool RelationExists(Oid relationId);
/* access WorkerNodeHash */
extern HTAB * GetWorkerNodeHash(void);

View File

@ -159,3 +159,6 @@ s/failed to roll back prepared transaction '.*'/failed to roll back prepared tra
# Errors with binary decoding where OIDs should be normalized
s/wrong data type: [0-9]+, expected [0-9]+/wrong data type: XXXX, expected XXXX/g
# Errors with relation OID does not exist
s/relation with OID [0-9]+ does not exist/relation with OID XXXX does not exist/g

View File

@ -31,6 +31,14 @@ SELECT * FROM dist_table ORDER BY 1, 2, 3;
2 | 3 | abcd
(3 rows)
-- we cannot immediately convert in the same statement, because
-- the name->OID conversion happens at parse time.
SELECT undistribute_table('dist_table'), create_distributed_table('dist_table', 'a');
NOTICE: Creating a new local table for undistribute_table.dist_table
NOTICE: Moving the data of undistribute_table.dist_table
NOTICE: Dropping the old undistribute_table.dist_table
NOTICE: Renaming the new table to undistribute_table.dist_table
ERROR: relation with OID XXXX does not exist
SELECT undistribute_table('dist_table');
NOTICE: Creating a new local table for undistribute_table.dist_table
NOTICE: Moving the data of undistribute_table.dist_table

View File

@ -11,6 +11,10 @@ SELECT logicalrelid FROM pg_dist_partition WHERE logicalrelid = 'dist_table'::re
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'dist\_table\_%'$$);
SELECT * FROM dist_table ORDER BY 1, 2, 3;
-- we cannot immediately convert in the same statement, because
-- the name->OID conversion happens at parse time.
SELECT undistribute_table('dist_table'), create_distributed_table('dist_table', 'a');
SELECT undistribute_table('dist_table');
SELECT logicalrelid FROM pg_dist_partition WHERE logicalrelid = 'dist_table'::regclass;