forked from huawei/openGauss-server
!162 【gpi】 修复全局分区索引只支持31列的报错输出
Merge pull request !162 from xiliu/GPI_BUGFIX
This commit is contained in:
commit
ea34abb507
|
|
@ -1268,6 +1268,7 @@ static bool _equalIndexStmt(const IndexStmt* a, const IndexStmt* b)
|
|||
COMPARE_SCALAR_FIELD(oldNode);
|
||||
COMPARE_NODE_FIELD(partClause);
|
||||
COMPARE_SCALAR_FIELD(isPartitioned);
|
||||
COMPARE_SCALAR_FIELD(isGlobal);
|
||||
COMPARE_SCALAR_FIELD(unique);
|
||||
COMPARE_SCALAR_FIELD(primary);
|
||||
COMPARE_SCALAR_FIELD(isconstraint);
|
||||
|
|
|
|||
|
|
@ -3293,6 +3293,7 @@ static void _outIndexStmt(StringInfo str, IndexStmt* node)
|
|||
WRITE_OID_FIELD(oldNode);
|
||||
WRITE_NODE_FIELD(partClause);
|
||||
WRITE_BOOL_FIELD(isPartitioned);
|
||||
WRITE_BOOL_FIELD(isGlobal);
|
||||
WRITE_BOOL_FIELD(unique);
|
||||
WRITE_BOOL_FIELD(primary);
|
||||
WRITE_BOOL_FIELD(isconstraint);
|
||||
|
|
|
|||
|
|
@ -4628,6 +4628,7 @@ static IndexStmt* _readIndexStmt()
|
|||
READ_OID_FIELD(oldNode);
|
||||
READ_NODE_FIELD(partClause);
|
||||
READ_BOOL_FIELD(isPartitioned);
|
||||
READ_BOOL_FIELD(isGlobal);
|
||||
READ_BOOL_FIELD(unique);
|
||||
READ_BOOL_FIELD(primary);
|
||||
READ_BOOL_FIELD(isconstraint);
|
||||
|
|
@ -4674,18 +4675,21 @@ static Constraint* _readConstraint()
|
|||
} else if (MATCH_TYPE("PRIMARY_KEY")) {
|
||||
local_node->contype = CONSTR_PRIMARY;
|
||||
READ_NODE_FIELD(keys);
|
||||
READ_NODE_FIELD(including);
|
||||
READ_NODE_FIELD(options);
|
||||
READ_STRING_FIELD(indexname);
|
||||
READ_STRING_FIELD(indexspace);
|
||||
} else if (MATCH_TYPE("UNIQUE")) {
|
||||
local_node->contype = CONSTR_UNIQUE;
|
||||
READ_NODE_FIELD(keys);
|
||||
READ_NODE_FIELD(including);
|
||||
READ_NODE_FIELD(options);
|
||||
READ_STRING_FIELD(indexname);
|
||||
READ_STRING_FIELD(indexspace);
|
||||
} else if (MATCH_TYPE("EXCLUSION")) {
|
||||
local_node->contype = CONSTR_EXCLUSION;
|
||||
READ_NODE_FIELD(exclusions);
|
||||
READ_NODE_FIELD(including);
|
||||
READ_NODE_FIELD(options);
|
||||
READ_STRING_FIELD(indexname);
|
||||
READ_STRING_FIELD(indexspace);
|
||||
|
|
|
|||
|
|
@ -322,9 +322,9 @@ void tbm_add_tuples(TIDBitmap* tbm, const ItemPointer tids, int ntids, bool rech
|
|||
* This causes the whole page to be reported (with the recheck flag)
|
||||
* when the TIDBitmap is scanned.
|
||||
*/
|
||||
void tbm_add_page(TIDBitmap* tbm, BlockNumber pageno)
|
||||
void tbm_add_page(TIDBitmap* tbm, BlockNumber pageno, Oid partitionOid)
|
||||
{
|
||||
PagetableEntryNode pnode = {pageno, InvalidOid};
|
||||
PagetableEntryNode pnode = {pageno, partitionOid};
|
||||
/* Enter the page in the bitmap, or mark it lossy if already present */
|
||||
tbm_mark_page_lossy(tbm, pnode);
|
||||
/* If we went over the memory limit, lossify some more pages */
|
||||
|
|
|
|||
|
|
@ -3159,6 +3159,12 @@ IndexStmt* transformIndexStmt(Oid relid, IndexStmt* stmt, const char* queryStrin
|
|||
stmt->internal_flag = true;
|
||||
}
|
||||
|
||||
/* default partition index is set to Global index */
|
||||
if (RELATION_IS_PARTITIONED(rel) && !stmt->isPartitioned) {
|
||||
stmt->isPartitioned = true;
|
||||
stmt->isGlobal = true;
|
||||
}
|
||||
|
||||
bool isColStore = RelationIsColStore(rel);
|
||||
if (stmt->accessMethod == NULL) {
|
||||
if (!isColStore) {
|
||||
|
|
|
|||
|
|
@ -4703,9 +4703,10 @@ List* RelationGetSpecificKindIndexList(Relation relation, bool isGlobal)
|
|||
{
|
||||
ListCell* indList = NULL;
|
||||
List* result = NULL;
|
||||
List* indexOidList = RelationGetIndexList(relation);
|
||||
|
||||
/* Ask the relcache to produce a list of the indexes of the rel */
|
||||
foreach (indList, RelationGetIndexList(relation)) {
|
||||
foreach (indList, indexOidList) {
|
||||
Oid indexId = lfirst_oid(indList);
|
||||
Relation currentIndex;
|
||||
|
||||
|
|
@ -4723,6 +4724,7 @@ List* RelationGetSpecificKindIndexList(Relation relation, bool isGlobal)
|
|||
index_close(currentIndex, AccessShareLock);
|
||||
}
|
||||
|
||||
list_free_ext(indexOidList);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -433,6 +433,12 @@ Oid DefineIndex(Oid relationId, IndexStmt* stmt, Oid indexRelationId, bool is_al
|
|||
ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot create concurrent partitioned indexes ")));
|
||||
}
|
||||
|
||||
if (stmt->isGlobal && (list_length(stmt->indexParams) > INDEX_MAX_KEYS - 1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TOO_MANY_COLUMNS),
|
||||
errmsg("cannot use more than %d columns in an global partition index", INDEX_MAX_KEYS - 1)));
|
||||
}
|
||||
|
||||
/* Add special index columns tableoid to global partition index */
|
||||
if (stmt->isGlobal) {
|
||||
AddIndexColumnForGpi(stmt);
|
||||
|
|
@ -3067,8 +3073,7 @@ static bool CheckGlobalIndexCompatible(Oid relOid, bool isGlobal, const IndexInf
|
|||
/* only check index of different type(local and global) */
|
||||
if (currIdxKind != tarIdxKind) {
|
||||
if (!CheckIndexMethodConsistency(tarTuple, indexRelation, currMethodOid)) {
|
||||
ret = false;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
heap_getattr(tarTuple, Anum_pg_index_indexprs, RelationGetDescr(indexRelation), &isNull);
|
||||
|
|
|
|||
|
|
@ -8904,7 +8904,7 @@ static void ATExecAddIndex(AlteredTableInfo* tab, Relation rel, IndexStmt* stmt,
|
|||
if (OidIsValid(stmt->oldNode)) {
|
||||
Relation irel = index_open(new_index, NoLock);
|
||||
|
||||
if (!stmt->isPartitioned) {
|
||||
if (!stmt->isPartitioned || stmt->isGlobal) {
|
||||
RelationPreserveStorage(irel->rd_node, true);
|
||||
} else {
|
||||
List* partOids = NIL;
|
||||
|
|
@ -11316,7 +11316,7 @@ static void ATCutOffPSortDependency(List* oldIndexPassList, LOCKMODE lockmode)
|
|||
|
||||
// if the index is a partition table, handle all the
|
||||
// psort info for each partition.
|
||||
if (istmt->isPartitioned) {
|
||||
if (istmt->isPartitioned && !istmt->isGlobal) {
|
||||
Relation hrel = relation_openrv(istmt->relation, lockmode);
|
||||
Relation irel = index_open(istmt->indexOid, lockmode);
|
||||
List* partHeapOids = relationGetPartitionOidList(hrel);
|
||||
|
|
@ -11492,7 +11492,7 @@ static void ATPostAlterTypeParse(
|
|||
AlterTableCmd* newcmd = NULL;
|
||||
|
||||
if (!rewrite) {
|
||||
if (!stmt->isPartitioned) {
|
||||
if (!stmt->isPartitioned || stmt->isGlobal) {
|
||||
TryReuseIndex(oldId, stmt);
|
||||
} else {
|
||||
tryReusePartedIndex(oldId, stmt, rel);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ static TupleTableSlot* BitmapHeapTblNext(BitmapHeapScanState* node);
|
|||
static void bitgetpage(HeapScanDesc scan, TBMIterateResult* tbmres);
|
||||
static void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate);
|
||||
static void ExecInitNextPartitionForBitmapHeapScan(BitmapHeapScanState* node);
|
||||
static void BitmapHeapPrefetchNext(
|
||||
BitmapHeapScanState* node, HeapScanDesc scan, const TIDBitmap* tbm, TBMIterator** prefetch_iterator);
|
||||
|
||||
/* This struct is used for partition switch while prefetch pages */
|
||||
typedef struct PrefetchNode {
|
||||
|
|
@ -182,18 +184,6 @@ static TupleTableSlot* BitmapHeapTblNext(BitmapHeapScanState* node)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Check whether switch partition-fake-rel, use rd_rel save */
|
||||
if (BitmapNodeNeedSwitchPartRel(node)) {
|
||||
GPISetCurrPartOid(node->gpi_scan, node->tbmres->partitionOid);
|
||||
if (!GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
/* If the current partition is invalid, the next page is directly processed */
|
||||
tbmres = NULL;
|
||||
continue;
|
||||
}
|
||||
scan->rs_rd = node->gpi_scan->fakePartRelation;
|
||||
scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_rd);
|
||||
}
|
||||
|
||||
#ifdef USE_PREFETCH
|
||||
if (node->prefetch_pages > 0) {
|
||||
/* The main iterator has closed the distance by one page */
|
||||
|
|
@ -211,6 +201,21 @@ static TupleTableSlot* BitmapHeapTblNext(BitmapHeapScanState* node)
|
|||
}
|
||||
#endif /* USE_PREFETCH */
|
||||
|
||||
/* Check whether switch partition-fake-rel, use rd_rel save */
|
||||
if (BitmapNodeNeedSwitchPartRel(node)) {
|
||||
GPISetCurrPartOid(node->gpi_scan, node->tbmres->partitionOid);
|
||||
if (!GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
/* If the current partition is invalid, the next page is directly processed */
|
||||
tbmres = NULL;
|
||||
#ifdef USE_PREFETCH
|
||||
BitmapHeapPrefetchNext(node, scan, tbm, &prefetch_iterator);
|
||||
#endif /* USE_PREFETCH */
|
||||
continue;
|
||||
}
|
||||
scan->rs_rd = node->gpi_scan->fakePartRelation;
|
||||
scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_rd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore any claimed entries past what we think is the end of the
|
||||
* relation. (This is probably not necessary given that we got at
|
||||
|
|
@ -286,126 +291,7 @@ static TupleTableSlot* BitmapHeapTblNext(BitmapHeapScanState* node)
|
|||
}
|
||||
|
||||
#ifdef USE_PREFETCH
|
||||
|
||||
/*
|
||||
* We issue prefetch requests *after* fetching the current page to try
|
||||
* to avoid having prefetching interfere with the main I/O. Also, this
|
||||
* should happen only when we have determined there is still something
|
||||
* to do on the current page, else we may uselessly prefetch the same
|
||||
* page we are just about to request for real.
|
||||
*/
|
||||
if (prefetch_iterator != NULL) {
|
||||
ADIO_RUN()
|
||||
{
|
||||
BlockNumber* blockList = NULL;
|
||||
BlockNumber* blockListPtr = NULL;
|
||||
PrefetchNode* prefetchNode = NULL;
|
||||
PrefetchNode* prefetchNodePtr = NULL;
|
||||
int prefetchNow = 0;
|
||||
int prefetchWindow = node->prefetch_target - node->prefetch_pages;
|
||||
|
||||
/* We expect to prefetch at most prefetchWindow pages */
|
||||
if (prefetchWindow > 0) {
|
||||
if (tbm_is_global(tbm)) {
|
||||
prefetchNode = (PrefetchNode*)malloc(sizeof(PrefetchNode) * prefetchWindow);
|
||||
prefetchNodePtr = prefetchNode;
|
||||
}
|
||||
blockList = (BlockNumber*)palloc(sizeof(BlockNumber) * prefetchWindow);
|
||||
blockListPtr = blockList;
|
||||
}
|
||||
while (node->prefetch_pages < node->prefetch_target) {
|
||||
TBMIterateResult* tbmpre = tbm_iterate(prefetch_iterator);
|
||||
|
||||
if (tbmpre == NULL) {
|
||||
/* No more pages to prefetch */
|
||||
tbm_end_iterate(prefetch_iterator);
|
||||
node->prefetch_iterator = prefetch_iterator = NULL;
|
||||
break;
|
||||
}
|
||||
node->prefetch_pages++;
|
||||
/* we use PrefetchNode here to store relations between blockno and partition Oid */
|
||||
if (tbm_is_global(tbm)) {
|
||||
prefetchNodePtr->blockNum = tbmpre->blockno;
|
||||
prefetchNodePtr->partOid = tbmpre->partitionOid;
|
||||
prefetchNodePtr++;
|
||||
}
|
||||
/* For Async Direct I/O we accumulate a list and send it */
|
||||
*blockListPtr++ = tbmpre->blockno;
|
||||
prefetchNow++;
|
||||
}
|
||||
|
||||
/* Send the list we generated and free it */
|
||||
if (prefetchNow) {
|
||||
if (tbm_is_global(tbm)) {
|
||||
/*
|
||||
* we must save part Oid before switch relation, and recover it after prefetch.
|
||||
* The reason for this is to assure correctness while getting a new tbmres.
|
||||
*/
|
||||
Oid oldOid = GPIGetCurrPartOid(node->gpi_scan);
|
||||
int blkCount = 0;
|
||||
Oid prevOid = prefetchNode[0].partOid;
|
||||
for (int i = 0; i < prefetchNow; i++) {
|
||||
if (prefetchNode[i].partOid == prevOid) {
|
||||
blockList[blkCount++] = prefetchNode[i].blockNum;
|
||||
} else {
|
||||
GPISetCurrPartOid(node->gpi_scan, prevOid);
|
||||
if (GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
PageListPrefetch(
|
||||
node->gpi_scan->fakePartRelation, MAIN_FORKNUM, blockList, blkCount, 0, 0);
|
||||
}
|
||||
blkCount = 0;
|
||||
prevOid = prefetchNode[i].partOid;
|
||||
blockList[blkCount++] = prefetchNode[i].blockNum;
|
||||
}
|
||||
}
|
||||
GPISetCurrPartOid(node->gpi_scan, prevOid);
|
||||
if (GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
PageListPrefetch(node->gpi_scan->fakePartRelation, MAIN_FORKNUM, blockList, blkCount, 0, 0);
|
||||
}
|
||||
/* recover old oid after prefetch switch */
|
||||
GPISetCurrPartOid(node->gpi_scan, oldOid);
|
||||
} else {
|
||||
PageListPrefetch(scan->rs_rd, MAIN_FORKNUM, blockList, prefetchNow, 0, 0);
|
||||
}
|
||||
}
|
||||
if (prefetchWindow > 0) {
|
||||
pfree_ext(blockList);
|
||||
if (tbm_is_global(tbm)) {
|
||||
pfree_ext(prefetchNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
ADIO_ELSE()
|
||||
{
|
||||
Oid oldOid = GPIGetCurrPartOid(node->gpi_scan);
|
||||
while (node->prefetch_pages < node->prefetch_target) {
|
||||
TBMIterateResult* tbmpre = tbm_iterate(prefetch_iterator);
|
||||
Relation prefetchRel = scan->rs_rd;
|
||||
if (tbmpre == NULL) {
|
||||
/* No more pages to prefetch */
|
||||
tbm_end_iterate(prefetch_iterator);
|
||||
node->prefetch_iterator = prefetch_iterator = NULL;
|
||||
break;
|
||||
}
|
||||
node->prefetch_pages++;
|
||||
if (tbm_is_global(node->tbm) && GPIScanCheckPartOid(node->gpi_scan, tbmpre->partitionOid)) {
|
||||
GPISetCurrPartOid(node->gpi_scan, tbmpre->partitionOid);
|
||||
if (!GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
/* If the current partition is invalid, the next page is directly processed */
|
||||
tbmpre = NULL;
|
||||
continue;
|
||||
} else {
|
||||
prefetchRel = node->gpi_scan->fakePartRelation;
|
||||
}
|
||||
}
|
||||
/* For posix_fadvise() we just send the one request */
|
||||
PrefetchBuffer(prefetchRel, MAIN_FORKNUM, tbmpre->blockno);
|
||||
}
|
||||
/* recover old oid after prefetch switch */
|
||||
GPISetCurrPartOid(node->gpi_scan, oldOid);
|
||||
}
|
||||
ADIO_END();
|
||||
}
|
||||
BitmapHeapPrefetchNext(node, scan, tbm, &prefetch_iterator);
|
||||
#endif /* USE_PREFETCH */
|
||||
|
||||
/*
|
||||
|
|
@ -908,3 +794,127 @@ static void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, E
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We issue prefetch requests *after* fetching the current page to try
|
||||
* to avoid having prefetching interfere with the main I/O. Also, this
|
||||
* should happen only when we have determined there is still something
|
||||
* to do on the current page, else we may uselessly prefetch the same
|
||||
* page we are just about to request for real.
|
||||
*/
|
||||
void BitmapHeapPrefetchNext(
|
||||
BitmapHeapScanState* node, HeapScanDesc scan, const TIDBitmap* tbm, TBMIterator** prefetch_iterator)
|
||||
{
|
||||
if (*prefetch_iterator == NULL) {
|
||||
return;
|
||||
}
|
||||
ADIO_RUN()
|
||||
{
|
||||
BlockNumber* blockList = NULL;
|
||||
BlockNumber* blockListPtr = NULL;
|
||||
PrefetchNode* prefetchNode = NULL;
|
||||
PrefetchNode* prefetchNodePtr = NULL;
|
||||
int prefetchNow = 0;
|
||||
int prefetchWindow = node->prefetch_target - node->prefetch_pages;
|
||||
|
||||
/* We expect to prefetch at most prefetchWindow pages */
|
||||
if (prefetchWindow > 0) {
|
||||
if (tbm_is_global(tbm)) {
|
||||
prefetchNode = (PrefetchNode*)malloc(sizeof(PrefetchNode) * prefetchWindow);
|
||||
prefetchNodePtr = prefetchNode;
|
||||
}
|
||||
blockList = (BlockNumber*)palloc(sizeof(BlockNumber) * prefetchWindow);
|
||||
blockListPtr = blockList;
|
||||
}
|
||||
while (node->prefetch_pages < node->prefetch_target) {
|
||||
TBMIterateResult* tbmpre = tbm_iterate(*prefetch_iterator);
|
||||
|
||||
if (tbmpre == NULL) {
|
||||
/* No more pages to prefetch */
|
||||
tbm_end_iterate(*prefetch_iterator);
|
||||
node->prefetch_iterator = *prefetch_iterator = NULL;
|
||||
break;
|
||||
}
|
||||
node->prefetch_pages++;
|
||||
/* we use PrefetchNode here to store relations between blockno and partition Oid */
|
||||
if (tbm_is_global(tbm)) {
|
||||
prefetchNodePtr->blockNum = tbmpre->blockno;
|
||||
prefetchNodePtr->partOid = tbmpre->partitionOid;
|
||||
prefetchNodePtr++;
|
||||
}
|
||||
/* For Async Direct I/O we accumulate a list and send it */
|
||||
*blockListPtr++ = tbmpre->blockno;
|
||||
prefetchNow++;
|
||||
}
|
||||
|
||||
/* Send the list we generated and free it */
|
||||
if (prefetchNow) {
|
||||
if (tbm_is_global(tbm)) {
|
||||
/*
|
||||
* we must save part Oid before switch relation, and recover it after prefetch.
|
||||
* The reason for this is to assure correctness while getting a new tbmres.
|
||||
*/
|
||||
Oid oldOid = GPIGetCurrPartOid(node->gpi_scan);
|
||||
int blkCount = 0;
|
||||
Oid prevOid = prefetchNode[0].partOid;
|
||||
for (int i = 0; i < prefetchNow; i++) {
|
||||
if (prefetchNode[i].partOid == prevOid) {
|
||||
blockList[blkCount++] = prefetchNode[i].blockNum;
|
||||
} else {
|
||||
GPISetCurrPartOid(node->gpi_scan, prevOid);
|
||||
if (GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
PageListPrefetch(node->gpi_scan->fakePartRelation, MAIN_FORKNUM, blockList, blkCount, 0, 0);
|
||||
}
|
||||
blkCount = 0;
|
||||
prevOid = prefetchNode[i].partOid;
|
||||
blockList[blkCount++] = prefetchNode[i].blockNum;
|
||||
}
|
||||
}
|
||||
GPISetCurrPartOid(node->gpi_scan, prevOid);
|
||||
if (GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
PageListPrefetch(node->gpi_scan->fakePartRelation, MAIN_FORKNUM, blockList, blkCount, 0, 0);
|
||||
}
|
||||
/* recover old oid after prefetch switch */
|
||||
GPISetCurrPartOid(node->gpi_scan, oldOid);
|
||||
} else {
|
||||
PageListPrefetch(scan->rs_rd, MAIN_FORKNUM, blockList, prefetchNow, 0, 0);
|
||||
}
|
||||
}
|
||||
if (prefetchWindow > 0) {
|
||||
pfree_ext(blockList);
|
||||
if (tbm_is_global(tbm)) {
|
||||
pfree_ext(prefetchNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
ADIO_ELSE()
|
||||
{
|
||||
Oid oldOid = GPIGetCurrPartOid(node->gpi_scan);
|
||||
while (node->prefetch_pages < node->prefetch_target) {
|
||||
TBMIterateResult* tbmpre = tbm_iterate(*prefetch_iterator);
|
||||
Relation prefetchRel = scan->rs_rd;
|
||||
if (tbmpre == NULL) {
|
||||
/* No more pages to prefetch */
|
||||
tbm_end_iterate(*prefetch_iterator);
|
||||
node->prefetch_iterator = *prefetch_iterator = NULL;
|
||||
break;
|
||||
}
|
||||
node->prefetch_pages++;
|
||||
if (tbm_is_global(node->tbm) && GPIScanCheckPartOid(node->gpi_scan, tbmpre->partitionOid)) {
|
||||
GPISetCurrPartOid(node->gpi_scan, tbmpre->partitionOid);
|
||||
if (!GPIGetNextPartRelation(node->gpi_scan, CurrentMemoryContext, AccessShareLock)) {
|
||||
/* If the current partition is invalid, the next page is directly processed */
|
||||
tbmpre = NULL;
|
||||
continue;
|
||||
} else {
|
||||
prefetchRel = node->gpi_scan->fakePartRelation;
|
||||
}
|
||||
}
|
||||
/* For posix_fadvise() we just send the one request */
|
||||
PrefetchBuffer(prefetchRel, MAIN_FORKNUM, tbmpre->blockno);
|
||||
}
|
||||
/* recover old oid after prefetch switch */
|
||||
GPISetCurrPartOid(node->gpi_scan, oldOid);
|
||||
}
|
||||
ADIO_END();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1582,6 +1582,7 @@ static void scanPendingInsert(IndexScanDesc scan, TIDBitmap* tbm, int64* ntids)
|
|||
pendingPosition pos;
|
||||
Buffer metabuffer = ReadBuffer(scan->indexRelation, GIN_METAPAGE_BLKNO);
|
||||
BlockNumber blkno;
|
||||
Oid partHeapOid = IndexScanGetPartHeapOid(scan);
|
||||
|
||||
*ntids = 0;
|
||||
|
||||
|
|
@ -1640,7 +1641,7 @@ static void scanPendingInsert(IndexScanDesc scan, TIDBitmap* tbm, int64* ntids)
|
|||
MemoryContextReset(so->tempCtx);
|
||||
|
||||
if (match) {
|
||||
tbm_add_tuples(tbm, &pos.item, 1, recheck);
|
||||
tbm_add_tuples(tbm, &pos.item, 1, recheck, partHeapOid);
|
||||
(*ntids)++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1664,6 +1665,7 @@ Datum gingetbitmap(PG_FUNCTION_ARGS)
|
|||
int64 ntids;
|
||||
ItemPointerData iptr;
|
||||
bool recheck = false;
|
||||
Oid partHeapOid = IndexScanGetPartHeapOid(scan);
|
||||
|
||||
/*
|
||||
* Set up the scan keys, and check for unsatisfiable query.
|
||||
|
|
@ -1702,9 +1704,9 @@ Datum gingetbitmap(PG_FUNCTION_ARGS)
|
|||
break;
|
||||
|
||||
if (ItemPointerIsLossyPage(&iptr))
|
||||
tbm_add_page(tbm, ItemPointerGetBlockNumber(&iptr));
|
||||
tbm_add_page(tbm, ItemPointerGetBlockNumber(&iptr), partHeapOid);
|
||||
else
|
||||
tbm_add_tuples(tbm, &iptr, 1, recheck);
|
||||
tbm_add_tuples(tbm, &iptr, 1, recheck, partHeapOid);
|
||||
ntids++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ static void gistScanPage(IndexScanDesc scan, const GISTSearchItem *pageItem, con
|
|||
bool isNew = false;
|
||||
MemoryContext oldcxt;
|
||||
errno_t ret = EOK;
|
||||
Oid partHeapOid = IndexScanGetPartHeapOid(scan);
|
||||
|
||||
Assert(!GISTSearchItemIsHeap(*pageItem));
|
||||
|
||||
|
|
@ -290,7 +291,7 @@ static void gistScanPage(IndexScanDesc scan, const GISTSearchItem *pageItem, con
|
|||
* getbitmap scan, so just push heap tuple TIDs into the bitmap
|
||||
* without worrying about ordering
|
||||
*/
|
||||
tbm_add_tuples(tbm, &it->t_tid, 1, recheck);
|
||||
tbm_add_tuples(tbm, &it->t_tid, 1, recheck, partHeapOid);
|
||||
(*ntids)++;
|
||||
} else if (scan->numberOfOrderBys == 0 && GistPageIsLeaf(page)) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ Datum hashgetbitmap(PG_FUNCTION_ARGS)
|
|||
HashScanOpaque so = (HashScanOpaque)scan->opaque;
|
||||
bool res = false;
|
||||
int64 ntids = 0;
|
||||
Oid partHeapOid = IndexScanGetPartHeapOid(scan);
|
||||
|
||||
res = _hash_first(scan, ForwardScanDirection);
|
||||
|
||||
|
|
@ -325,7 +326,7 @@ Datum hashgetbitmap(PG_FUNCTION_ARGS)
|
|||
/* Save tuple ID, and continue scanning */
|
||||
if (add_tuple) {
|
||||
/* Note we mark the tuple ID as requiring recheck */
|
||||
tbm_add_tuples(tbm, &(so->hashso_heappos), 1, true);
|
||||
tbm_add_tuples(tbm, &(so->hashso_heappos), 1, true, partHeapOid);
|
||||
ntids++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -664,6 +664,7 @@ bool GPIGetNextPartRelation(GPIScanDesc gpiScan, MemoryContext cxt, LOCKMODE lmo
|
|||
if (bms_is_member(gpiScan->currPartOid, gpiScan->invisiblePartMap)) {
|
||||
gpiScan->fakePartRelation = NULL;
|
||||
gpiScan->partition = NULL;
|
||||
gpiScan->currPartOid = InvalidOid;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -679,6 +680,7 @@ bool GPIGetNextPartRelation(GPIScanDesc gpiScan, MemoryContext cxt, LOCKMODE lmo
|
|||
if (currStatus == PART_METADATA_INVISIBLE) {
|
||||
/* If current partition metadata is invisible, add current partition oid into invisiblePartMap */
|
||||
gpiScan->invisiblePartMap = bms_add_member(gpiScan->invisiblePartMap, gpiScan->currPartOid);
|
||||
gpiScan->currPartOid = InvalidOid;
|
||||
result = false;
|
||||
} else {
|
||||
/* If current partition metadata is invisible, add current partition oid into fakeRelationTable */
|
||||
|
|
|
|||
|
|
@ -411,7 +411,6 @@ static TransactionId _bt_check_unique(Relation rel, IndexTuple itup, Relation he
|
|||
* everyone, so we may as well mark the index entry
|
||||
* killed.
|
||||
*/
|
||||
/* okay, we gotta fetch the heap tuple ... */
|
||||
ItemIdMarkDead(curitemid);
|
||||
opaque->btpo_flags |= BTP_HAS_GARBAGE;
|
||||
|
||||
|
|
|
|||
|
|
@ -497,7 +497,7 @@ static void spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, st
|
|||
/* storeRes subroutine for getbitmap case */
|
||||
static void storeBitmap(SpGistScanOpaque so, ItemPointer heapPtr, Datum leafValue, bool isnull, bool recheck)
|
||||
{
|
||||
tbm_add_tuples(so->tbm, heapPtr, 1, recheck);
|
||||
tbm_add_tuples(so->tbm, heapPtr, 1, recheck, so->partHeapOid);
|
||||
so->ntids++;
|
||||
}
|
||||
|
||||
|
|
@ -511,6 +511,7 @@ Datum spggetbitmap(PG_FUNCTION_ARGS)
|
|||
so->want_itup = false;
|
||||
so->tbm = tbm;
|
||||
so->ntids = 0;
|
||||
so->partHeapOid = IndexScanGetPartHeapOid(scan);
|
||||
|
||||
spgWalk(scan->indexRelation, so, true, storeBitmap);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,8 +136,9 @@ typedef struct SpGistScanOpaqueData {
|
|||
List* scanStack; /* List of ScanStackEntrys */
|
||||
|
||||
/* These fields are only used in amgetbitmap scans: */
|
||||
TIDBitmap* tbm; /* bitmap being filled */
|
||||
int64 ntids; /* number of TIDs passed to bitmap */
|
||||
TIDBitmap* tbm; /* bitmap being filled */
|
||||
int64 ntids; /* number of TIDs passed to bitmap */
|
||||
Oid partHeapOid; /* partition oid passed to bitmap */
|
||||
|
||||
/* These fields are only used in amgettuple scans: */
|
||||
bool want_itup; /* are we reconstructing tuples? */
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ extern void tbm_free(TIDBitmap* tbm);
|
|||
|
||||
extern void tbm_add_tuples(
|
||||
TIDBitmap* tbm, const ItemPointer tids, int ntids, bool recheck, Oid partitionOid = InvalidOid);
|
||||
extern void tbm_add_page(TIDBitmap* tbm, BlockNumber pageno);
|
||||
extern void tbm_add_page(TIDBitmap* tbm, BlockNumber pageno, Oid partitionOid = InvalidOid);
|
||||
|
||||
extern void tbm_union(TIDBitmap* a, const TIDBitmap* b);
|
||||
extern void tbm_intersect(TIDBitmap* a, const TIDBitmap* b);
|
||||
|
|
|
|||
|
|
@ -227,3 +227,172 @@ ERROR: "idx1_gpi_bitmap_table2" is not a table
|
|||
HINT: Use DROP INDEX to remove an global partition index.
|
||||
SET enable_seqscan=on;
|
||||
SET enable_indexscan=on;
|
||||
drop table if exists test_part_bitmapand_ginst_btree;
|
||||
NOTICE: table "test_part_bitmapand_ginst_btree" does not exist, skipping
|
||||
CREATE TABLE test_part_bitmapand_ginst_btree (a int, txtkeyword TEXT, txtsample TEXT) partition by range(a) (partition p1 values less than (1001), partition p2 values less than (2001), partition p3 values less than (3001));
|
||||
insert into test_part_bitmapand_ginst_btree values (10, $$'New York'$$, 'new & york | big & apple | nyc');
|
||||
insert into test_part_bitmapand_ginst_btree values (1010, 'Moscow', 'moskva | moscow');
|
||||
insert into test_part_bitmapand_ginst_btree values (1020, $$'Sanct Peter'$$, $$Peterburg | peter | 'Sanct Peterburg'$$);
|
||||
insert into test_part_bitmapand_ginst_btree values (1030, $$'foo bar qq'$$, 'foo & (bar | qq) & city');
|
||||
ALTER TABLE test_part_bitmapand_ginst_btree ADD COLUMN keyword tsquery;
|
||||
UPDATE test_part_bitmapand_ginst_btree SET keyword = to_tsquery('english', txtkeyword);
|
||||
ALTER TABLE test_part_bitmapand_ginst_btree ADD COLUMN sample tsquery;
|
||||
UPDATE test_part_bitmapand_ginst_btree SET sample = to_tsquery('english', txtsample::text);
|
||||
CREATE UNIQUE INDEX ON test_part_bitmapand_ginst_btree (a) local;
|
||||
-- failed
|
||||
CREATE INDEX qq ON test_part_bitmapand_ginst_btree USING gist (keyword tsquery_ops);
|
||||
ERROR: Global partition index only support btree.
|
||||
CREATE INDEX qq ON test_part_bitmapand_ginst_btree USING gist (keyword tsquery_ops) local;
|
||||
CREATE INDEX ON test_part_bitmapand_ginst_btree USING gist (keyword tsquery_ops);
|
||||
ERROR: Global partition index only support btree.
|
||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 1
|
||||
-> Partitioned Index Scan using qq on test_part_bitmapand_ginst_btree
|
||||
Index Cond: (keyword @> '''new'''::tsquery)
|
||||
Filter: (a = 10)
|
||||
Selected Partitions: 1
|
||||
(6 rows)
|
||||
|
||||
SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
keyword
|
||||
----------------
|
||||
'new' & 'york'
|
||||
(1 row)
|
||||
|
||||
set force_bitmapand = on;
|
||||
set enable_seqscan = off;
|
||||
set enable_indexscan = off;
|
||||
--bitmapand scan
|
||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 1
|
||||
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_ginst_btree
|
||||
Recheck Cond: ((keyword @> '''new'''::tsquery) AND (a = 10))
|
||||
Selected Partitions: 1
|
||||
-> BitmapAnd
|
||||
-> Partitioned Bitmap Index Scan on qq
|
||||
Index Cond: (keyword @> '''new'''::tsquery)
|
||||
Selected Partitions: 1
|
||||
-> Partitioned Bitmap Index Scan on test_part_bitmapand_ginst_btree_a_idx
|
||||
Index Cond: (a = 10)
|
||||
Selected Partitions: 1
|
||||
(12 rows)
|
||||
|
||||
SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
keyword
|
||||
----------------
|
||||
'new' & 'york'
|
||||
(1 row)
|
||||
|
||||
drop index test_part_bitmapand_ginst_btree_a_idx;
|
||||
CREATE UNIQUE INDEX ON test_part_bitmapand_ginst_btree (a);
|
||||
--bitmapand scan
|
||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 1
|
||||
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_ginst_btree
|
||||
Recheck Cond: (keyword @> '''new'''::tsquery)
|
||||
Filter: (a = 10)
|
||||
Selected Partitions: 1
|
||||
-> Partitioned Bitmap Index Scan on qq
|
||||
Index Cond: (keyword @> '''new'''::tsquery)
|
||||
Selected Partitions: 1
|
||||
(9 rows)
|
||||
|
||||
SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
keyword
|
||||
----------------
|
||||
'new' & 'york'
|
||||
(1 row)
|
||||
|
||||
drop table if exists test_part_bitmapand_gin_btree;
|
||||
NOTICE: table "test_part_bitmapand_gin_btree" does not exist, skipping
|
||||
create table test_part_bitmapand_gin_btree (a int, ts tsvector) partition by range(a) (partition p1 values less than (1001), partition p2 values less than (2001), partition p3 values less than (3001));
|
||||
insert into test_part_bitmapand_gin_btree values (10, to_tsvector('Lore ipsam'));
|
||||
insert into test_part_bitmapand_gin_btree values (1010, to_tsvector('Lore ipsum'));
|
||||
create index test_part_bitmapand_gin_btree_idx on test_part_bitmapand_gin_btree using gin(ts) local;
|
||||
create index test_part_bitmapand_gin_btree_idx_a on test_part_bitmapand_gin_btree using btree(a) local;
|
||||
set force_bitmapand = on;
|
||||
set enable_seqscan = off;
|
||||
set enable_indexscan = off;
|
||||
explain (costs off) select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 10;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 1
|
||||
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_gin_btree
|
||||
Recheck Cond: ((a = 10) AND ('''ipsu'':*'::tsquery @@ ts))
|
||||
Selected Partitions: 1
|
||||
-> BitmapAnd
|
||||
-> Partitioned Bitmap Index Scan on test_part_bitmapand_gin_btree_idx_a
|
||||
Index Cond: (a = 10)
|
||||
Selected Partitions: 1
|
||||
-> Partitioned Bitmap Index Scan on test_part_bitmapand_gin_btree_idx
|
||||
Index Cond: ('''ipsu'':*'::tsquery @@ ts)
|
||||
Selected Partitions: 1
|
||||
(12 rows)
|
||||
|
||||
select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 10;
|
||||
a | ts
|
||||
---+----
|
||||
(0 rows)
|
||||
|
||||
explain (costs off) select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 1
|
||||
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_gin_btree
|
||||
Recheck Cond: ((a = 1010) AND ('''ipsu'':*'::tsquery @@ ts))
|
||||
Selected Partitions: 2
|
||||
-> BitmapAnd
|
||||
-> Partitioned Bitmap Index Scan on test_part_bitmapand_gin_btree_idx_a
|
||||
Index Cond: (a = 1010)
|
||||
Selected Partitions: 2
|
||||
-> Partitioned Bitmap Index Scan on test_part_bitmapand_gin_btree_idx
|
||||
Index Cond: ('''ipsu'':*'::tsquery @@ ts)
|
||||
Selected Partitions: 2
|
||||
(12 rows)
|
||||
|
||||
select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
a | ts
|
||||
------+--------------------
|
||||
1010 | 'ipsum':2 'lore':1
|
||||
(1 row)
|
||||
|
||||
drop index test_part_bitmapand_gin_btree_idx_a;
|
||||
create index test_part_bitmapand_gin_btree_idx_a on test_part_bitmapand_gin_btree using btree(a) global;
|
||||
explain (costs off) select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------------------------------
|
||||
Partition Iterator
|
||||
Iterations: 1
|
||||
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_gin_btree
|
||||
Recheck Cond: ((a = 1010) AND ('''ipsu'':*'::tsquery @@ ts))
|
||||
Selected Partitions: 2
|
||||
-> BitmapAnd
|
||||
-> Bitmap Index Scan on test_part_bitmapand_gin_btree_idx_a
|
||||
Index Cond: (a = 1010)
|
||||
-> Partitioned Bitmap Index Scan on test_part_bitmapand_gin_btree_idx
|
||||
Index Cond: ('''ipsu'':*'::tsquery @@ ts)
|
||||
Selected Partitions: 2
|
||||
(11 rows)
|
||||
|
||||
select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
a | ts
|
||||
------+--------------------
|
||||
1010 | 'ipsum':2 'lore':1
|
||||
(1 row)
|
||||
|
||||
reset force_bitmapand;
|
||||
reset enable_seqscan;
|
||||
reset enable_indexscan;
|
||||
drop table test_part_bitmapand_gin_btree;
|
||||
drop table test_part_bitmapand_ginst_btree;
|
||||
|
|
@ -249,7 +249,7 @@ create table gpi_multi_cols(a0 int,a1 int,a2 int,a3 int,a4 int,a5 int,a6 int,a7
|
|||
create index gpi_multi_cols_index on gpi_multi_cols(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30) global;
|
||||
--failed
|
||||
create index gpi_multi_cols_index on gpi_multi_cols(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30, a31) global;
|
||||
ERROR: cannot use more than 32 columns in an index
|
||||
ERROR: cannot use more than 31 columns in an global partition index
|
||||
--success
|
||||
create index gpi_multi_cols_index_local on gpi_multi_cols(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30, a31) local;
|
||||
insert into gpi_multi_cols select r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r from generate_series(1,3000) as r;
|
||||
|
|
|
|||
|
|
@ -78,4 +78,69 @@ SELECT * FROM gpi_bitmap_table2 WHERE c1 = 10000 OR c2 = 30000;
|
|||
DROP TABLE idx1_gpi_bitmap_table1;
|
||||
DROP TABLE idx1_gpi_bitmap_table2;
|
||||
SET enable_seqscan=on;
|
||||
SET enable_indexscan=on;
|
||||
SET enable_indexscan=on;
|
||||
|
||||
drop table if exists test_part_bitmapand_ginst_btree;
|
||||
CREATE TABLE test_part_bitmapand_ginst_btree (a int, txtkeyword TEXT, txtsample TEXT) partition by range(a) (partition p1 values less than (1001), partition p2 values less than (2001), partition p3 values less than (3001));
|
||||
insert into test_part_bitmapand_ginst_btree values (10, $$'New York'$$, 'new & york | big & apple | nyc');
|
||||
insert into test_part_bitmapand_ginst_btree values (1010, 'Moscow', 'moskva | moscow');
|
||||
insert into test_part_bitmapand_ginst_btree values (1020, $$'Sanct Peter'$$, $$Peterburg | peter | 'Sanct Peterburg'$$);
|
||||
insert into test_part_bitmapand_ginst_btree values (1030, $$'foo bar qq'$$, 'foo & (bar | qq) & city');
|
||||
|
||||
ALTER TABLE test_part_bitmapand_ginst_btree ADD COLUMN keyword tsquery;
|
||||
UPDATE test_part_bitmapand_ginst_btree SET keyword = to_tsquery('english', txtkeyword);
|
||||
ALTER TABLE test_part_bitmapand_ginst_btree ADD COLUMN sample tsquery;
|
||||
UPDATE test_part_bitmapand_ginst_btree SET sample = to_tsquery('english', txtsample::text);
|
||||
|
||||
CREATE UNIQUE INDEX ON test_part_bitmapand_ginst_btree (a) local;
|
||||
-- failed
|
||||
CREATE INDEX qq ON test_part_bitmapand_ginst_btree USING gist (keyword tsquery_ops);
|
||||
CREATE INDEX qq ON test_part_bitmapand_ginst_btree USING gist (keyword tsquery_ops) local;
|
||||
|
||||
CREATE INDEX ON test_part_bitmapand_ginst_btree USING gist (keyword tsquery_ops);
|
||||
|
||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
|
||||
set force_bitmapand = on;
|
||||
set enable_seqscan = off;
|
||||
set enable_indexscan = off;
|
||||
|
||||
--bitmapand scan
|
||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
|
||||
drop index test_part_bitmapand_ginst_btree_a_idx;
|
||||
CREATE UNIQUE INDEX ON test_part_bitmapand_ginst_btree (a);
|
||||
|
||||
--bitmapand scan
|
||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||
|
||||
drop table if exists test_part_bitmapand_gin_btree;
|
||||
create table test_part_bitmapand_gin_btree (a int, ts tsvector) partition by range(a) (partition p1 values less than (1001), partition p2 values less than (2001), partition p3 values less than (3001));
|
||||
insert into test_part_bitmapand_gin_btree values (10, to_tsvector('Lore ipsam'));
|
||||
insert into test_part_bitmapand_gin_btree values (1010, to_tsvector('Lore ipsum'));
|
||||
create index test_part_bitmapand_gin_btree_idx on test_part_bitmapand_gin_btree using gin(ts) local;
|
||||
create index test_part_bitmapand_gin_btree_idx_a on test_part_bitmapand_gin_btree using btree(a) local;
|
||||
|
||||
set force_bitmapand = on;
|
||||
set enable_seqscan = off;
|
||||
set enable_indexscan = off;
|
||||
explain (costs off) select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 10;
|
||||
select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 10;
|
||||
|
||||
explain (costs off) select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
|
||||
drop index test_part_bitmapand_gin_btree_idx_a;
|
||||
create index test_part_bitmapand_gin_btree_idx_a on test_part_bitmapand_gin_btree using btree(a) global;
|
||||
explain (costs off) select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
select * from test_part_bitmapand_gin_btree where 'ipsu:*'::tsquery @@ ts and a = 1010;
|
||||
|
||||
reset force_bitmapand;
|
||||
reset enable_seqscan;
|
||||
reset enable_indexscan;
|
||||
|
||||
drop table test_part_bitmapand_gin_btree;
|
||||
drop table test_part_bitmapand_ginst_btree;
|
||||
Loading…
Reference in New Issue