Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CORE] Creates vanilla plan when the join operators fall back #6093

Merged
merged 1 commit into from
Jul 1, 2024

Conversation

zml1206
Copy link
Contributor

@zml1206 zml1206 commented Jun 14, 2024

What changes were proposed in this pull request?

  1. drop custom strategy for create vanilla plan when the join operators fall back
  2. clickhouse backend already support AQE, delete relevant code.

How was this patch tested?

Copy link

Thanks for opening a pull request!

Could you open an issue for this pull request on Github Issues?

https://github.com/apache/incubator-gluten/issues

Then could you also rename commit message and pull request title in the following format?

[GLUTEN-${ISSUES_ID}][COMPONENT]feat/fix: ${detailed message}

See also:

Copy link

Run Gluten Clickhouse CI

Copy link

Run Gluten Clickhouse CI

3 similar comments
Copy link

Run Gluten Clickhouse CI

Copy link

Run Gluten Clickhouse CI

Copy link

Run Gluten Clickhouse CI

+- ^ RegularHashAggregateExecTransformer (38)
+- ^ ProjectExecTransformer (37)
+- ^ ShuffledHashJoinExecTransformer Inner BuildLeft (36)
:- ^ SortExecTransformer (26)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't drop SortExecTransformer when RAS enabled is a known issue, #6011 @zhztheplayer

@zml1206
Copy link
Contributor Author

zml1206 commented Jun 17, 2024

@ulysses-you @zhztheplayer If you have time, can you help to take a look again? Thank you.

if (isReOptimize && existsShuffledJoin(plan)) {
cost -= 1
}
isReOptimize = !isReOptimize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could understand how this statement works but it's like something too caller-sensitive to rely on.

I see Cost is a trait that can be extended. Could we store the plan's id which is incremental by instantiation order in a customized Cost structure, then use the ID during cost comparison to find out the one that was created later?

Comment on lines 146 to 151
// sql adaptive customCostEvaluatorClass
conf.set(
SQLConf.ADAPTIVE_CUSTOM_COST_EVALUATOR_CLASS.key,
"org.apache.spark.sql.execution.adaptive.GlutenCostEvaluator")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's have a check to raise an error when there was already another cost evaluator set by user.

val simpleCost =
SimpleCostEvaluator(forceOptimizeSkewedJoin).evaluateCost(plan).asInstanceOf[SimpleCost]
var cost = simpleCost.value * 2
if (isReOptimize && plan.exists(_.isInstanceOf[ShuffledJoin])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should only change the plan when there is an actual better build side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have considered it before, but doing this requires a lot of cost. First, need to add extra rule to add tags. Secondly, when the plan contains multiple joins, it is not easy to judge which join is about to be executed. I just modified cost equal. If the costs are equal, it is forced to use new physics plan, which doesn't seem to hurt.

Copy link
Member

@zhztheplayer zhztheplayer Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the costs are equal, it is forced to use new physics plan

Would you like to confirm why the newer plan is always better than the older one? E.g., The newer one carries the latest up-to-date statistics so the build side re-calculation in columnar rule could be more reliable?

If we can make sure the newer is better, then it sounds reasonable to use the newer one.

Copy link
Member

@zhztheplayer zhztheplayer Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, I assume cost(reoptimizePlan) == cost(plan) happens frequently speaking of AQE execution. If so we should measure on the planer performance too.

Copy link
Contributor Author

@zml1206 zml1206 Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default condition for spark to use newPhysicalPlan is newCost < origCost || (newCost == origCost && currentPhysicalPlan != newPhysicalPlan) , this pr just adds a situation, newCost == origCost && currentPhysicalPlan == newPhysicalPlan && !currentPhysicalPlan eq newPhysicalPlan, so I think the performance of newPhysicalPlan has not changed.

Copy link

Run Gluten Clickhouse CI

1 similar comment
Copy link

Run Gluten Clickhouse CI

case class GlutenCost(value: Long, planId: Int) extends Cost {
override def compare(that: Cost): Int = that match {
case GlutenCost(thatValue, thatId) =>
if (value < thatValue || (value == thatValue && planId != thatId)) -1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The planId is increasing, but the parent node may be removed, causing the id to become smaller, such as OptimizeOneRowPlan, so use !=.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is comparatively tricky and important in this PR so let's code it carefully. planId != thatId is still a condition relying on caller code.

Would you check if we can use something like this:

class GlutenCost(val eval: CostEvaluator, val plan: SparkPlan) extends Cost {
  override def compare(that: Cost): Int = that match {
    case that: GlutenCost if plan eq that.plan =>
      0
    case that: GlutenCost if plan == that.plan =>
      // Plans are identical. Considers the newer one as having lower cost.
      -(plan.id - that.plan.id)
    case that: GlutenCost =>
      // Plans are different. Use the delegated cost evaluator.
      assert(eval == that.eval)
      eval.evaluateCost(plan).compare(eval.evaluateCost(that.plan))
    case _ =>
      throw QueryExecutionErrors.cannotCompareCostWithTargetCostError(that.toString)
  }

  override def hashCode(): Int = throw new UnsupportedOperationException()

  override def equals(obj: Any): Boolean = obj match {
    case that: Cost => compare(that) == 0
    case _ => false
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

      eval.evaluateCost(plan).compare(eval.evaluateCost(that.plan))

There seems to be a codependency issue here.
How about this:

class GlutenCost(value: Long, plan: SparkPlan) extends SimpleCost(value) {
  override def compare(that: Cost): Int = that match {
    case that: GlutenCost if plan eq that.plan =>
      0
    case that: GlutenCost if plan == that.plan =>
      // Plans are identical. Considers the newer one as having lower cost.
      -(plan.id - that.plan.id)
    case _ =>
      // Plans are different. Use the default cost compare.
      super.compare(that)
  }

  override def hashCode(): Int = throw new UnsupportedOperationException()

  override def equals(obj: Any): Boolean = obj match {
    case that: Cost => compare(that) == 0
    case _ => false
  }
}

/** This [[CostEvaluator]] is to force use the new physical plan when cost is equal. */
case class GlutenCostEvaluator() extends CostEvaluator with SQLConfHelper {
  override def evaluateCost(plan: SparkPlan): Cost = {
    val forceOptimizeSkewedJoin = conf.getConf(SQLConf.ADAPTIVE_FORCE_OPTIMIZE_SKEWED_JOIN)
    val simpleCost = SimpleCostEvaluator(forceOptimizeSkewedJoin)
      .evaluateCost(plan)
      .asInstanceOf[SimpleCost]
    new GlutenCost(simpleCost.value, plan)
  }
}

Copy link
Member

@zhztheplayer zhztheplayer Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class GlutenCost(value: Long, plan: SparkPlan) extends SimpleCost(value)

I will not be into this approach. Class inherency (despite that it's a case-class inheritance) should be used only when no other ways.

There seems to be a codependency issue here.

There should not be codependency. val eval: CostEvaluator is the one that used by Spark (SimpleCostEvaluator) rather than GlutenCostEvaluator. E.g.,

case class GlutenCostEvaluator() extends CostEvaluator with SQLConfHelper {
  override def evaluateCost(plan: SparkPlan): Cost = {
    val forceOptimizeSkewedJoin = conf.getConf(SQLConf.ADAPTIVE_FORCE_OPTIMIZE_SKEWED_JOIN)
    new GlutenCost(SimpleCostEvaluator(forceOptimizeSkewedJoin), plan)
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SimpleCostEvaluator.evaluateCost return SimpleCost, not GlutenCost

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SimpleCostEvaluator.evaluateCost return SimpleCost, not GlutenCost

It's intentional. Gluten only chooses the newest plan when plans are equal. Otherwise we just compare against SimpleCost.

Copy link
Contributor Author

@zml1206 zml1206 Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class GlutenCost(val eval: CostEvaluator, val plan: SparkPlan) extends Cost {
  override def compare(that: Cost): Int = that match {
    case that: GlutenCost if plan eq that.plan =>
      0
    case that: GlutenCost if plan == that.plan =>
      // Plans are identical. Considers the newer one as having lower cost.
      -(plan.id - that.plan.id)
    case that: GlutenCost =>
      // Plans are different. Use the delegated cost evaluator.
      assert(eval == that.eval)
      eval.evaluateCost(plan).compare(eval.evaluateCost(that.plan))
    case _ =>
      throw QueryExecutionErrors.cannotCompareCostWithTargetCostError(that.toString)
  }

  override def hashCode(): Int = throw new UnsupportedOperationException()

  override def equals(obj: Any): Boolean = obj match {
    case that: Cost => compare(that) == 0
    case _ => false
  }
}

/** This [[CostEvaluator]] is to force use the new physical plan when cost is equal. */
case class GlutenCostEvaluator() extends CostEvaluator with SQLConfHelper {
  override def evaluateCost(plan: SparkPlan): Cost = {
    val forceOptimizeSkewedJoin = conf.getConf(SQLConf.ADAPTIVE_FORCE_OPTIMIZE_SKEWED_JOIN)
    new GlutenCost(SimpleCostEvaluator(forceOptimizeSkewedJoin), plan)
  }
}

smj.joinType,
getBuildSide(smj),
smj.condition,
dropPartialSort(smj.left),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strip local sort is a bit conflict with pull out project, there is a pre-project leak if we pull out expr from sort first but the sort is stripped later. Before the smj can never happen since we plan join at strategy side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t understand. Which rule is it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see PullOutPreProject

case class GlutenCost(value: Long, planId: Int) extends Cost {
override def compare(that: Cost): Int = that match {
case GlutenCost(thatValue, thatId) =>
if (value < thatValue || (value == thatValue && planId != thatId)) -1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does planId != thatId needed ? When will two plan have same planId ?

Comment on lines 39 to 42
val simpleCost = SimpleCostEvaluator(forceOptimizeSkewedJoin)
.evaluateCost(plan)
.asInstanceOf[SimpleCost]
GlutenCost(simpleCost.value, plan.id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add one more config to crontrol this feature ? if disable then do nothing.

Copy link
Contributor Author

@zml1206 zml1206 Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about add GlutenConfig spark.gluten.sql.execution.adaptive.costEvaluator.enabled, if true, use GlutenCostEvaluator, else follow the configuration spark.sql.adaptive.customCostEvaluatorClass?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, besides, we'd better to respect spark.gluten.enabled even costEvaluator is enabled. People may tune spark.gluten.enabled off at runtime.

Copy link

Run Gluten Clickhouse CI

3 similar comments
Copy link

Run Gluten Clickhouse CI

Copy link

Run Gluten Clickhouse CI

Copy link

Run Gluten Clickhouse CI

@zhztheplayer
Copy link
Member

@zml1206 Would you like to rebase onto newest main code since #6107 was merged? Thank you very much.

Copy link

Run Gluten Clickhouse CI

1 similar comment
Copy link

Run Gluten Clickhouse CI

zhztheplayer
zhztheplayer previously approved these changes Jun 18, 2024
Copy link
Member

@zhztheplayer zhztheplayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

% a rebase. Thanks.

Copy link

Run Gluten Clickhouse CI

1 similar comment
Copy link

Run Gluten Clickhouse CI

Comment on lines 70 to 73
private val nodeNameMap = Map(
"SortMergeJoin" -> "ShuffledHashJoin",
"SortMergeJoin(skew=true)" -> "ShuffledHashJoin(skew=true)")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this mapping needed? This is like an exception comparing to other rewrites.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

year, other rules are to add nodes, and rewriteJoin is to replace nodes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use nodeName to get original plan is bit strict. It seems the only added node is ProjectExec. We can skip all ProjectExec and make sure there is only one target rewritten plan. e.g.:

-  private def getTransformHintBack(
-      origin: SparkPlan,
-      rewrittenPlan: SparkPlan): Option[TransformHint] = {
-    // The rewritten plan may contain more nodes than origin, here use the node name to get it back
+  private def getTransformHintBack(rewrittenPlan: SparkPlan): Option[TransformHint] = {
+    // The rewritten plan may contain more nodes than origin, for now it should only be
+    // `ProjectExec`.
     val target = rewrittenPlan.collect {
-      case p if p.nodeName == origin.nodeName => p
+      case p if !p.isInstanceOf[ProjectExec] => p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, also excludes RewrittenNodeWall.

@zhztheplayer
Copy link
Member

Run Gluten Clickhouse CI

1 similar comment
Copy link

Run Gluten Clickhouse CI

@ulysses-you
Copy link
Contributor

@zml1206 It seems clickhouse failed test is related, jenkins account:
https://github.com/apache/incubator-gluten/blob/main/docs/get-started/ClickHouse.md#new-ci-system

Copy link

Run Gluten Clickhouse CI

1 similar comment
Copy link

Run Gluten Clickhouse CI

case smj: SortMergeJoinExec if GlutenConfig.getConf.forceShuffledHashJoin =>
getBuildSide(smj.joinType) match {
case Some(buildSide) =>
ShuffledHashJoinExec(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move drop local sort code into this rule ? The sort is a part pf smj, we should handle them together. We do not need introduce SortUtils, just move code into this rule.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RewriteSparkPlanRulesManager currently handles a single node, and simple move code cannot be achieved.
Is it possible to consider whether it can be optimized in future pr?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, keep SortUtils for use it later for sortAgg.

}

override def rewrite(plan: SparkPlan): SparkPlan = plan match {
case smj: SortMergeJoinExec if GlutenConfig.getConf.forceShuffledHashJoin =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: better to define val forceShuffledHashJoin = GlutenConfig.getConf.forceShuffledHashJoin as the class member variables

Copy link
Contributor Author

@zml1206 zml1206 Jun 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RewriteJoin is object, define val cannot be modified forceShuffledHashJoin dynamically.

@@ -421,7 +395,7 @@ case class AddTransformHintRule() extends Rule[SparkPlan] {
plan.leftKeys,
plan.rightKeys,
plan.joinType,
TransformHints.getShuffleHashJoinBuildSide(plan),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need change it? The build side may be changed when we offload shj, and we should use the target build side to do validate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it carefully. The buildSide itself is the legal buildSide in the corresponding backends obtained. The buildSide will not be verified in doValidate, and it should not be done in the future. If there are changes in the future, the corresponding supportHashBuildJoinTypeOnLeft and supportHashBuildJoinTypeOnRight should be changed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buildSide here is from vanilla Spark rather than Gluten backends.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, but I think there is no need to convert here, because do validate does not require buildside.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still stay consistent to avoid risks, updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should match SortMergeJoinExec in mayNeedRewrite. The CI did not fail due to the SortMergeJoinExec always have SortExec.

Copy link
Contributor Author

@zml1206 zml1206 Jun 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mayNeedRewrite match BaseJoinExec, it contains SortMergeJoinExec.

@zml1206 zml1206 requested a review from ulysses-you June 27, 2024 02:52
Copy link

Run Gluten Clickhouse CI

1 similar comment
Copy link

Run Gluten Clickhouse CI

@ulysses-you
Copy link
Contributor

/Benchmark Velox TPCDS

1 similar comment
@ulysses-you
Copy link
Contributor

/Benchmark Velox TPCDS

@zml1206
Copy link
Contributor Author

zml1206 commented Jun 28, 2024

There seems to be a problem with the benchmark workflow and it keeps being queued. @ulysses-you cc @zhztheplayer

@zml1206
Copy link
Contributor Author

zml1206 commented Jun 28, 2024

/Benchmark Velox TPCDS

@zhouyuan
Copy link
Contributor

CC @zzcclp @baibaichen

@GlutenPerfBot
Copy link
Contributor

===== Performance report for TPCDS SF2000 with Velox backend, for reference only ====

query log/native_6093_time.csv log/native_master_06_27_2024_22dc4fdcb_time.csv difference percentage
q1 14.56 14.69 0.132 100.91%
q2 14.85 19.29 4.435 129.86%
q3 5.68 4.34 -1.342 76.39%
q4 63.12 63.59 0.465 100.74%
q5 7.81 6.46 -1.345 82.77%
q6 3.90 3.58 -0.320 91.80%
q7 4.22 4.12 -0.095 97.74%
q8 5.11 5.08 -0.025 99.51%
q9 17.34 18.54 1.202 106.93%
q10 10.97 11.30 0.336 103.07%
q11 35.63 36.94 1.306 103.67%
q12 1.55 2.41 0.866 155.99%
q13 5.24 5.68 0.439 108.38%
q14a 43.54 41.94 -1.599 96.33%
q14b 40.76 44.07 3.307 108.11%
q15 2.54 2.84 0.308 112.16%
q16 42.15 39.50 -2.652 93.71%
q17 4.78 4.81 0.028 100.58%
q18 7.56 6.24 -1.319 82.56%
q19 2.45 2.39 -0.054 97.79%
q20 1.41 1.42 0.011 100.75%
q21 2.43 5.68 3.242 233.19%
q22 7.73 8.70 0.969 112.54%
q23a 86.61 87.00 0.395 100.46%
q23b 105.26 102.16 -3.104 97.05%
q24a 79.85 75.38 -4.470 94.40%
q24b 69.63 76.71 7.078 110.16%
q25 4.31 5.95 1.642 138.08%
q26 2.62 2.97 0.349 113.35%
q27 3.12 3.30 0.183 105.86%
q28 21.19 23.56 2.370 111.19%
q29 8.12 7.70 -0.421 94.82%
q30 10.25 6.47 -3.781 63.12%
q31 7.43 6.23 -1.196 83.91%
q32 1.17 1.10 -0.077 93.44%
q33 4.93 4.84 -0.085 98.28%
q34 3.90 3.54 -0.355 90.90%
q35 6.65 6.47 -0.184 97.23%
q36 3.32 3.30 -0.020 99.41%
q37 4.35 3.95 -0.396 90.90%
q38 11.66 11.86 0.200 101.71%
q39a 3.31 3.42 0.119 103.59%
q39b 2.85 2.87 0.024 100.85%
q40 5.32 3.75 -1.571 70.46%
q41 0.63 0.62 -0.014 97.75%
q42 1.07 0.92 -0.143 86.60%
q43 3.77 3.52 -0.250 93.38%
q44 14.68 8.25 -6.430 56.20%
q45 3.53 3.67 0.138 103.92%
q46 3.41 3.31 -0.101 97.03%
q47 14.11 14.71 0.601 104.26%
q48 4.76 4.57 -0.192 95.98%
q49 9.42 9.74 0.321 103.40%
q50 20.99 23.70 2.702 112.87%
q51 8.97 8.40 -0.571 93.64%
q52 1.02 1.08 0.062 106.07%
q53 1.95 2.03 0.083 104.24%
q54 3.33 3.45 0.122 103.68%
q55 1.03 1.02 -0.011 98.97%
q56 4.38 4.46 0.081 101.85%
q57 8.43 8.48 0.049 100.58%
q58 2.69 2.69 -0.001 99.96%
q59 14.15 13.96 -0.195 98.62%
q60 4.68 6.49 1.807 138.62%
q61 5.32 5.72 0.400 107.52%
q62 5.63 4.55 -1.079 80.83%
q63 4.15 2.33 -1.819 56.13%
q64 48.79 49.04 0.247 100.51%
q65 16.10 13.81 -2.293 85.76%
q66 3.52 5.59 2.074 158.94%
q67 347.57 349.42 1.855 100.53%
q68 3.70 3.45 -0.246 93.35%
q69 6.50 6.40 -0.095 98.54%
q70 8.95 13.50 4.557 150.94%
q71 2.49 2.02 -0.472 81.06%
q72 185.30 187.82 2.526 101.36%
q73 2.41 4.45 2.048 185.11%
q74 21.75 22.19 0.442 102.03%
q75 23.16 23.03 -0.133 99.43%
q76 9.65 9.14 -0.508 94.73%
q77 2.28 2.19 -0.087 96.20%
q78 38.73 41.33 2.600 106.71%
q79 3.61 3.57 -0.034 99.05%
q80 11.31 11.02 -0.294 97.40%
q81 5.10 5.29 0.183 103.59%
q82 6.88 9.55 2.671 138.85%
q83 1.48 1.60 0.128 108.69%
q84 2.78 2.78 -0.004 99.86%
q85 6.65 7.01 0.361 105.42%
q86 3.22 3.21 -0.011 99.65%
q87 12.29 12.23 -0.061 99.50%
q88 28.47 27.33 -1.138 96.00%
q89 3.38 3.36 -0.021 99.39%
q90 4.57 10.11 5.531 220.91%
q91 2.61 2.62 0.001 100.04%
q92 1.27 1.35 0.089 107.00%
q93 29.17 28.71 -0.458 98.43%
q94 21.25 21.28 0.035 100.16%
q9 82.96 85.02 2.064 102.49%
q5 3.46 3.53 0.069 102.00%
q96 12.31 12.38 0.070 100.57%
q97 1.99 2.16 0.167 108.37%
q98 12.59 8.93 -3.659 70.94%
q99 12.59 8.93 -3.659 70.94%
total 1911.50 1930.27 18.763 100.98%

fix

fix

fix

fix ut

fix ut

update

fix

update

fix

fix

fix

update

update golden file

split add cost evaluator

fix

update

update

update

fix

refactor to convert SortMergeJoinExec to ShuffledHashJoinExec

update

fix

fix

update

fix

fix ck ut

fix style

move drop local sort into RewriteJoin

update
@zml1206
Copy link
Contributor Author

zml1206 commented Jun 28, 2024

Resolve conflicts

Copy link

Run Gluten Clickhouse CI

Copy link
Contributor

@ulysses-you ulysses-you left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thank you @zml1206

@ulysses-you ulysses-you merged commit d516f56 into apache:main Jul 1, 2024
40 checks passed
@zml1206
Copy link
Contributor Author

zml1206 commented Jul 1, 2024

Thank you very much for your patiently review. @ulysses-you @zhztheplayer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants