diff --git a/cpp/velox/substrait/SubstraitToVeloxPlan.cc b/cpp/velox/substrait/SubstraitToVeloxPlan.cc index 0dab6b280a5e..58fc4020bf2b 100644 --- a/cpp/velox/substrait/SubstraitToVeloxPlan.cc +++ b/cpp/velox/substrait/SubstraitToVeloxPlan.cc @@ -391,6 +391,9 @@ core::PlanNodePtr SubstraitToVeloxPlanConverter::toVeloxPlan(const ::substrait:: case ::substrait::CrossRel_JoinType::CrossRel_JoinType_JOIN_TYPE_LEFT: joinType = core::JoinType::kLeft; break; + case ::substrait::CrossRel_JoinType::CrossRel_JoinType_JOIN_TYPE_RIGHT: + joinType = core::JoinType::kRight; + break; default: VELOX_NYI("Unsupported Join type: {}", std::to_string(crossRel.type())); } diff --git a/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc b/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc index 42d91bd48d12..54021a574494 100644 --- a/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc +++ b/cpp/velox/substrait/SubstraitToVeloxPlanValidator.cc @@ -973,6 +973,7 @@ bool SubstraitToVeloxPlanValidator::validate(const ::substrait::CrossRel& crossR switch (crossRel.type()) { case ::substrait::CrossRel_JoinType_JOIN_TYPE_INNER: case ::substrait::CrossRel_JoinType_JOIN_TYPE_LEFT: + case ::substrait::CrossRel_JoinType_JOIN_TYPE_RIGHT: break; default: LOG_VALIDATION_MSG("Unsupported Join type in CrossRel"); diff --git a/gluten-substrait/src/main/scala/org/apache/gluten/execution/BroadcastNestedLoopJoinExecTransformer.scala b/gluten-substrait/src/main/scala/org/apache/gluten/execution/BroadcastNestedLoopJoinExecTransformer.scala index ae407b3b3efa..b7be3d90ca34 100644 --- a/gluten-substrait/src/main/scala/org/apache/gluten/execution/BroadcastNestedLoopJoinExecTransformer.scala +++ b/gluten-substrait/src/main/scala/org/apache/gluten/execution/BroadcastNestedLoopJoinExecTransformer.scala @@ -49,9 +49,9 @@ abstract class BroadcastNestedLoopJoinExecTransformer( override def rightKeys: Seq[Expression] = Nil private lazy val substraitJoinType: CrossRel.JoinType = - SubstraitUtil.toCrossRelSubstrait(joinType) + SubstraitUtil.toCrossRelSubstrait(joinType, needSwitchChildren) - // Unique ID for builded table + // Unique ID for built table. lazy val buildBroadcastTableId: String = "BuiltBNLJBroadcastTable-" + buildPlan.id // Hint substrait to switch the left and right, @@ -96,6 +96,7 @@ abstract class BroadcastNestedLoopJoinExecTransformer( joinType match { case _: InnerLike => right.outputPartitioning case RightOuter => right.outputPartitioning + case LeftOuter => left.outputPartitioning case x => throw new IllegalArgumentException( s"BroadcastNestedLoopJoin should not take $x as the JoinType with building left side") @@ -104,6 +105,7 @@ abstract class BroadcastNestedLoopJoinExecTransformer( joinType match { case _: InnerLike => left.outputPartitioning case LeftOuter => left.outputPartitioning + case RightOuter => right.outputPartitioning case x => throw new IllegalArgumentException( s"BroadcastNestedLoopJoin should not take $x as the JoinType with building right side") @@ -123,9 +125,7 @@ abstract class BroadcastNestedLoopJoinExecTransformer( val operatorId = context.nextOperatorId(this.nodeName) val joinParams = new JoinParams - if (condition.isDefined) { - joinParams.isWithCondition = true - } + joinParams.isWithCondition = condition.isDefined val crossRel = JoinUtils.createCrossRel( substraitJoinType, @@ -162,21 +162,11 @@ abstract class BroadcastNestedLoopJoinExecTransformer( } def validateJoinTypeAndBuildSide(): ValidationResult = { - val result = joinType match { + joinType match { case _: InnerLike | LeftOuter | RightOuter => ValidationResult.succeeded case _ => ValidationResult.failed(s"$joinType join is not supported with BroadcastNestedLoopJoin") } - - if (!result.ok()) { - return result - } - - (joinType, buildSide) match { - case (LeftOuter, BuildLeft) | (RightOuter, BuildRight) => - ValidationResult.failed(s"$joinType join is not supported with $buildSide") - case _ => ValidationResult.succeeded // continue - } } override protected def doValidateInternal(): ValidationResult = { diff --git a/gluten-substrait/src/main/scala/org/apache/gluten/utils/SubstraitUtil.scala b/gluten-substrait/src/main/scala/org/apache/gluten/utils/SubstraitUtil.scala index c150391434f7..6a678014ebcd 100644 --- a/gluten-substrait/src/main/scala/org/apache/gluten/utils/SubstraitUtil.scala +++ b/gluten-substrait/src/main/scala/org/apache/gluten/utils/SubstraitUtil.scala @@ -49,6 +49,33 @@ object SubstraitUtil { JoinRel.JoinType.UNRECOGNIZED } + def toCrossRelSubstrait(sparkJoin: JoinType, needSwitchChildren: Boolean): CrossRel.JoinType = + sparkJoin match { + case _: InnerLike => + CrossRel.JoinType.JOIN_TYPE_INNER + case LeftOuter => + // since we always assume build right side in substrait, + // the left and right relations are exchanged and the + // join type is reverted. + if (needSwitchChildren) { + CrossRel.JoinType.JOIN_TYPE_RIGHT + } else { + CrossRel.JoinType.JOIN_TYPE_LEFT + } + case RightOuter => + if (needSwitchChildren) { + CrossRel.JoinType.JOIN_TYPE_LEFT + } else { + CrossRel.JoinType.JOIN_TYPE_RIGHT + } + case LeftSemi => + CrossRel.JoinType.JOIN_TYPE_LEFT_SEMI + case FullOuter => + CrossRel.JoinType.JOIN_TYPE_OUTER + case _ => + CrossRel.JoinType.UNRECOGNIZED + } + def toCrossRelSubstrait(sparkJoin: JoinType): CrossRel.JoinType = sparkJoin match { case _: InnerLike => CrossRel.JoinType.JOIN_TYPE_INNER