@ -251,11 +251,20 @@ void get_relation_info(PlannerInfo* root, Oid relationObjectId, bool inhparent,
|
|||||||
* mark the plan we are generating as transient. See
|
* mark the plan we are generating as transient. See
|
||||||
* src/backend/access/heap/README.HOT for discussion.
|
* src/backend/access/heap/README.HOT for discussion.
|
||||||
*/
|
*/
|
||||||
if (index->indcheckxmin && !TransactionIdPrecedes(HeapTupleGetRawXmin(indexRelation->rd_indextuple),
|
if (index->indcheckxmin) {
|
||||||
u_sess->utils_cxt.TransactionXmin)) {
|
TransactionId xmin = HeapTupleGetRawXmin(indexRelation->rd_indextuple);
|
||||||
root->glob->transientPlan = true;
|
if (!TransactionIdPrecedes(xmin, u_sess->utils_cxt.TransactionXmin)) {
|
||||||
index_close(indexRelation, NoLock);
|
/*
|
||||||
continue;
|
* Since the TransactionXmin won't advance immediately(see CalculateLocalLatestSnapshot),
|
||||||
|
* we need to check CSN for the visibility.
|
||||||
|
*/
|
||||||
|
CommitSeqNo csn = TransactionIdGetCommitSeqNo(xmin, true, true, false);
|
||||||
|
if (csn >= u_sess->utils_cxt.CurrentSnapshot->snapshotcsn) {
|
||||||
|
root->glob->transientPlan = true;
|
||||||
|
index_close(indexRelation, NoLock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info = makeNode(IndexOptInfo);
|
info = makeNode(IndexOptInfo);
|
||||||
|
@ -93,6 +93,10 @@ const char *getBypassReason(FusionType result)
|
|||||||
return "Bypass not executed because query used unsupported indexscan condition";
|
return "Bypass not executed because query used unsupported indexscan condition";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NOBYPASS_ONLY_SUPPORT_BTREE_INDEX: {
|
||||||
|
return "Bypass not executed because only support btree index currently";
|
||||||
|
}
|
||||||
|
|
||||||
case NOBYPASS_INDEXONLYSCAN_WITH_ORDERBY: {
|
case NOBYPASS_INDEXONLYSCAN_WITH_ORDERBY: {
|
||||||
return "Bypass not executed because query used indexonlyscan with order by clause method";
|
return "Bypass not executed because query used indexonlyscan with order by clause method";
|
||||||
}
|
}
|
||||||
@ -438,12 +442,14 @@ template <bool is_dml, bool isonlyindex> FusionType checkFusionIndexScan(Node *n
|
|||||||
List *indexorderby = NULL;
|
List *indexorderby = NULL;
|
||||||
List *indexqual = NULL;
|
List *indexqual = NULL;
|
||||||
List *qual = NULL;
|
List *qual = NULL;
|
||||||
|
Oid indexOid = InvalidOid;
|
||||||
|
Relation index = NULL;
|
||||||
if (isonlyindex) {
|
if (isonlyindex) {
|
||||||
tarlist = ((IndexOnlyScan *)node)->scan.plan.targetlist;
|
tarlist = ((IndexOnlyScan *)node)->scan.plan.targetlist;
|
||||||
indexorderby = ((IndexOnlyScan *)node)->indexorderby;
|
indexorderby = ((IndexOnlyScan *)node)->indexorderby;
|
||||||
indexqual = ((IndexOnlyScan *)node)->indexqual;
|
indexqual = ((IndexOnlyScan *)node)->indexqual;
|
||||||
qual = ((IndexOnlyScan *)node)->scan.plan.qual;
|
qual = ((IndexOnlyScan *)node)->scan.plan.qual;
|
||||||
|
indexOid = ((IndexOnlyScan *)node)->indexid;
|
||||||
if (indexorderby != NULL) {
|
if (indexorderby != NULL) {
|
||||||
return NOBYPASS_INDEXONLYSCAN_WITH_ORDERBY;
|
return NOBYPASS_INDEXONLYSCAN_WITH_ORDERBY;
|
||||||
}
|
}
|
||||||
@ -452,12 +458,19 @@ template <bool is_dml, bool isonlyindex> FusionType checkFusionIndexScan(Node *n
|
|||||||
indexorderby = ((IndexScan *)node)->indexorderby;
|
indexorderby = ((IndexScan *)node)->indexorderby;
|
||||||
indexqual = ((IndexScan *)node)->indexqual;
|
indexqual = ((IndexScan *)node)->indexqual;
|
||||||
qual = ((IndexScan *)node)->scan.plan.qual;
|
qual = ((IndexScan *)node)->scan.plan.qual;
|
||||||
|
indexOid = ((IndexScan *)node)->indexid;
|
||||||
if (indexorderby != NULL) {
|
if (indexorderby != NULL) {
|
||||||
return NOBYPASS_INDEXSCAN_WITH_ORDERBY;
|
return NOBYPASS_INDEXSCAN_WITH_ORDERBY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index = index_open(indexOid, AccessShareLock);
|
||||||
|
if (index->rd_rel->relam != BTREE_AM_OID) {
|
||||||
|
index_close(index, AccessShareLock);
|
||||||
|
return NOBYPASS_ONLY_SUPPORT_BTREE_INDEX;
|
||||||
|
}
|
||||||
|
index_close(index, AccessShareLock);
|
||||||
|
|
||||||
ListCell *lc = NULL;
|
ListCell *lc = NULL;
|
||||||
|
|
||||||
if (is_dml == false) {
|
if (is_dml == false) {
|
||||||
|
@ -68,6 +68,7 @@ enum FusionType {
|
|||||||
NOBYPASS_UPSERT_NOT_SUPPORT,
|
NOBYPASS_UPSERT_NOT_SUPPORT,
|
||||||
|
|
||||||
NOBYPASS_NO_INDEXSCAN,
|
NOBYPASS_NO_INDEXSCAN,
|
||||||
|
NOBYPASS_ONLY_SUPPORT_BTREE_INDEX,
|
||||||
NOBYPASS_INDEXSCAN_WITH_ORDERBY,
|
NOBYPASS_INDEXSCAN_WITH_ORDERBY,
|
||||||
NOBYPASS_INDEXSCAN_WITH_QUAL,
|
NOBYPASS_INDEXSCAN_WITH_QUAL,
|
||||||
NOBYPASS_INDEXSCAN_CONDITION_INVALID,
|
NOBYPASS_INDEXSCAN_CONDITION_INVALID,
|
||||||
|
@ -619,10 +619,9 @@ EXPLAIN (NUM_NODES OFF, NODES OFF, COSTS OFF)
|
|||||||
SELECT * FROM point_tbl WHERE f1 IS NULL;
|
SELECT * FROM point_tbl WHERE f1 IS NULL;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
[Bypass]
|
|
||||||
Index Scan using gpointind on point_tbl
|
Index Scan using gpointind on point_tbl
|
||||||
Index Cond: (f1 IS NULL)
|
Index Cond: (f1 IS NULL)
|
||||||
(3 rows)
|
(2 rows)
|
||||||
|
|
||||||
SELECT * FROM point_tbl WHERE f1 IS NULL;
|
SELECT * FROM point_tbl WHERE f1 IS NULL;
|
||||||
f1
|
f1
|
||||||
@ -2748,3 +2747,33 @@ drop index test_table_idx1;
|
|||||||
drop index test_table_col_idx1;
|
drop index test_table_col_idx1;
|
||||||
drop table test_table;
|
drop table test_table;
|
||||||
drop table test_table_col;
|
drop table test_table_col;
|
||||||
|
SET enable_seqscan=off;
|
||||||
|
reset enable_indexscan;
|
||||||
|
reset enable_bitmapscan;
|
||||||
|
DROP TABLE IF EXISTS ddl_index_visibility;
|
||||||
|
NOTICE: table "ddl_index_visibility" does not exist, skipping
|
||||||
|
CREATE TABLE ddl_index_visibility(id INT, first_name text, last_name text);
|
||||||
|
--insert data
|
||||||
|
INSERT INTO ddl_index_visibility SELECT id, md5(random()::text), md5(random()::text) FROM (SELECT * FROM generate_series(1,2000) AS id) AS x;
|
||||||
|
--this update will produce a HOT, then the next created index need to check xmin when using it(get_relation_info)
|
||||||
|
update ddl_index_visibility set first_name='+dw', last_name='dw_rt' where id = 698;
|
||||||
|
--create index, indcheckxmin will be true
|
||||||
|
create index ddl_index_visibility_idx on ddl_index_visibility USING btree(id);
|
||||||
|
--explain, should be BitmapHeapScan
|
||||||
|
explain(costs off) select * from ddl_index_visibility where id=698;
|
||||||
|
QUERY PLAN
|
||||||
|
-----------------------------------------------------
|
||||||
|
Bitmap Heap Scan on ddl_index_visibility
|
||||||
|
Recheck Cond: (id = 698)
|
||||||
|
-> Bitmap Index Scan on ddl_index_visibility_idx
|
||||||
|
Index Cond: (id = 698)
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
select * from ddl_index_visibility where id=698;
|
||||||
|
id | first_name | last_name
|
||||||
|
-----+------------+-----------
|
||||||
|
698 | +dw | dw_rt
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
reset enable_seqscan;
|
||||||
|
DROP TABLE ddl_index_visibility;
|
||||||
|
@ -293,18 +293,20 @@ drop index test_part_bitmapand_ginst_btree_a_idx;
|
|||||||
CREATE UNIQUE INDEX ON test_part_bitmapand_ginst_btree (a);
|
CREATE UNIQUE INDEX ON test_part_bitmapand_ginst_btree (a);
|
||||||
--bitmapand scan
|
--bitmapand scan
|
||||||
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
explain (costs off) SELECT keyword FROM test_part_bitmapand_ginst_btree WHERE keyword @> 'new' and a = 10;
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------
|
---------------------------------------------------------------------------------------
|
||||||
Partition Iterator
|
Partition Iterator
|
||||||
Iterations: 1
|
Iterations: 1
|
||||||
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_ginst_btree
|
-> Partitioned Bitmap Heap Scan on test_part_bitmapand_ginst_btree
|
||||||
Recheck Cond: (keyword @> '''new'''::tsquery)
|
Recheck Cond: ((keyword @> '''new'''::tsquery) AND (a = 10))
|
||||||
Filter: (a = 10)
|
|
||||||
Selected Partitions: 1
|
Selected Partitions: 1
|
||||||
-> Partitioned Bitmap Index Scan on qq
|
-> BitmapAnd
|
||||||
Index Cond: (keyword @> '''new'''::tsquery)
|
-> Partitioned Bitmap Index Scan on qq
|
||||||
Selected Partitions: 1
|
Index Cond: (keyword @> '''new'''::tsquery)
|
||||||
(9 rows)
|
Selected Partitions: 1
|
||||||
|
-> Bitmap Index Scan on test_part_bitmapand_ginst_btree_a_tableoid_idx
|
||||||
|
Index Cond: (a = 10)
|
||||||
|
(11 rows)
|
||||||
|
|
||||||
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;
|
||||||
keyword
|
keyword
|
||||||
|
@ -968,3 +968,22 @@ drop index test_table_idx1;
|
|||||||
drop index test_table_col_idx1;
|
drop index test_table_col_idx1;
|
||||||
drop table test_table;
|
drop table test_table;
|
||||||
drop table test_table_col;
|
drop table test_table_col;
|
||||||
|
|
||||||
|
SET enable_seqscan=off;
|
||||||
|
reset enable_indexscan;
|
||||||
|
reset enable_bitmapscan;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS ddl_index_visibility;
|
||||||
|
CREATE TABLE ddl_index_visibility(id INT, first_name text, last_name text);
|
||||||
|
--insert data
|
||||||
|
INSERT INTO ddl_index_visibility SELECT id, md5(random()::text), md5(random()::text) FROM (SELECT * FROM generate_series(1,2000) AS id) AS x;
|
||||||
|
--this update will produce a HOT, then the next created index need to check xmin when using it(get_relation_info)
|
||||||
|
update ddl_index_visibility set first_name='+dw', last_name='dw_rt' where id = 698;
|
||||||
|
--create index, indcheckxmin will be true
|
||||||
|
create index ddl_index_visibility_idx on ddl_index_visibility USING btree(id);
|
||||||
|
--explain, should be BitmapHeapScan
|
||||||
|
explain(costs off) select * from ddl_index_visibility where id=698;
|
||||||
|
select * from ddl_index_visibility where id=698;
|
||||||
|
|
||||||
|
reset enable_seqscan;
|
||||||
|
DROP TABLE ddl_index_visibility;
|
||||||
|
Reference in New Issue
Block a user