Re: BUG #19037: Planner fails on estimating array length with "no relation entry" error - Mailing list pgsql-bugs
From | Tom Lane |
---|---|
Subject | Re: BUG #19037: Planner fails on estimating array length with "no relation entry" error |
Date | |
Msg-id | 50858.1756590676@sss.pgh.pa.us Whole thread Raw |
In response to | BUG #19037: Planner fails on estimating array length with "no relation entry" error (PG Bug reporting form <noreply@postgresql.org>) |
Responses |
Re: BUG #19037: Planner fails on estimating array length with "no relation entry" error
Re: BUG #19037: Planner fails on estimating array length with "no relation entry" error |
List | pgsql-bugs |
PG Bug reporting form <noreply@postgresql.org> writes: > The following script: > create table t(ia int[]); > select exists (select 1 from (select 1) where case when b then 1 else 0 end > = 1) > from (select 1 = any(ia) as b from t); > triggers: > ERROR: XX000: no relation entry for relid 2 > LOCATION: find_base_rel, relnode.c:426 Thanks for the report. After a bit of experimentation, I can shorten the reproducer to select exists (select 1 where (1 = any(ia))::int = 1) from t; ERROR: no relation entry for relid 1 but it doesn't happen any more if you simplify further to select exists (select 1 where 1 = any(ia)) from t; The reason for the difference seems to be that make_subplan checks to see if the EXISTS can be converted to a hashable ANY subplan (cf. convert_EXISTS_to_ANY), and the form where there's a top-level "=" operator in the sub-select's WHERE clause can be so converted. Then we hit the failure while trying to do cost_qual_eval on the converted ANY expression. So you also get this failure if you manually write out the form that convert_EXISTS_to_ANY is generating: select ((1 = any(ia))::int) = any (select 1) from t; ERROR: no relation entry for relid 1 Anyway that's sort of a sideshow. The real issue here is that we're applying cost_qual_eval before the planner has created any RelOptInfos, which means that examine_variable won't work. I find it surprising that this is the first report of such trouble, because it certainly isn't obvious that cost_qual_eval shouldn't be allowed to consult statistics. The most expedient solution is probably to hack examine_variable so that it doesn't fail if root->simple_rel_array isn't there yet. That seems mighty ugly though. Another low-risk response could be to revert 9391f7152. But I don't care for that because it's not really addressing the underlying problem. We might have the same issue elsewhere in cost estimation already, and even if we don't, it would be quite likely we'd introduce it again in future. In some sense the "right" fix would be to do SubPlan generation later, when we have statistics available for the Vars of the parent query. But that seems like a rather large task, and we'd surely not wish to back-patch the results. So I'm not really seeing another workable answer besides hacking examine_variable, more or less as attached. regards, tom lane diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 1c480cfaaf7..1a6db244c94 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -5309,6 +5309,20 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, /* Save the exposed type of the expression */ vardata->vartype = exprType(node); + /* + * It's possible to get here during SubLink planning, before we have + * constructed any RelOptInfos for the parent query level. In that case + * we have to punt by pretending the node is variable-free, since we + * cannot satisfy the API expectation of passing back a RelOptInfo. + */ + if (root->simple_rel_array == NULL) + { + vardata->var = node; + vardata->atttype = vardata->vartype; + vardata->atttypmod = exprTypmod(node); + return; + } + /* Look inside any binary-compatible relabeling */ if (IsA(node, RelabelType))
pgsql-bugs by date: