!6312 修复表分区删除后,执行查询语句报错partition does not exist的问题

Merge pull request !6312 from yuchao/master
This commit is contained in:
opengauss_bot
2024-09-20 06:13:04 +00:00
committed by Gitee
4 changed files with 77 additions and 23 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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,