mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
postgres_fdw: Fix "may be used uninitialized" warning in foreign_join_ok()
Commit 0ee83dd4a9 detected the mixed foreign x function-RTE cases in one
if/else chain that only set a pair of bool flags, then acted on those flags in
a second chain. fpinfo_o and fpinfo_i are each assigned in one chain and read
in the other, so proving them initialized requires correlating the flags with
the assignments. gcc 13 with -Og does not manage that and reports fpinfo_i as
possibly uninitialized; clang's -Wconditional-uninitialized likewise reports
both variables.
The flags served no purpose beyond deferring the work, so merge the two chains
and read both fdw_private pointers up front, unconditionally. A function rel
never has an fdw_private of its own, so the pointer is simply NULL until the
stub replaces it, and each branch now assigns and uses the two variables in one
place.
Reported-by: Karina Litskevich <litskevichkarina@gmail.com>
Reported-by: Marina Polyakova <m.polyakova@postgrespro.ru>
Reviewed-by: Marina Polyakova <m.polyakova@postgrespro.ru>
Discussion: https://postgr.es/m/CACiT8iamoL-%3D792e6JK2uCVvwDhfCg7DXHhvqN0P33jhGg2-8A%40mail.gmail.com
This commit is contained in:
@@ -7045,8 +7045,6 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype,
|
||||
PgFdwRelationInfo *fpinfo_i;
|
||||
ListCell *lc;
|
||||
List *joinclauses;
|
||||
bool outer_is_function = false;
|
||||
bool inner_is_function = false;
|
||||
|
||||
/*
|
||||
* We support pushing down INNER, LEFT, RIGHT, FULL OUTER and SEMI joins.
|
||||
@@ -7070,40 +7068,22 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype,
|
||||
* function RTE can be absorbed into joins on multiple foreign servers
|
||||
* (each call gets its own stub fpinfo and rechecks shippability for the
|
||||
* specific server).
|
||||
*
|
||||
* A function rel has no fdw_private of its own, so when one side is a
|
||||
* function RTE we replace its NULL fpinfo with a stub, and the rest of
|
||||
* this function and the cost estimator can then treat both sides
|
||||
* uniformly. We hand the stub to the joinrel's deparser via the same
|
||||
* path the foreign side uses, but we never permanently attach it to the
|
||||
* function rel's fdw_private (different joinrels may pair the same
|
||||
* function RTE with different foreign servers).
|
||||
*/
|
||||
fpinfo = (PgFdwRelationInfo *) joinrel->fdw_private;
|
||||
if (jointype == JOIN_INNER && innerrel->rtekind == RTE_FUNCTION &&
|
||||
(fpinfo_o = (PgFdwRelationInfo *) outerrel->fdw_private) &&
|
||||
fpinfo_o->pushdown_safe &&
|
||||
function_rte_pushdown_ok(root, innerrel, outerrel))
|
||||
{
|
||||
inner_is_function = true;
|
||||
}
|
||||
else if (jointype == JOIN_INNER && outerrel->rtekind == RTE_FUNCTION &&
|
||||
(fpinfo_i = (PgFdwRelationInfo *) innerrel->fdw_private) &&
|
||||
fpinfo_i->pushdown_safe &&
|
||||
function_rte_pushdown_ok(root, outerrel, innerrel))
|
||||
{
|
||||
outer_is_function = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fpinfo_o = (PgFdwRelationInfo *) outerrel->fdw_private;
|
||||
fpinfo_i = (PgFdwRelationInfo *) innerrel->fdw_private;
|
||||
if (!fpinfo_o || !fpinfo_o->pushdown_safe ||
|
||||
!fpinfo_i || !fpinfo_i->pushdown_safe)
|
||||
return false;
|
||||
}
|
||||
fpinfo_o = (PgFdwRelationInfo *) outerrel->fdw_private;
|
||||
fpinfo_i = (PgFdwRelationInfo *) innerrel->fdw_private;
|
||||
|
||||
/*
|
||||
* If one side is a function RTE, allocate a stub fpinfo so the rest of
|
||||
* this function and the cost estimator can treat it uniformly. We hand
|
||||
* the stub to the joinrel's deparser via the same path the foreign side
|
||||
* uses, but we never permanently attach it to the function rel's
|
||||
* fdw_private (different joinrels may pair the same function RTE with
|
||||
* different foreign servers).
|
||||
*/
|
||||
if (inner_is_function)
|
||||
if (jointype == JOIN_INNER && innerrel->rtekind == RTE_FUNCTION &&
|
||||
fpinfo_o && fpinfo_o->pushdown_safe &&
|
||||
function_rte_pushdown_ok(root, innerrel, outerrel))
|
||||
{
|
||||
fpinfo_i = init_func_stub_fpinfo(fpinfo_o, innerrel);
|
||||
|
||||
@@ -7118,15 +7098,20 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype,
|
||||
&fpinfo_i->remote_conds, &fpinfo_i->local_conds);
|
||||
fpinfo->inner_func_fpinfo = fpinfo_i;
|
||||
}
|
||||
else if (outer_is_function)
|
||||
else if (jointype == JOIN_INNER && outerrel->rtekind == RTE_FUNCTION &&
|
||||
fpinfo_i && fpinfo_i->pushdown_safe &&
|
||||
function_rte_pushdown_ok(root, outerrel, innerrel))
|
||||
{
|
||||
fpinfo_o = init_func_stub_fpinfo(fpinfo_i, outerrel);
|
||||
|
||||
/* See the comment in the inner_is_function branch above. */
|
||||
/* See the comment in the branch above. */
|
||||
classifyConditions(root, outerrel, fpinfo_o, outerrel->baserestrictinfo,
|
||||
&fpinfo_o->remote_conds, &fpinfo_o->local_conds);
|
||||
fpinfo->outer_func_fpinfo = fpinfo_o;
|
||||
}
|
||||
else if (!fpinfo_o || !fpinfo_o->pushdown_safe ||
|
||||
!fpinfo_i || !fpinfo_i->pushdown_safe)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If joining relations have local conditions, those conditions are
|
||||
|
||||
Reference in New Issue
Block a user