提交 eae823f4 编写于 作者: B Bhuvnesh Chaudhary 提交者: Abhijit Subramanya

Support GIN Indexes with ORCA.

This commit adds the GPDB side changes required to support GIN Indexes with
ORCA.  It also adds a new test file gp_gin_indexes to test plans produced for
ORCA/planner.

GIN indexes are not supported with index expression or predicate constraints.
ORCA does not support it currently for other types of indexes too.
上级 fc88b4ee
......@@ -587,7 +587,11 @@ recordIndexesOnLeafPart(PartitionIndexNode **pNodePtr,
*/
indRel = index_open(indexoid, NoLock);
if (GIST_AM_OID == indRel->rd_rel->relam)
if (GIN_AM_OID == indRel->rd_rel->relam)
{
indType = INDTYPE_GIN;
}
else if (GIST_AM_OID == indRel->rd_rel->relam)
{
indType = INDTYPE_GIST;
}
......@@ -1553,7 +1557,11 @@ logicalIndexInfoForIndexOid(Oid rootOid, Oid indexOid)
}
plogicalIndexInfo->indType = INDTYPE_BITMAP;
if (GIST_AM_OID == indRel->rd_rel->relam)
if (GIN_AM_OID == indRel->rd_rel->relam)
{
plogicalIndexInfo->indType = INDTYPE_GIN;
}
else if (GIST_AM_OID == indRel->rd_rel->relam)
{
plogicalIndexInfo->indType = INDTYPE_GIST;
}
......
......@@ -1116,7 +1116,12 @@ CTranslatorRelcacheToDXL::RetrieveIndex
index_type = IMDIndex::EmdindBtree;
IMDRelation::Erelstoragetype rel_storage_type = md_rel->RetrieveRelStorageType();
if (GIST_AM_OID == index_rel->rd_rel->relam)
if (GIN_AM_OID == index_rel->rd_rel->relam)
{
index_type = IMDIndex::EmdindGin;
mdid_item_type = GPOS_NEW(mp) CMDIdGPDB(GPDB_ANY);
}
else if (GIST_AM_OID == index_rel->rd_rel->relam)
{
index_type = IMDIndex::EmdindGist;
mdid_item_type = GPOS_NEW(mp) CMDIdGPDB(GPDB_ANY);
......@@ -1381,7 +1386,7 @@ CTranslatorRelcacheToDXL::RetrievePartTableIndex
default_levels_derived->Release();
mdid_index->AddRef();
GPOS_ASSERT(INDTYPE_BITMAP == index_info->indType || INDTYPE_BTREE == index_info->indType || INDTYPE_GIST == index_info->indType);
GPOS_ASSERT(INDTYPE_BITMAP == index_info->indType || INDTYPE_BTREE == index_info->indType || INDTYPE_GIST == index_info->indType || INDTYPE_GIN == index_info->indType);
IMDIndex::EmdindexType index_type = IMDIndex::EmdindBtree;
IMDId *mdid_item_type = NULL;
......@@ -1393,6 +1398,11 @@ CTranslatorRelcacheToDXL::RetrievePartTableIndex
else if (INDTYPE_GIST == index_info->indType)
{
index_type = IMDIndex::EmdindGist;
mdid_item_type = GPOS_NEW(mp) CMDIdGPDB(GPDB_ANY);
}
else if (INDTYPE_GIN == index_info->indType)
{
index_type = IMDIndex::EmdindGin;
mdid_item_type = GPOS_NEW(mp) CMDIdGPDB(GPDB_ANY);
}
......@@ -3394,7 +3404,8 @@ CTranslatorRelcacheToDXL::IsIndexSupported
// index expressions and index constraints not supported
return gpdb::HeapAttIsNull(tup, Anum_pg_index_indexprs) &&
gpdb::HeapAttIsNull(tup, Anum_pg_index_indpred) &&
(BTREE_AM_OID == index_rel->rd_rel->relam || BITMAP_AM_OID == index_rel->rd_rel->relam || GIST_AM_OID == index_rel->rd_rel->relam);
(BTREE_AM_OID == index_rel->rd_rel->relam || BITMAP_AM_OID == index_rel->rd_rel->relam || GIST_AM_OID == index_rel->rd_rel->relam ||
GIN_AM_OID == index_rel->rd_rel->relam);
}
//---------------------------------------------------------------------------
......
......@@ -488,7 +488,8 @@ typedef enum LogicalIndexType
{
INDTYPE_BTREE = 0,
INDTYPE_BITMAP = 1,
INDTYPE_GIST = 2
INDTYPE_GIST = 2,
INDTYPE_GIN = 3
} LogicalIndexType;
typedef struct LogicalIndexInfo
......
此差异已折叠。
此差异已折叠。
......@@ -55,6 +55,8 @@ test: copy copyselect
test: create_misc create_operator
# These depend on the above two
test: create_index create_view
# Depends on things setup for create_index
test: gp_gin_index
test: inherit
......
CREATE INDEX jidx ON testjsonb USING gin (j);
SET optimizer_enable_tablescan = off;
SET enable_seqscan = off;
set enable_bitmapscan = on;
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"array":["foo"]}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"array":["bar"]}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}';
SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}';
SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}';
SELECT count(*) FROM testjsonb WHERE j @> '{"array":["foo"]}';
SELECT count(*) FROM testjsonb WHERE j @> '{"array":["bar"]}';
-- exercise GIN_SEARCH_MODE_ALL
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j ? 'public';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j ? 'bar';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled'];
EXPLAIN SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled'];
SELECT count(*) FROM testjsonb WHERE j @> '{}';
SELECT count(*) FROM testjsonb WHERE j ? 'public';
SELECT count(*) FROM testjsonb WHERE j ? 'bar';
SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled'];
SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled'];
-- array exists - array elements should behave as keys (for GIN index scans too)
CREATE INDEX jidx_array ON testjsonb USING gin((j->'array'));
-- gin index on expression not support for orca
EXPLAIN SELECT count(*) from testjsonb WHERE j->'array' ? 'bar';
SELECT count(*) from testjsonb WHERE j->'array' ? 'bar';
-- type sensitive array exists - should return no rows (since "exists" only
-- matches strings that are either object keys or array elements)
-- gin index on expression not support for orca
EXPLAIN SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text;
SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text;
-- However, a raw scalar is *contained* within the array
EXPLAIN SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb;
SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb;
DROP INDEX jidx_array;
--gin path opclass
DROP INDEX jidx;
CREATE INDEX jidx ON testjsonb USING gin (j jsonb_path_ops);
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}';
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}';
SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}';
SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}';
-- exercise GIN_SEARCH_MODE_ALL
EXPLAIN SELECT count(*) FROM testjsonb WHERE j @> '{}';
SELECT count(*) FROM testjsonb WHERE j @> '{}';
DROP INDEX jidx;
-- check some corner cases for indexed nested containment (bug #13756)
create temp table nestjsonb (j jsonb);
insert into nestjsonb (j) values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
insert into nestjsonb (j) values ('[[14,2,3]]');
insert into nestjsonb (j) values ('[1,[14,2,3]]');
create index on nestjsonb using gin(j jsonb_path_ops);
explain select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb;
explain select * from nestjsonb where j @> '{"c":3}';
explain select * from nestjsonb where j @> '[[14]]';
select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb;
select * from nestjsonb where j @> '{"c":3}';
select * from nestjsonb where j @> '[[14]]';
CREATE INDEX wowidx ON test_tsvector USING gin (a);
-- GIN only supports bitmapscan, so no need to test plain indexscan
explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
-- For orca, ScalarArrayOpExpr condition on index scan not supported
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}');
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme';
EXPLAIN SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme';
SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*';
-- For orca, ScalarArrayOpExpr condition on index scan not supported
SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}');
SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme';
SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme';
DROP INDEX wowidx;
-- GIN index on complex array
CREATE TABLE complex_array_table (complex_arr complex[]);
CREATE INDEX ON complex_array_table USING gin (complex_arr);
INSERT INTO complex_array_table VALUES (ARRAY[COMPLEX(1,3), COMPLEX(5,7)]);
INSERT INTO complex_array_table VALUES (ARRAY[COMPLEX(2,4), COMPLEX(6,8)]);
EXPLAIN SELECT * FROM complex_array_table WHERE complex_arr @> ARRAY[COMPLEX(2,4)];
SELECT * FROM complex_array_table WHERE complex_arr @> ARRAY[COMPLEX(2,4)];
-- with orca bitmap table scan off and table scan off, orca should fallback to
-- planner to use bitmap index scan, as btree index plans are not supported with gin
set optimizer_enable_tablescan=off;
EXPLAIN SELECT * FROM complex_array_table WHERE complex_arr @> ARRAY[COMPLEX(2,4)];
DROP TABLE complex_array_table;
RESET enable_seqscan;
RESET enable_bitmapscan;
RESET optimizer_enable_tablescan;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册