memoize_semi_and_anti_joins_experiment.patch

application/octet-stream

Filename: memoize_semi_and_anti_joins_experiment.patch
Type: application/octet-stream
Part: 0
Message: Re: Memoize ANTI and SEMI JOIN inner

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/optimizer/path/joinpath.c 2 15
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 18891ce9156..03b4506e873 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -714,19 +714,6 @@ get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel,
 		ph_lateral_vars == NIL)
 		return NULL;
 
-	/*
-	 * Currently we don't do this for SEMI and ANTI joins unless they're
-	 * marked as inner_unique.  This is because nested loop SEMI/ANTI joins
-	 * don't scan the inner node to completion, which will mean memoize cannot
-	 * mark the cache entry as complete.
-	 *
-	 * XXX Currently we don't attempt to mark SEMI/ANTI joins as inner_unique
-	 * = true.  Should we?  See add_paths_to_joinrel()
-	 */
-	if (!extra->inner_unique && (jointype == JOIN_SEMI ||
-								 jointype == JOIN_ANTI))
-		return NULL;
-
 	/*
 	 * Memoize normally marks cache entries as complete when it runs out of
 	 * tuples to read from its subplan.  However, with unique joins, Nested
@@ -753,7 +740,7 @@ get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel,
 	 * the inner scan's filter instead of the join filter.  Maybe it's worth
 	 * considering doing that?
 	 */
-	if (extra->inner_unique &&
+	if ((extra->inner_unique || jointype == JOIN_SEMI || jointype == JOIN_ANTI) &&
 		(inner_path->param_info == NULL ||
 		 bms_num_members(inner_path->param_info->ppi_serials) <
 		 list_length(extra->restrictlist)))
@@ -808,7 +795,7 @@ get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel,
 											inner_path,
 											param_exprs,
 											hash_operators,
-											extra->inner_unique,
+											extra->inner_unique || jointype == JOIN_SEMI || jointype == JOIN_ANTI,
 											binary_mode,
 											outer_path->rows);
 	}