Re: Removing unneeded self joins

Alexander Korotkov <aekorotkov@gmail.com>

From: Alexander Korotkov <aekorotkov@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Alena Rybakina <a.rybakina@postgrespro.ru>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, Andrei Lepikhov <lepihov@gmail.com>, Robert Haas <robertmhaas@gmail.com>, Richard Guo <guofenglinux@gmail.com>, Alexander Lakhin <exclusion@gmail.com>, "Gregory Stark (as CFM)" <stark.cfm@gmail.com>, Michał Kłeczek <michal@kleczek.org>, Dean Rasheed <dean.a.rasheed@gmail.com>
Date: 2025-02-23T21:15:35Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Remove GUC_NOT_IN_SAMPLE from enable_self_join_elimination

  2. Put enable_self_join_elimination into postgresql.conf.sample

  3. Get rid of ojrelid local variable in remove_rel_from_query()

  4. Implement Self-Join Elimination

  5. Revert: Remove useless self-joins

  6. Replace lateral references to removed rels in subqueries

  7. Replace relids in lateral subquery parse tree during SJE

  8. Forbid SJE with result relation

  9. Fix misuse of RelOptInfo.unique_for_rels cache by SJE

  10. Replace the relid in some missing fields during SJE

  11. Revert 56-bit relfilenode change and follow-up commits.

  12. Stabilize timetz test across DST transitions.

  13. Speed up finding EquivalenceClasses for a given set of rels

  14. Fix mark-and-restore-skipping test case to not be a self-join.

Attachments

On Sun, Feb 23, 2025 at 7:02 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> Alexander Korotkov <aekorotkov@gmail.com> writes:
> > I've corrected some spelling error reported by Alexander Lakhin
> > privately to me.  Also, I've revised comments around ChangeVarNodes()
> > and ChangeVarNodesExtended().  I'm going to continue nitpicking this
> > patch during next couple days then push it if no objections.
>
> Coverity has another nit-pick:
>
> /srv/coverity/git/pgsql-git/postgresql/src/backend/optimizer/plan/analyzejoins.c: 327 in remove_rel_from_query()
> 321     static void
> 322     remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
> 323                                               int subst, SpecialJoinInfo *sjinfo,
> 324                                               Relids joinrelids)
> 325     {
> 326             int                     relid = rel->relid;
> >>>     CID 1643155:  Integer handling issues  (INTEGER_OVERFLOW)
> >>>     Expression "ojrelid", which is equal to 4294967295, where "(sjinfo != NULL) ? sjinfo->ojrelid : 4294967295U" is known to be equal to 4294967295, overflows the type that receives it, a signed integer 32 bits wide.
> 327             int                     ojrelid = (sjinfo != NULL) ? sjinfo->ojrelid : -1;
> 328             Index           rti;
> 329             ListCell   *l;
> 330
> 331             /*
> 332              * Update all_baserels and related relid sets.
>
> This is unhappy because sjinfo->ojrelid, which is declared Index
> (that is, unsigned int) is being converted to int.  Admittedly
> there are plenty of other places that do likewise, but the additional
> load of assuming that -1 isn't a possible value of sjinfo->ojrelid
> seems to be enough to draw its ire.

Thank you for reporting this!

> I suggest finding another way to code this function that doesn't
> depend on that type pun.  I think it's fairly accidental that
> adjust_relid_set doesn't misbehave on -1 anyway, so personally I'd
> get rid of that local variable entirely in favor of something like
>
>     if (sjinfo != NULL)
>     {
>         root->outer_join_rels = adjust_relid_set(root->outer_join_rels,
>                                                  sjinfo->ojrelid, subst);
>         root->all_query_rels = adjust_relid_set(root->all_query_rels,
>                                                 sjinfo->ojrelid, subst);
>     }

There is my attempt to implement this approach.  Getting rid of local
variable (and computation of the same value other way) required to
change arguments of remove_rel_from_eclass() as well.  I'm going to
further polish this tomorrow.

------
Regards,
Alexander Korotkov
Supabase