Merge pull request #4610 from citusdata/fix_4600

Columnar: Fix lateral joins
pull/4618/head
Hadi Moshayedi 2021-02-01 12:09:28 -08:00 committed by GitHub
commit 877d87e372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 5 deletions

View File

@ -53,7 +53,8 @@ typedef struct ColumnarScanState
static void ColumnarSetRelPathlistHook(PlannerInfo *root, RelOptInfo *rel, Index rti,
RangeTblEntry *rte);
static Path * CreateColumnarScanPath(RelOptInfo *rel, RangeTblEntry *rte);
static Path * CreateColumnarScanPath(PlannerInfo *root, RelOptInfo *rel,
RangeTblEntry *rte);
static Cost ColumnarScanCost(RangeTblEntry *rte);
static Plan * ColumnarScanPath_PlanCustomPath(PlannerInfo *root,
RelOptInfo *rel,
@ -182,7 +183,7 @@ ColumnarSetRelPathlistHook(PlannerInfo *root, RelOptInfo *rel, Index rti,
errmsg("sample scans not supported on columnar tables")));
}
Path *customPath = CreateColumnarScanPath(rel, rte);
Path *customPath = CreateColumnarScanPath(root, rel, rte);
ereport(DEBUG1, (errmsg("pathlist hook for columnar table am")));
@ -195,7 +196,7 @@ ColumnarSetRelPathlistHook(PlannerInfo *root, RelOptInfo *rel, Index rti,
static Path *
CreateColumnarScanPath(RelOptInfo *rel, RangeTblEntry *rte)
CreateColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
{
ColumnarScanPath *cspath = (ColumnarScanPath *) newNode(sizeof(ColumnarScanPath),
T_CustomPath);
@ -214,6 +215,14 @@ CreateColumnarScanPath(RelOptInfo *rel, RangeTblEntry *rte)
path->parent = rel;
path->pathtarget = rel->reltarget;
/*
* We don't support pushing join clauses into the quals of a seqscan, but
* it could still have required parameterization due to LATERAL refs in
* its tlist.
*/
path->param_info = get_baserel_parampathinfo(root, rel,
rel->lateral_relids);
/*
* Add cost estimates for a columnar table scan, row count is the rows estimated by
* postgres' planner.

View File

@ -1,6 +1,8 @@
--
-- Test querying cstore_fdw tables.
-- Test querying columnar tables.
--
CREATE SCHEMA columnar_join;
SET search_path to columnar_join, public;
-- Settings to make the result deterministic
SET datestyle = "ISO, YMD";
-- Query uncompressed data
@ -119,3 +121,63 @@ INSERT INTO union_second SELECT a, a FROM generate_series(11, 15) a;
(10 rows)
DROP TABLE union_first, union_second;
-- https://github.com/citusdata/citus/issues/4600
CREATE TABLE INT8_TBL_columnar(q1 int8, q2 int8) using columnar;
INSERT INTO INT8_TBL_columnar VALUES(' 123 ',' 456');
INSERT INTO INT8_TBL_columnar VALUES('123 ','4567890123456789');
INSERT INTO INT8_TBL_columnar VALUES('4567890123456789','123');
INSERT INTO INT8_TBL_columnar VALUES(+4567890123456789,'4567890123456789');
INSERT INTO INT8_TBL_columnar VALUES('+4567890123456789','-4567890123456789');
explain (costs off, summary off) select * from
INT8_TBL_columnar a left join lateral
(select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from
INT8_TBL_columnar b cross join INT8_TBL_columnar c) ss
on a.q2 = ss.bq1;
QUERY PLAN
---------------------------------------------------------------------
Nested Loop Left Join
-> Custom Scan (ColumnarScan) on int8_tbl_columnar a
-> Nested Loop
-> Custom Scan (ColumnarScan) on int8_tbl_columnar b
Filter: (a.q2 = q1)
-> Custom Scan (ColumnarScan) on int8_tbl_columnar c
(6 rows)
explain (costs off, summary off)
SELECT COUNT(*) FROM INT8_TBL_columnar t1 JOIN
LATERAL (SELECT * FROM INT8_TBL_columnar t2 WHERE t1.q1 = t2.q1)
as foo ON (true);
QUERY PLAN
---------------------------------------------------------------------
Aggregate
-> Hash Join
Hash Cond: (t2.q1 = t1.q1)
-> Custom Scan (ColumnarScan) on int8_tbl_columnar t2
-> Hash
-> Custom Scan (ColumnarScan) on int8_tbl_columnar t1
(6 rows)
CREATE TABLE INT8_TBL_heap (LIKE INT8_TBL_columnar) ;
INSERT INTO INT8_TBL_heap SELECT * FROM INT8_TBL_columnar;
CREATE TABLE result_columnar AS
select * from
INT8_TBL_columnar a left join lateral
(select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from
INT8_TBL_columnar b cross join INT8_TBL_columnar c) ss
on a.q2 = ss.bq1;
CREATE TABLE result_regular AS
select * from
INT8_TBL_heap a left join lateral
(select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from
INT8_TBL_heap b cross join INT8_TBL_heap c) ss
on a.q2 = ss.bq1;
-- 2 results should be identical, so the following should be empty
(table result_columnar EXCEPT table result_regular)
UNION
(table result_regular EXCEPT table result_columnar);
q1 | q2 | bq1 | cq1 | least
---------------------------------------------------------------------
(0 rows)
SET client_min_messages TO WARNING;
DROP SCHEMA columnar_join CASCADE;

View File

@ -1,7 +1,10 @@
--
-- Test querying cstore_fdw tables.
-- Test querying columnar tables.
--
CREATE SCHEMA columnar_join;
SET search_path to columnar_join, public;
-- Settings to make the result deterministic
SET datestyle = "ISO, YMD";
@ -43,3 +46,48 @@ INSERT INTO union_second SELECT a, a FROM generate_series(11, 15) a;
(SELECT a*1, b FROM union_first) union all (SELECT a*1, b FROM union_second);
DROP TABLE union_first, union_second;
-- https://github.com/citusdata/citus/issues/4600
CREATE TABLE INT8_TBL_columnar(q1 int8, q2 int8) using columnar;
INSERT INTO INT8_TBL_columnar VALUES(' 123 ',' 456');
INSERT INTO INT8_TBL_columnar VALUES('123 ','4567890123456789');
INSERT INTO INT8_TBL_columnar VALUES('4567890123456789','123');
INSERT INTO INT8_TBL_columnar VALUES(+4567890123456789,'4567890123456789');
INSERT INTO INT8_TBL_columnar VALUES('+4567890123456789','-4567890123456789');
explain (costs off, summary off) select * from
INT8_TBL_columnar a left join lateral
(select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from
INT8_TBL_columnar b cross join INT8_TBL_columnar c) ss
on a.q2 = ss.bq1;
explain (costs off, summary off)
SELECT COUNT(*) FROM INT8_TBL_columnar t1 JOIN
LATERAL (SELECT * FROM INT8_TBL_columnar t2 WHERE t1.q1 = t2.q1)
as foo ON (true);
CREATE TABLE INT8_TBL_heap (LIKE INT8_TBL_columnar) USING heap;
INSERT INTO INT8_TBL_heap SELECT * FROM INT8_TBL_columnar;
CREATE TABLE result_columnar AS
select * from
INT8_TBL_columnar a left join lateral
(select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from
INT8_TBL_columnar b cross join INT8_TBL_columnar c) ss
on a.q2 = ss.bq1;
CREATE TABLE result_regular AS
select * from
INT8_TBL_heap a left join lateral
(select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from
INT8_TBL_heap b cross join INT8_TBL_heap c) ss
on a.q2 = ss.bq1;
-- 2 results should be identical, so the following should be empty
(table result_columnar EXCEPT table result_regular)
UNION
(table result_regular EXCEPT table result_columnar);
SET client_min_messages TO WARNING;
DROP SCHEMA columnar_join CASCADE;