fix inlist2join error
This commit is contained in:
@ -4796,6 +4796,19 @@ void examine_variable(PlannerInfo* root, Node* node, int varRelid, VariableStatD
|
||||
}
|
||||
}
|
||||
|
||||
static void switch_subquery(const PlannerInfo *const root, Query **subquery, const RelOptInfo *const rel)
|
||||
{
|
||||
if (!rel->subroot->parse->is_from_inlist2join_rewrite) {
|
||||
*subquery = rel->subroot->parse;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!root->parse->is_from_sublink_rewrite && !root->parse->is_from_subquery_rewrite) {
|
||||
*subquery = rel->subroot->parse;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* examine_simple_variable
|
||||
* Handle a simple Var for examine_variable
|
||||
@ -4904,9 +4917,8 @@ static void examine_simple_variable(PlannerInfo* root, Var* var, VariableStatDat
|
||||
* This is a temporary fix for mislocated varattno after inlist2join
|
||||
* optimization.
|
||||
*/
|
||||
if (!rel->subroot->parse->is_from_inlist2join_rewrite) {
|
||||
subquery = rel->subroot->parse;
|
||||
}
|
||||
switch_subquery(root, &subquery, rel);
|
||||
|
||||
Assert(IsA(subquery, Query));
|
||||
|
||||
/* Get the subquery output expression referenced by the upper Var */
|
||||
|
||||
@ -236,6 +236,7 @@ void pull_up_sublinks(PlannerInfo* root)
|
||||
* root->parse->jointree must always be a FromExpr, so insert a dummy one
|
||||
* if we got a bare RangeTblRef or JoinExpr out of the recursion.
|
||||
*/
|
||||
FromExpr* old_jointree = root->parse->jointree;
|
||||
if (IsA(jtnode, FromExpr))
|
||||
root->parse->jointree = (FromExpr*)jtnode;
|
||||
else
|
||||
@ -265,6 +266,9 @@ void pull_up_sublinks(PlannerInfo* root)
|
||||
root->parse->jointree = makeFromExpr(list_make1(jtnode), NULL);
|
||||
}
|
||||
|
||||
if (!equal(root->parse->jointree, old_jointree)) {
|
||||
root->parse->is_from_sublink_rewrite = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1082,6 +1086,7 @@ static Node* pull_up_simple_subquery(PlannerInfo* root, Node* jtnode, RangeTblEn
|
||||
return jtnode;
|
||||
}
|
||||
|
||||
root->parse->is_from_subquery_rewrite = true;
|
||||
/*
|
||||
* Need a modifiable copy of the subquery to hack on. Even if we didn't
|
||||
* sometimes choose not to pull up below, we must do this to avoid
|
||||
|
||||
@ -1979,6 +1979,9 @@ typedef struct Query {
|
||||
* Please refer to subquery_planner.
|
||||
*/
|
||||
bool is_from_inlist2join_rewrite; /* true if the query is created when applying inlist2join optimization */
|
||||
bool is_from_sublink_rewrite; /* true if the query is created when applying pull sublink optimization */
|
||||
bool is_from_subquery_rewrite; /* true if the query is created when applying pull subquery optimization */
|
||||
|
||||
uint64 uniqueSQLId; /* used by unique sql id */
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
char* unique_sql_text; /* used by unique sql plain text */
|
||||
|
||||
@ -226,9 +226,65 @@ where
|
||||
5 | 5 | records.storage.state
|
||||
(1 row)
|
||||
|
||||
-- fix bug: ERROR: no relation entry for relid 1
|
||||
-- Scenario:1
|
||||
set enable_hashjoin=on;
|
||||
set enable_material=off;
|
||||
set enable_mergejoin=off;
|
||||
set enable_nestloop=off;
|
||||
create table k1(id int,id1 int);
|
||||
create table k2(id int,id1 int);
|
||||
create table k3(id int,id1 int);
|
||||
explain (costs off)select m.*,k3.id from (select tz.* from (select k1.id from k1 WHERE exists (select k2.id from k2 where k2.id = k1.id and k2.id1 in (1,2,3,4,5,6,7,8,9,10,11))) tz limit 10) m left join k3 on m.id = k3.id;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------------------------
|
||||
Hash Right Join
|
||||
Hash Cond: (k3.id = k1.id)
|
||||
-> Seq Scan on k3
|
||||
-> Hash
|
||||
-> Limit
|
||||
-> Hash Join
|
||||
Hash Cond: (k1.id = query_rewrite.k2.id)
|
||||
-> Seq Scan on k1
|
||||
-> Hash
|
||||
-> HashAggregate
|
||||
Group By Key: query_rewrite.k2.id
|
||||
-> Hash Join
|
||||
Hash Cond: (query_rewrite.k2.id1 = "*VALUES*".column1)
|
||||
-> Seq Scan on k2
|
||||
-> Hash
|
||||
-> HashAggregate
|
||||
Group By Key: "*VALUES*".column1
|
||||
-> Values Scan on "*VALUES*"
|
||||
(18 rows)
|
||||
|
||||
-- Scenario:2
|
||||
create table customer(c_birth_month int);
|
||||
select
|
||||
1
|
||||
from
|
||||
customer t1 ,
|
||||
(with tmp2 as ( select 1 as c_birth_month, 2 as c_birth_day from now())
|
||||
select c_birth_month, c_birth_day from ( select 1 as c_birth_month, 2 as c_birth_day from now()) tmp2 ) t2
|
||||
where
|
||||
t1.c_birth_month = t2.c_birth_day and exists (select 1 ) ;
|
||||
?column?
|
||||
----------
|
||||
(0 rows)
|
||||
|
||||
-- Scenario:3
|
||||
select 1 from customer where c_birth_month not in (with tmp1 as (select 1 from now()) select * from tmp1);
|
||||
?column?
|
||||
----------
|
||||
(0 rows)
|
||||
|
||||
drop schema query_rewrite cascade;
|
||||
NOTICE: drop cascades to 3 other objects
|
||||
NOTICE: drop cascades to 7 other objects
|
||||
DETAIL: drop cascades to table t1
|
||||
drop cascades to table t2
|
||||
drop cascades to table t3
|
||||
drop cascades to table k1
|
||||
drop cascades to table k2
|
||||
drop cascades to table k3
|
||||
drop cascades to table customer
|
||||
reset current_schema;
|
||||
|
||||
@ -147,6 +147,28 @@ where
|
||||
50
|
||||
)
|
||||
);
|
||||
-- fix bug: ERROR: no relation entry for relid 1
|
||||
-- Scenario:1
|
||||
set enable_hashjoin=on;
|
||||
set enable_material=off;
|
||||
set enable_mergejoin=off;
|
||||
set enable_nestloop=off;
|
||||
create table k1(id int,id1 int);
|
||||
create table k2(id int,id1 int);
|
||||
create table k3(id int,id1 int);
|
||||
explain (costs off)select m.*,k3.id from (select tz.* from (select k1.id from k1 WHERE exists (select k2.id from k2 where k2.id = k1.id and k2.id1 in (1,2,3,4,5,6,7,8,9,10,11))) tz limit 10) m left join k3 on m.id = k3.id;
|
||||
-- Scenario:2
|
||||
create table customer(c_birth_month int);
|
||||
select
|
||||
1
|
||||
from
|
||||
customer t1 ,
|
||||
(with tmp2 as ( select 1 as c_birth_month, 2 as c_birth_day from now())
|
||||
select c_birth_month, c_birth_day from ( select 1 as c_birth_month, 2 as c_birth_day from now()) tmp2 ) t2
|
||||
where
|
||||
t1.c_birth_month = t2.c_birth_day and exists (select 1 ) ;
|
||||
-- Scenario:3
|
||||
select 1 from customer where c_birth_month not in (with tmp1 as (select 1 from now()) select * from tmp1);
|
||||
|
||||
drop schema query_rewrite cascade;
|
||||
reset current_schema;
|
||||
|
||||
Reference in New Issue
Block a user