Thread

  1. Re: pg_plan_advice

    Robert Haas <robertmhaas@gmail.com> — 2025-12-09T19:45:47Z

    On Mon, Dec 8, 2025 at 8:19 PM Jacob Champion
    <jacob.champion@enterprisedb.com> wrote:
    > I really like this idea! Telling the planner, "if you need to make a
    > decision for [this thing], choose [this way]," seems to be a really
    > nice way of sidestepping many of the concerns with "user control".
    >
    > I've started an attempt to throw a fuzzer at this, because I'm pretty
    > useless when it comes to planner/optimizer review. I don't really know
    > what the overall fuzzing strategy is going to be, given the multiple
    > complicated inputs that have to be constructed and somehow correlated
    > with each other, but I'll try to start small and expand:
    >
    > a) fuzz the parser first, because it's easy and we can get interesting inputs
    > b) fuzz the AST utilities, seeded with "successful" corpus members from a)
    > c) stare really hard at the corpus of b) and figure out how to
    > usefully mutate a PlannedStmt with it
    > d) use c) to fuzz pgpa_plan_walker, then pgpa_output_advice, then...?
    
    Cool. I'm bad at fuzzing, but I think fuzzing by someone who is good
    at it is very promising for this kind of patch.
    
    > I'm in the middle of an implementation of b) now, and it noticed the
    > following code (which probably bodes well for the fuzzer itself!):
    >
    > >        if (rid->partnsp == NULL)
    > >            result = psprintf("%s/%s", result,
    > >                              quote_identifier(rid->partnsp));
    >
    > I assume that should be quote_identifier(rid->partrel)?
    
    Yes, thanks. Fixed locally. By the way, if your fuzzer can also
    produces some things to add contrib/pg_plan_advice/sql for cases like
    this, that would be quite helpful. Ideally I would have caught this
    with a manually-written test case, but obviously that didn't happen.
    
    > = Other Notes =
    >
    > GCC 11 complains about the following code in pgpa_collect_advice():
    >
    > >        dsa_area   *area = pg_plan_advice_dsa_area();
    > >        dsa_pointer ca_pointer;
    > >
    > >        pgpa_make_collected_advice(userid, dbid, queryId, now,
    > >                                   query_string, advice_string, area,
    > >                                   &ca_pointer);
    > >        pgpa_store_shared_advice(ca_pointer);
    >
    > It doesn't know that area is guaranteed to be non-NULL, so it can't
    > prove that ca_pointer is initialized.
    
    I don't know what to do about that. I can understand why it might be
    unable to prove that, but I don't see an obvious way to change the
    code that would make life easier. I could add Assert(area != NULL)
    before the call to pgpa_make_collected_advice() if that helps.
    
    > (GCC also complains about unique_nonjoin_rtekind() not initializing
    > the rtekind, but I think that's because of a bug [1].)
    
    This one could be fixed with a dummy initialization, if needed.
    
    --
    Robert Haas
    EDB: http://www.enterprisedb.com