mirror of https://github.com/citusdata/citus.git
Merge pull request #5192 from citusdata/use-pg-functions
Use relcache utils instead of scanning catalog tables for indexes and ext statspull/5195/head
commit
262f89359e
|
@ -888,17 +888,12 @@ GetIndexAccessMethodName(Oid indexId)
|
||||||
Oid indexAMId = indexForm->relam;
|
Oid indexAMId = indexForm->relam;
|
||||||
ReleaseSysCache(indexTuple);
|
ReleaseSysCache(indexTuple);
|
||||||
|
|
||||||
/* fetch pg_am tuple of index' access method */
|
char *indexAmName = get_am_name(indexAMId);
|
||||||
HeapTuple indexAMTuple = SearchSysCache1(AMOID, ObjectIdGetDatum(indexAMId));
|
if (!indexAmName)
|
||||||
if (!HeapTupleIsValid(indexAMTuple))
|
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("access method with oid %u does not exist", indexAMId)));
|
ereport(ERROR, (errmsg("access method with oid %u does not exist", indexAMId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Form_pg_am indexAMForm = (Form_pg_am) GETSTRUCT(indexAMTuple);
|
|
||||||
char *indexAmName = pstrdup(indexAMForm->amname.data);
|
|
||||||
ReleaseSysCache(indexAMTuple);
|
|
||||||
|
|
||||||
return indexAmName;
|
return indexAmName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,9 @@ static char * GetRenameShardTriggerCommand(Oid shardRelationId, char *triggerNam
|
||||||
static void DropRelationTruncateTriggers(Oid relationId);
|
static void DropRelationTruncateTriggers(Oid relationId);
|
||||||
static char * GetDropTriggerCommand(Oid relationId, char *triggerName);
|
static char * GetDropTriggerCommand(Oid relationId, char *triggerName);
|
||||||
static List * GetRenameStatsCommandList(List *statsOidList, uint64 shardId);
|
static List * GetRenameStatsCommandList(List *statsOidList, uint64 shardId);
|
||||||
|
static void AppendExplicitIndexIdsToList(Form_pg_index indexForm,
|
||||||
|
List **explicitIndexIdList,
|
||||||
|
int flags);
|
||||||
static void DropDefaultExpressionsAndMoveOwnedSequenceOwnerships(Oid sourceRelationId,
|
static void DropDefaultExpressionsAndMoveOwnedSequenceOwnerships(Oid sourceRelationId,
|
||||||
Oid targetRelationId);
|
Oid targetRelationId);
|
||||||
static void DropDefaultColumnDefinition(Oid relationId, char *columnName);
|
static void DropDefaultColumnDefinition(Oid relationId, char *columnName);
|
||||||
|
@ -684,7 +687,10 @@ GetRenameShardIndexCommand(Oid indexOid, uint64 shardId)
|
||||||
static void
|
static void
|
||||||
RenameShardRelationStatistics(Oid shardRelationId, uint64 shardId)
|
RenameShardRelationStatistics(Oid shardRelationId, uint64 shardId)
|
||||||
{
|
{
|
||||||
List *statsOidList = GetExplicitStatisticsIdList(shardRelationId);
|
Relation shardRelation = RelationIdGetRelation(shardRelationId);
|
||||||
|
List *statsOidList = RelationGetStatExtList(shardRelation);
|
||||||
|
RelationClose(shardRelation);
|
||||||
|
|
||||||
List *statsCommandList = GetRenameStatsCommandList(statsOidList, shardId);
|
List *statsCommandList = GetRenameStatsCommandList(statsOidList, shardId);
|
||||||
|
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
|
@ -834,51 +840,25 @@ GetDropTriggerCommand(Oid relationId, char *triggerName)
|
||||||
List *
|
List *
|
||||||
GetExplicitIndexOidList(Oid relationId)
|
GetExplicitIndexOidList(Oid relationId)
|
||||||
{
|
{
|
||||||
int scanKeyCount = 1;
|
/* flags are not applicable for AppendExplicitIndexIdsToList */
|
||||||
ScanKeyData scanKey[1];
|
int flags = 0;
|
||||||
|
return ExecuteFunctionOnEachTableIndex(relationId, AppendExplicitIndexIdsToList,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
PushOverrideEmptySearchPath(CurrentMemoryContext);
|
|
||||||
|
|
||||||
Relation pgIndex = table_open(IndexRelationId, AccessShareLock);
|
/*
|
||||||
|
* AppendExplicitIndexIdsToList adds the given index oid if it is
|
||||||
ScanKeyInit(&scanKey[0], Anum_pg_index_indrelid,
|
* explicitly created on its relation.
|
||||||
BTEqualStrategyNumber, F_OIDEQ, relationId);
|
*/
|
||||||
|
static void
|
||||||
bool useIndex = true;
|
AppendExplicitIndexIdsToList(Form_pg_index indexForm, List **explicitIndexIdList,
|
||||||
SysScanDesc scanDescriptor = systable_beginscan(pgIndex, IndexIndrelidIndexId,
|
int flags)
|
||||||
useIndex, NULL, scanKeyCount,
|
{
|
||||||
scanKey);
|
if (!IndexImpliedByAConstraint(indexForm))
|
||||||
|
|
||||||
List *indexOidList = NIL;
|
|
||||||
|
|
||||||
HeapTuple heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
while (HeapTupleIsValid(heapTuple))
|
|
||||||
{
|
{
|
||||||
Form_pg_index indexForm = (Form_pg_index) GETSTRUCT(heapTuple);
|
*explicitIndexIdList = lappend_oid(*explicitIndexIdList, indexForm->indexrelid);
|
||||||
|
|
||||||
Oid indexId = indexForm->indexrelid;
|
|
||||||
|
|
||||||
bool indexImpliedByConstraint = IndexImpliedByAConstraint(indexForm);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Skip the indexes that are not implied by explicitly executing
|
|
||||||
* a CREATE INDEX command.
|
|
||||||
*/
|
|
||||||
if (!indexImpliedByConstraint)
|
|
||||||
{
|
|
||||||
indexOidList = lappend_oid(indexOidList, indexId);
|
|
||||||
}
|
|
||||||
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
systable_endscan(scanDescriptor);
|
|
||||||
table_close(pgIndex, NoLock);
|
|
||||||
|
|
||||||
/* revert back to original search_path */
|
|
||||||
PopOverrideSearchPath();
|
|
||||||
|
|
||||||
return indexOidList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -306,37 +306,25 @@ ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor pgIndexProcesso
|
||||||
int indexFlags)
|
int indexFlags)
|
||||||
{
|
{
|
||||||
List *result = NIL;
|
List *result = NIL;
|
||||||
ScanKeyData scanKey[1];
|
|
||||||
int scanKeyCount = 1;
|
|
||||||
|
|
||||||
PushOverrideEmptySearchPath(CurrentMemoryContext);
|
Relation relation = RelationIdGetRelation(relationId);
|
||||||
|
List *indexIdList = RelationGetIndexList(relation);
|
||||||
/* open system catalog and scan all indexes that belong to this table */
|
Oid indexId = InvalidOid;
|
||||||
Relation pgIndex = table_open(IndexRelationId, AccessShareLock);
|
foreach_oid(indexId, indexIdList)
|
||||||
|
|
||||||
ScanKeyInit(&scanKey[0], Anum_pg_index_indrelid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ, relationId);
|
|
||||||
|
|
||||||
SysScanDesc scanDescriptor = systable_beginscan(pgIndex,
|
|
||||||
IndexIndrelidIndexId, true, /* indexOK */
|
|
||||||
NULL, scanKeyCount, scanKey);
|
|
||||||
|
|
||||||
HeapTuple heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
while (HeapTupleIsValid(heapTuple))
|
|
||||||
{
|
{
|
||||||
Form_pg_index indexForm = (Form_pg_index) GETSTRUCT(heapTuple);
|
HeapTuple indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId));
|
||||||
pgIndexProcessor(indexForm, &result, indexFlags);
|
if (!HeapTupleIsValid(indexTuple))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg("cache lookup failed for index with oid %u",
|
||||||
|
indexId)));
|
||||||
|
}
|
||||||
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
Form_pg_index indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
|
||||||
|
pgIndexProcessor(indexForm, &result, indexFlags);
|
||||||
|
ReleaseSysCache(indexTuple);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up scan and close system catalog */
|
RelationClose(relation);
|
||||||
systable_endscan(scanDescriptor);
|
|
||||||
table_close(pgIndex, AccessShareLock);
|
|
||||||
|
|
||||||
/* revert back to original search_path */
|
|
||||||
PopOverrideSearchPath();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -425,16 +425,18 @@ PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString,
|
||||||
* GetExplicitStatisticsCommandList returns the list of DDL commands to create
|
* GetExplicitStatisticsCommandList returns the list of DDL commands to create
|
||||||
* or alter statistics that are explicitly created for the table with relationId.
|
* or alter statistics that are explicitly created for the table with relationId.
|
||||||
* This function gets called when distributing the table with relationId.
|
* This function gets called when distributing the table with relationId.
|
||||||
* See comment of GetExplicitStatisticsIdList function.
|
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
GetExplicitStatisticsCommandList(Oid relationId)
|
GetExplicitStatisticsCommandList(Oid relationId)
|
||||||
{
|
{
|
||||||
List *explicitStatisticsCommandList = NIL;
|
List *explicitStatisticsCommandList = NIL;
|
||||||
|
|
||||||
PushOverrideEmptySearchPath(CurrentMemoryContext);
|
Relation relation = RelationIdGetRelation(relationId);
|
||||||
|
List *statisticsIdList = RelationGetStatExtList(relation);
|
||||||
|
RelationClose(relation);
|
||||||
|
|
||||||
List *statisticsIdList = GetExplicitStatisticsIdList(relationId);
|
/* generate fully-qualified names */
|
||||||
|
PushOverrideEmptySearchPath(CurrentMemoryContext);
|
||||||
|
|
||||||
Oid statisticsId = InvalidOid;
|
Oid statisticsId = InvalidOid;
|
||||||
foreach_oid(statisticsId, statisticsIdList)
|
foreach_oid(statisticsId, statisticsIdList)
|
||||||
|
@ -488,23 +490,19 @@ GetExplicitStatisticsSchemaIdList(Oid relationId)
|
||||||
{
|
{
|
||||||
List *schemaIdList = NIL;
|
List *schemaIdList = NIL;
|
||||||
|
|
||||||
Relation pgStatistics = table_open(StatisticExtRelationId, AccessShareLock);
|
Relation relation = RelationIdGetRelation(relationId);
|
||||||
|
List *statsIdList = RelationGetStatExtList(relation);
|
||||||
|
RelationClose(relation);
|
||||||
|
|
||||||
int scanKeyCount = 1;
|
Oid statsId = InvalidOid;
|
||||||
ScanKeyData scanKey[1];
|
foreach_oid(statsId, statsIdList)
|
||||||
|
|
||||||
ScanKeyInit(&scanKey[0], Anum_pg_statistic_ext_stxrelid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ, relationId);
|
|
||||||
|
|
||||||
bool useIndex = true;
|
|
||||||
SysScanDesc scanDescriptor = systable_beginscan(pgStatistics,
|
|
||||||
StatisticExtRelidIndexId,
|
|
||||||
useIndex, NULL, scanKeyCount,
|
|
||||||
scanKey);
|
|
||||||
|
|
||||||
HeapTuple heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
while (HeapTupleIsValid(heapTuple))
|
|
||||||
{
|
{
|
||||||
|
HeapTuple heapTuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsId));
|
||||||
|
if (!HeapTupleIsValid(heapTuple))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg("cache lookup failed for statistics "
|
||||||
|
"object with oid %u", statsId)));
|
||||||
|
}
|
||||||
FormData_pg_statistic_ext *statisticsForm =
|
FormData_pg_statistic_ext *statisticsForm =
|
||||||
(FormData_pg_statistic_ext *) GETSTRUCT(heapTuple);
|
(FormData_pg_statistic_ext *) GETSTRUCT(heapTuple);
|
||||||
|
|
||||||
|
@ -513,12 +511,9 @@ GetExplicitStatisticsSchemaIdList(Oid relationId)
|
||||||
{
|
{
|
||||||
schemaIdList = lappend_oid(schemaIdList, schemaId);
|
schemaIdList = lappend_oid(schemaIdList, schemaId);
|
||||||
}
|
}
|
||||||
|
ReleaseSysCache(heapTuple);
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
systable_endscan(scanDescriptor);
|
|
||||||
table_close(pgStatistics, NoLock);
|
|
||||||
|
|
||||||
return schemaIdList;
|
return schemaIdList;
|
||||||
}
|
}
|
||||||
|
@ -567,48 +562,6 @@ GetAlterIndexStatisticsCommands(Oid indexOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetExplicitStatisticsIdList returns a list of OIDs corresponding to the statistics
|
|
||||||
* that are explicitly created on the relation with relationId. That means,
|
|
||||||
* this function discards internal statistics implicitly created by postgres.
|
|
||||||
*/
|
|
||||||
List *
|
|
||||||
GetExplicitStatisticsIdList(Oid relationId)
|
|
||||||
{
|
|
||||||
List *statisticsIdList = NIL;
|
|
||||||
|
|
||||||
Relation pgStatistics = table_open(StatisticExtRelationId, AccessShareLock);
|
|
||||||
|
|
||||||
int scanKeyCount = 1;
|
|
||||||
ScanKeyData scanKey[1];
|
|
||||||
|
|
||||||
ScanKeyInit(&scanKey[0], Anum_pg_statistic_ext_stxrelid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ, relationId);
|
|
||||||
|
|
||||||
bool useIndex = true;
|
|
||||||
SysScanDesc scanDescriptor = systable_beginscan(pgStatistics,
|
|
||||||
StatisticExtRelidIndexId,
|
|
||||||
useIndex, NULL, scanKeyCount,
|
|
||||||
scanKey);
|
|
||||||
|
|
||||||
HeapTuple heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
while (HeapTupleIsValid(heapTuple))
|
|
||||||
{
|
|
||||||
FormData_pg_statistic_ext *statisticsForm =
|
|
||||||
(FormData_pg_statistic_ext *) GETSTRUCT(heapTuple);
|
|
||||||
Oid statisticsId = statisticsForm->oid;
|
|
||||||
statisticsIdList = lappend_oid(statisticsIdList, statisticsId);
|
|
||||||
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
systable_endscan(scanDescriptor);
|
|
||||||
table_close(pgStatistics, NoLock);
|
|
||||||
|
|
||||||
return statisticsIdList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GenerateAlterIndexColumnSetStatsCommand returns a string in form of 'ALTER INDEX ..
|
* GenerateAlterIndexColumnSetStatsCommand returns a string in form of 'ALTER INDEX ..
|
||||||
* ALTER COLUMN .. SET STATISTICS ..' which will be used to create a DDL command to
|
* ALTER COLUMN .. SET STATISTICS ..' which will be used to create a DDL command to
|
||||||
|
|
|
@ -798,6 +798,9 @@ void
|
||||||
GatherIndexAndConstraintDefinitionList(Form_pg_index indexForm, List **indexDDLEventList,
|
GatherIndexAndConstraintDefinitionList(Form_pg_index indexForm, List **indexDDLEventList,
|
||||||
int indexFlags)
|
int indexFlags)
|
||||||
{
|
{
|
||||||
|
/* generate fully-qualified names */
|
||||||
|
PushOverrideEmptySearchPath(CurrentMemoryContext);
|
||||||
|
|
||||||
Oid indexId = indexForm->indexrelid;
|
Oid indexId = indexForm->indexrelid;
|
||||||
bool indexImpliedByConstraint = IndexImpliedByAConstraint(indexForm);
|
bool indexImpliedByConstraint = IndexImpliedByAConstraint(indexForm);
|
||||||
|
|
||||||
|
@ -845,6 +848,9 @@ GatherIndexAndConstraintDefinitionList(Form_pg_index indexForm, List **indexDDLE
|
||||||
*indexDDLEventList = list_concat(*indexDDLEventList,
|
*indexDDLEventList = list_concat(*indexDDLEventList,
|
||||||
alterIndexStatisticsCommands);
|
alterIndexStatisticsCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* revert back to original search_path */
|
||||||
|
PopOverrideSearchPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,6 @@ extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *querySt
|
||||||
extern List * GetExplicitStatisticsCommandList(Oid relationId);
|
extern List * GetExplicitStatisticsCommandList(Oid relationId);
|
||||||
extern List * GetExplicitStatisticsSchemaIdList(Oid relationId);
|
extern List * GetExplicitStatisticsSchemaIdList(Oid relationId);
|
||||||
extern List * GetAlterIndexStatisticsCommands(Oid indexOid);
|
extern List * GetAlterIndexStatisticsCommands(Oid indexOid);
|
||||||
extern List * GetExplicitStatisticsIdList(Oid relationId);
|
|
||||||
|
|
||||||
/* subscription.c - forward declarations */
|
/* subscription.c - forward declarations */
|
||||||
extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt);
|
extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt);
|
||||||
|
|
Loading…
Reference in New Issue