fanfuxiaoran commented on code in PR #724:
URL: https://github.com/apache/cloudberry/pull/724#discussion_r1853241023
##########
src/backend/executor/nodeHashjoin.c:
##########
@@ -162,6 +164,16 @@ static void ReleaseHashTable(HashJoinState *node);
static void SpillCurrentBatch(HashJoinState *node);
static bool ExecHashJoinReloadHashTable(HashJoinState *hjstate);
static void ExecEagerFreeHashJoin(HashJoinState *node);
+static void CreateRuntimeFilter(HashJoinState* hjstate);
+static bool IsEqualOp(Expr *expr);
+static bool CheckEqualArgs(Expr *expr, AttrNumber *lattno, AttrNumber *rattno);
+static PlanState *FindTargetAttr(HashJoinState *hjstate,
Review Comment:
Looks FindTargetNode is better.
##########
src/backend/executor/nodeHashjoin.c:
##########
@@ -2157,3 +2174,225 @@ ExecHashJoinInitializeWorker(HashJoinState *state,
ExecSetExecProcNode(&state->js.ps, ExecParallelHashJoin);
}
}
+
+/*
+ * Find "inner var = outer var" in hj->hashclauses and create runtime filter
+ * for it.
+ */
+void
+CreateRuntimeFilter(HashJoinState* hjstate)
+{
+ AttrNumber lattno, rattno;
+ Expr *expr;
+ JoinType jointype;
+ HashJoin *hj;
+ HashState *hstate;
+ PlanState *target;
+ AttrFilter *attr_filter;
+ ListCell *lc;
+
+ /*
+ * Only applicatable for inner, right and semi join,
+ */
+ jointype = hjstate->js.jointype;
+ if (jointype != JOIN_INNER
+ && jointype != JOIN_RIGHT
+ && jointype != JOIN_SEMI
+ )
+ return;
+
+ hstate = castNode(HashState, innerPlanState(hjstate));
+ hstate->filters = NIL;
+
+ /*
+ * check and initialize the runtime filter for all hash conds in
+ * hj->hashclauses
+ */
+ hj = castNode(HashJoin, hjstate->js.ps.plan);
+ foreach (lc, hj->hashclauses)
+ {
+ expr = (Expr *)lfirst(lc);
+
+ if (!IsEqualOp(expr))
+ continue;
+
+ lattno = -1;
+ rattno = -1;
+ if (!CheckEqualArgs(expr, &lattno, &rattno))
+ continue;
+
+ if (lattno < 1 || rattno < 1)
+ continue;
+
+ target = FindTargetAttr(hjstate, lattno, &lattno);
+ if (lattno == -1 || target == NULL || IsA(target,
HashJoinState))
+ continue;
+ Assert(IsA(target, SeqScanState));
+
+ attr_filter = CreateAttrFilter(target, lattno, rattno,
+
hstate->ps.plan->plan_rows);
+ if (attr_filter->blm_filter)
+ hstate->filters = lappend(hstate->filters, attr_filter);
+ else
+ pfree(attr_filter);
+ }
+}
+
+static bool
+IsEqualOp(Expr *expr)
+{
+ Oid funcid = InvalidOid;
+
+ if (!IsA(expr, OpExpr) && !IsA(expr, FuncExpr))
+ return false;
+
+ if (IsA(expr, OpExpr))
+ funcid = ((OpExpr *)expr)->opfuncid;
+ else if (IsA(expr, FuncExpr))
+ funcid = ((FuncExpr *)expr)->funcid;
+ else
+ return false;
+
+ if (funcid == F_INT2EQ || funcid == F_INT4EQ || funcid == F_INT8EQ
+ || funcid == F_INT24EQ || funcid == F_INT42EQ
+ || funcid == F_INT28EQ || funcid == F_INT82EQ
+ || funcid == F_INT48EQ || funcid == F_INT84EQ
+ )
+ return true;
+
+ return false;
+}
+
+/*
+ * runtime filters which can be pushed down:
+ * 1. hash expr MUST BE equal op;
+ * 2. args MUST BE Var node;
+ * 3. the data type MUST BE integer;
+ */
+static bool
+CheckEqualArgs(Expr *expr, AttrNumber *lattno, AttrNumber *rattno)
+{
+ Var *var;
+ bool match;
+ List *args;
+ ListCell *lc;
+
+ if (lattno == NULL || rattno == NULL)
+ return false;
+
+ if (!IsA(expr, OpExpr) && !IsA(expr, FuncExpr))
+ return false;
+
+ if (IsA(expr, OpExpr))
+ args = ((OpExpr *)expr)->args;
+ else if (IsA(expr, FuncExpr))
+ args = ((FuncExpr *)expr)->args;
+ else
+ return false;
+
+ if (!args || list_length(args) != 2)
+ return false;
+
+ match = false;
+ foreach (lc, args)
+ {
+ match = false;
+
+ if (!IsA(lfirst(lc), Var))
Review Comment:
Could it support other expression, whose one arg is the column attr, and the
other is a const?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]