MCPcopy Create free account
hub / github.com/apache/cloudberry / get_memoize_path

Function get_memoize_path

src/backend/optimizer/path/joinpath.c:597–712  ·  view source on GitHub ↗

* get_memoize_path * If possible, make and return a Memoize path atop of 'inner_path'. * Otherwise return NULL. */

Source from the content-addressed store, hash-verified

595 * Otherwise return NULL.
596 */
597static Path *
598get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel,
599 RelOptInfo *outerrel, Path *inner_path,
600 Path *outer_path, JoinType jointype,
601 JoinPathExtraData *extra)
602{
603 List *param_exprs;
604 List *hash_operators;
605 ListCell *lc;
606 bool binary_mode;
607
608 /* Obviously not if it's disabled */
609 if (!enable_memoize)
610 return NULL;
611
612 /*
613 * We can safely not bother with all this unless we expect to perform more
614 * than one inner scan. The first scan is always going to be a cache
615 * miss. This would likely fail later anyway based on costs, so this is
616 * really just to save some wasted effort.
617 */
618 if (outer_path->parent->rows < 2)
619 return NULL;
620
621 /*
622 * We can only have a memoize node when there's some kind of cache key,
623 * either parameterized path clauses or lateral Vars. No cache key sounds
624 * more like something a Materialize node might be more useful for.
625 */
626 if ((inner_path->param_info == NULL ||
627 inner_path->param_info->ppi_clauses == NIL) &&
628 innerrel->lateral_vars == NIL)
629 return NULL;
630
631 /*
632 * Currently we don't do this for SEMI and ANTI joins unless they're
633 * marked as inner_unique. This is because nested loop SEMI/ANTI joins
634 * don't scan the inner node to completion, which will mean memoize cannot
635 * mark the cache entry as complete.
636 *
637 * XXX Currently we don't attempt to mark SEMI/ANTI joins as inner_unique
638 * = true. Should we? See add_paths_to_joinrel()
639 */
640 if (!extra->inner_unique && (jointype == JOIN_SEMI ||
641 jointype == JOIN_ANTI))
642 return NULL;
643
644 /*
645 * Memoize normally marks cache entries as complete when it runs out of
646 * tuples to read from its subplan. However, with unique joins, Nested
647 * Loop will skip to the next outer tuple after finding the first matching
648 * inner tuple. This means that we may not read the inner side of the
649 * join to completion which leaves no opportunity to mark the cache entry
650 * as complete. To work around that, when the join is unique we
651 * automatically mark cache entries as complete after fetching the first
652 * tuple. This works when the entire join condition is parameterized.
653 * Otherwise, when the parameterization is only a subset of the join
654 * condition, we can't be sure which part of it causes the join to be

Callers 2

match_unsorted_outerFunction · 0.85

Calls 5

list_lengthFunction · 0.85
create_memoize_pathFunction · 0.85
foreachFunction · 0.50

Tested by

no test coverage detected