!6312 修复表分区删除后,执行查询语句报错partition does not exist的问题
Merge pull request !6312 from yuchao/master
This commit is contained in:
@ -1501,7 +1501,12 @@ void ExecInitPartitionForIndexScan(IndexScanState* index_state, EState* estate)
|
||||
|
||||
/* get table partition and add it to a list for following scan */
|
||||
tablepartitionid = getPartitionOidFromSequence(current_relation, partSeq, partitionno);
|
||||
table_partition = PartitionOpenWithPartitionno(current_relation, tablepartitionid, partitionno, lock);
|
||||
table_partition =
|
||||
PartitionOpenWithPartitionno(current_relation, tablepartitionid, partitionno, lock, true);
|
||||
/* Skip concurrent dropped partitions */
|
||||
if (table_partition == NULL) {
|
||||
continue;
|
||||
}
|
||||
index_state->ss.partitions = lappend(index_state->ss.partitions, table_partition);
|
||||
|
||||
appendStringInfo(partNameInfo, "%s ", table_partition->pd_part->relname.data);
|
||||
@ -1527,8 +1532,12 @@ void ExecInitPartitionForIndexScan(IndexScanState* index_state, EState* estate)
|
||||
int subpartitionno = lfirst_int(lc2);
|
||||
Relation tablepartrel = partitionGetRelation(current_relation, table_partition);
|
||||
Oid subpartitionid = getPartitionOidFromSequence(tablepartrel, subpartSeq, subpartitionno);
|
||||
Partition subpart =
|
||||
PartitionOpenWithPartitionno(tablepartrel, subpartitionid, subpartitionno, AccessShareLock);
|
||||
Partition subpart = PartitionOpenWithPartitionno(tablepartrel, subpartitionid, subpartitionno,
|
||||
AccessShareLock, true);
|
||||
/* Skip concurrent dropped partitions */
|
||||
if (subpart == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
partitionIndexOidList = PartitionGetPartIndexList(subpart);
|
||||
|
||||
@ -1585,5 +1594,18 @@ void ExecInitPartitionForIndexScan(IndexScanState* index_state, EState* estate)
|
||||
index_state->iss_IndexPartitionList = lappend(index_state->iss_IndexPartitionList, index_partition);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Set the total scaned num of partition from level 1 partition, subpartition
|
||||
* list is drilled down into node->subpartitions for each node_partition entry;
|
||||
*
|
||||
* Note: we do not set is value from select partittins from pruning-result as some of
|
||||
* pre-pruned partitions could be dropped from conecurrent DDL, node->partitions
|
||||
* is refreshed partition list to be scanned;
|
||||
*/
|
||||
if (index_state->ss.partitions != NULL) {
|
||||
index_state->ss.part_id = list_length(index_state->ss.partitions);
|
||||
} else {
|
||||
index_state->ss.part_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,6 +549,27 @@ static PruningResult *GetPartitionPruningResultInInitScanRelation(SeqScan *plan,
|
||||
return resultPlan;
|
||||
}
|
||||
|
||||
static void TraverseSubpartitions(Relation partRelation, LOCKMODE lockmode, List **subpartition,
|
||||
List *subpart_seqs, List *subpartitionnos)
|
||||
{
|
||||
ListCell *lc1 = NULL;
|
||||
ListCell *lc2 = NULL;
|
||||
forboth (lc1, subpart_seqs, lc2, subpartitionnos) {
|
||||
Oid subpartitionid = InvalidOid;
|
||||
int subpartSeq = lfirst_int(lc1);
|
||||
int subpartitionno = lfirst_int(lc2);
|
||||
|
||||
subpartitionid = getPartitionOidFromSequence(partRelation, subpartSeq, subpartitionno);
|
||||
Partition subpart =
|
||||
PartitionOpenWithPartitionno(partRelation, subpartitionid, subpartitionno, lockmode, true);
|
||||
/* Skip concurrent dropped partitions */
|
||||
if (subpart == NULL) {
|
||||
continue;
|
||||
}
|
||||
*subpartition = lappend(*subpartition, subpart);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* InitScanRelation
|
||||
*
|
||||
@ -643,7 +664,12 @@ void InitScanRelation(SeqScanState* node, EState* estate, int eflags)
|
||||
List* subpartition = NIL;
|
||||
|
||||
tablepartitionid = getPartitionOidFromSequence(current_relation, partSeq, partitionno);
|
||||
part = PartitionOpenWithPartitionno(current_relation, tablepartitionid, partitionno, lockmode);
|
||||
part = PartitionOpenWithPartitionno(current_relation, tablepartitionid, partitionno, lockmode, true);
|
||||
/* Skip concurrent dropped partitions */
|
||||
if (part == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
node->partitions = lappend(node->partitions, part);
|
||||
if (resultPlan->ls_selectedSubPartitions != NIL) {
|
||||
Relation partRelation = partitionGetRelation(current_relation, part);
|
||||
@ -655,25 +681,22 @@ void InitScanRelation(SeqScanState* node, EState* estate, int eflags)
|
||||
List *subpart_seqs = subPartPruningResult->ls_selectedSubPartitions;
|
||||
List *subpartitionnos = subPartPruningResult->ls_selectedSubPartitionnos;
|
||||
Assert(list_length(subpart_seqs) == list_length(subpartitionnos));
|
||||
ListCell *lc1 = NULL;
|
||||
ListCell *lc2 = NULL;
|
||||
forboth (lc1, subpart_seqs, lc2, subpartitionnos) {
|
||||
Oid subpartitionid = InvalidOid;
|
||||
int subpartSeq = lfirst_int(lc1);
|
||||
int subpartitionno = lfirst_int(lc2);
|
||||
|
||||
subpartitionid = getPartitionOidFromSequence(partRelation, subpartSeq, subpartitionno);
|
||||
Partition subpart =
|
||||
PartitionOpenWithPartitionno(partRelation, subpartitionid, subpartitionno, lockmode);
|
||||
subpartition = lappend(subpartition, subpart);
|
||||
}
|
||||
TraverseSubpartitions(partRelation, lockmode, &subpartition, subpart_seqs, subpartitionnos);
|
||||
releaseDummyRelation(&(partRelation));
|
||||
node->subPartLengthList = lappend_int(node->subPartLengthList, list_length(subpartition));
|
||||
node->subpartitions = lappend(node->subpartitions, subpartition);
|
||||
}
|
||||
}
|
||||
if (resultPlan->ls_rangeSelectedPartitions != NULL) {
|
||||
node->part_id = resultPlan->ls_rangeSelectedPartitions->length;
|
||||
/*
|
||||
* Set the total scaned num of partition from level 1 partition, subpartition
|
||||
* list is drilled down into node->subpartitions for each node_partition entry;
|
||||
*
|
||||
* Note: we do not set is value from select partittins from pruning-result as some of
|
||||
* pre-pruned partitions could be dropped from conecurrent DDL, node->partitions
|
||||
* is refreshed partition list to be scanned;
|
||||
*/
|
||||
if (node->partitions != NULL) {
|
||||
node->part_id = list_length(node->partitions);
|
||||
} else {
|
||||
node->part_id = 0;
|
||||
}
|
||||
|
||||
@ -10101,7 +10101,8 @@ Partition tryPartitionOpen(Relation relation, Oid partition_id, LOCKMODE lockmod
|
||||
* Must make sure the partitionno is of the old partition entry, otherwise a wrong entry may be found!
|
||||
* If the partitionno is invalid, this function is degenerated into partitionOpen.
|
||||
*/
|
||||
Partition PartitionOpenWithPartitionno(Relation relation, Oid partition_id, int partitionno, LOCKMODE lockmode)
|
||||
Partition PartitionOpenWithPartitionno(Relation relation, Oid partitionOid,
|
||||
int partitionno, LOCKMODE lockmode, bool missingOk)
|
||||
{
|
||||
Partition part = NULL;
|
||||
bool issubpartition = false;
|
||||
@ -10109,24 +10110,31 @@ Partition PartitionOpenWithPartitionno(Relation relation, Oid partition_id, int
|
||||
Oid newpartOid = InvalidOid;
|
||||
|
||||
/* first try open the partition */
|
||||
part = tryPartitionOpen(relation, partition_id, lockmode);
|
||||
part = tryPartitionOpen(relation, partitionOid, lockmode);
|
||||
if (likely(PartitionIsValid(part))) {
|
||||
return part;
|
||||
}
|
||||
|
||||
if (!PARTITIONNO_IS_VALID(partitionno)) {
|
||||
ReportPartitionOpenError(relation, partition_id);
|
||||
ReportPartitionOpenError(relation, partitionOid);
|
||||
}
|
||||
|
||||
PARTITION_LOG(
|
||||
"partition %u does not exist on relation \"%s\", we will try to use partitionno %d to search the new partition",
|
||||
partition_id, RelationGetRelationName(relation), partitionno);
|
||||
partitionOid, RelationGetRelationName(relation), partitionno);
|
||||
|
||||
/* if not found, search the new partition with partitionno */
|
||||
issubpartition = RelationIsPartitionOfSubPartitionTable(relation);
|
||||
parttype = issubpartition ? PART_OBJ_TYPE_TABLE_SUB_PARTITION : PART_OBJ_TYPE_TABLE_PARTITION;
|
||||
newpartOid = GetPartOidWithPartitionno(RelationGetRelid(relation), partitionno, parttype);
|
||||
|
||||
if (missingOk && !OidIsValid(newpartOid)) {
|
||||
ereport(LOG, (errcode(ERRCODE_PARTITION_ERROR),
|
||||
errmsg("Partition oid %u is invalid when opening partition", newpartOid),
|
||||
errdetail("There is a partition may have already been dropped on relation/partition \"%s\"",
|
||||
RelationGetRelationName(relation))));
|
||||
return NULL;
|
||||
}
|
||||
return partitionOpen(relation, newpartOid, lockmode);
|
||||
}
|
||||
|
||||
|
||||
@ -273,7 +273,8 @@ extern Partition partitionOpenWithRetry(Relation relation, Oid partitionId, LOCK
|
||||
extern Partition partitionOpen(Relation relation, Oid partitionId, LOCKMODE lockmode, int2 bucketId=-1);
|
||||
extern void partitionClose(Relation relation, Partition partition, LOCKMODE lockmode);
|
||||
extern Partition tryPartitionOpen(Relation relation, Oid partitionId, LOCKMODE lockmode);
|
||||
extern Partition PartitionOpenWithPartitionno(Relation relation, Oid partition_id, int partitionno, LOCKMODE lockmode);
|
||||
extern Partition PartitionOpenWithPartitionno(Relation relation, Oid partitionOid,
|
||||
int partitionno, LOCKMODE lockmode, bool missingOk = false);
|
||||
extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode);
|
||||
extern Relation relation_openrv(const RangeVar* relation, LOCKMODE lockmode);
|
||||
extern Relation relation_openrv_extended(const RangeVar* relation, LOCKMODE lockmode, bool missing_ok,
|
||||
|
||||
Reference in New Issue
Block a user