diff --git a/src/gausskernel/runtime/executor/nodeIndexscan.cpp b/src/gausskernel/runtime/executor/nodeIndexscan.cpp index 31b76ed41..9dab06d9e 100644 --- a/src/gausskernel/runtime/executor/nodeIndexscan.cpp +++ b/src/gausskernel/runtime/executor/nodeIndexscan.cpp @@ -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; + } } } diff --git a/src/gausskernel/runtime/executor/nodeSeqscan.cpp b/src/gausskernel/runtime/executor/nodeSeqscan.cpp index efd267331..04886df52 100644 --- a/src/gausskernel/runtime/executor/nodeSeqscan.cpp +++ b/src/gausskernel/runtime/executor/nodeSeqscan.cpp @@ -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; } diff --git a/src/gausskernel/storage/access/heap/heapam.cpp b/src/gausskernel/storage/access/heap/heapam.cpp index 93e715e2c..1ec82cc35 100755 --- a/src/gausskernel/storage/access/heap/heapam.cpp +++ b/src/gausskernel/storage/access/heap/heapam.cpp @@ -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); } diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 55590a686..ff7c84a08 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -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,