Re: assertion failure at cost_memoize_rescan() - Mailing list pgsql-hackers

From David Rowley
Subject Re: assertion failure at cost_memoize_rescan()
Date
Msg-id CAApHDvq6RpWyRs1iJg7CsyhX_SqDyv8znzjqPgBHD3ddYF19Rw@mail.gmail.com
Whole thread Raw
In response to Re: assertion failure at cost_memoize_rescan()  (Kohei KaiGai <kaigai@heterodb.com>)
Responses Re: assertion failure at cost_memoize_rescan()
List pgsql-hackers
On Tue, 18 Jun 2024 at 14:23, Kohei KaiGai <kaigai@heterodb.com> wrote:
>
> 2024年6月17日(月) 8:27 David Rowley <dgrowleyml@gmail.com>:
> > It would be good to know what type of Path outer_path is.  Normally
> > we'll clamp_row_est() on that field. I suspect we must have some Path
> > type that isn't doing that.
> >
> > KaiGai-san,  what type of Path is outer_path?
> >
> It is CustomPath with rows = 3251872.916666667.

I suspected this might have been a CustomPath.

> (I'm not certain whether the non-integer value in the estimated rows
> is legal or not.)

I guess since it's not documented that Path.rows is always clamped,
it's probably bad to assume that it is.

Since clamp_row_est() will ensure the value is clamped >= 1.0 && <=
MAXIMUM_ROWCOUNT (which ensures non-zero), I tried looking around the
codebase for anything that divides by Path.rows to see if we ever
assume that we can divide without first checking if Path.rows != 0.
Out of the places I saw, it seems we do tend to code things so that we
don't assume the value has been clamped.  E.g.
adjust_limit_rows_costs() does if (*rows < 1) *rows = 1;

I think the best solution is to apply the attached.  I didn't test,
but it should fix the issue you reported and also ensure that
MemoizePath.calls is never zero, which would also cause issues in the
hit_ratio calculation in cost_memoize_rescan().

David

Attachment

pgsql-hackers by date:

Previous
From: Nathan Bossart
Date:
Subject: Re: Better error message when --single is not the first arg to postgres executable
Next
From: Nathan Bossart
Date:
Subject: Re: New GUC autovacuum_max_threshold ?