提交 f50e5daf 编写于 作者: S Shreedhar Hardikar 提交者: Shreedhar Hardikar

Fix 'no parameter found for initplan subquery'

The issue happens because of constant folding in the testexpr of the
SUBPLAN expression node. The testexpr may be reduced to a const and any
PARAMs, previous used in the testexpr, disappear, However, the subplan
still remains.

This behavior is similar in upstream Postgres 10 and may be of
performance consideration. Leaving that aside for now, the constant
folding produces an elog(ERROR)s when the plan has subplans and no
PARAMs are used. This check in `addRemoteExecParamsToParamList()` uses
`context.params` which computes the used PARAMs in the plan and `nIntPrm
= list_length(root->glob->paramlist`, which is the number of PARAMs
declared/created.
Given the ERROR messages generated, the above check makes no sense.
Especially since it won’t even trip for the InitPlan bug (mentioned in
the comments) as long as there is at least one PARAM in the query.

This commit removes this check since it doesn't correctly capture the
intent.

In theory, it could be be replaced by one specifically aimed at
InitPlans, that is, find all the params ids used by InitPlan and then
make sure they are used in the plan. But we already do this and
remove any unused initplans in `remove_unused_initplans()`. So I don’t
see the point of adding that.

Fixes #2839
上级 996853cb
......@@ -270,21 +270,6 @@ addRemoteExecParamsToParamList(PlannedStmt *stmt, ParamListInfo extPrm, ParamExe
}
}
if (context.params == NIL &&
bms_num_members(context.wtParams) + bms_num_members(context.epqParams) < nIntPrm)
{
/*
* We apparently have an initplan with no corresponding parameter.
* This shouldn't happen, but we had a bug once (MPP-239) because we
* weren't looking for parameters in Function RTEs. So we still
* better check. The old correct, but unhelpful to ENG, message was
* "Subquery datatype information unavailable."
*/
ereport(ERROR,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("no parameter found for initplan subquery")));
}
/*
* Now initialize the ParamListInfo elements corresponding to the
* initplans we're "parameterizing". Use the datatype info harvested
......
......@@ -54,3 +54,24 @@ and usename='xxx' and datname='xxx';
Optimizer: legacy query optimizer
(15 rows)
-- Planner test: constant folding in subplan testexpr produces no error
create table subselect_t1 (a int, b int, c int) distributed by (a);
create table subselect_t2 (a int, b int, c int) distributed by (a);
insert into subselect_t1 values (1,1,1);
insert into subselect_t2 values (1,1,1);
select * from subselect_t1 where NULL in (select c from subselect_t2);
a | b | c
---+---+---
(0 rows)
select * from subselect_t1 where NULL in (select c from subselect_t2) and exists (select generate_series(1,2));
a | b | c
---+---+---
(0 rows)
-- Planner test to make sure initplan is removed when no param is used
select * from subselect_t2 where false and exists (select generate_series(1,2));
a | b | c
---+---+---
(0 rows)
......@@ -26,3 +26,17 @@ explain (costs off)
select sess_id from pg_stat_activity
where current_query = (select current_query())
and usename='xxx' and datname='xxx';
-- Planner test: constant folding in subplan testexpr produces no error
create table subselect_t1 (a int, b int, c int) distributed by (a);
create table subselect_t2 (a int, b int, c int) distributed by (a);
insert into subselect_t1 values (1,1,1);
insert into subselect_t2 values (1,1,1);
select * from subselect_t1 where NULL in (select c from subselect_t2);
select * from subselect_t1 where NULL in (select c from subselect_t2) and exists (select generate_series(1,2));
-- Planner test to make sure initplan is removed when no param is used
select * from subselect_t2 where false and exists (select generate_series(1,2));
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册