Skip to content

Add in tests for Colocated joins with table hints#17846

Open
deepthi912 wants to merge 5 commits intoapache:masterfrom
deepthi912:colocatedJoin-tests
Open

Add in tests for Colocated joins with table hints#17846
deepthi912 wants to merge 5 commits intoapache:masterfrom
deepthi912:colocatedJoin-tests

Conversation

@deepthi912
Copy link
Collaborator

In reference to #16603 there have been changes to the colocated joins and the query hints used there. This PR adds in integration tests that can help us test the configs through which the colocated joins can be identified and be enabled for the user so the hash join and regular data shuffles are eliminated as the data and worker operations is colocated on a single server for the same partitions of the tables that would be joined in the query.

@codecov-commenter
Copy link

codecov-commenter commented Mar 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.25%. Comparing base (097a89f) to head (fa1d65d).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #17846      +/-   ##
============================================
- Coverage     63.27%   63.25%   -0.02%     
- Complexity     1466     1481      +15     
============================================
  Files          3190     3190              
  Lines        192101   192287     +186     
  Branches      29433    29471      +38     
============================================
+ Hits         121547   121627      +80     
- Misses        61040    61131      +91     
- Partials       9514     9529      +15     
Flag Coverage Δ
custom-integration1 100.00% <ø> (ø)
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-11 63.21% <ø> (-0.01%) ⬇️
java-21 63.22% <ø> (-0.03%) ⬇️
temurin 63.25% <ø> (-0.02%) ⬇️
unittests 63.24% <ø> (-0.02%) ⬇️
unittests1 55.58% <ø> (-0.01%) ⬇️
unittests2 34.25% <ø> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@yashmayya yashmayya left a comment

Choose a reason for hiding this comment

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

I've added a number of suggestions here, please take a look.

Comment on lines +128 to +140
/** Three-table join: result correctness with colocated hint. */
@Test
public void testThreeTableJoinResultCorrectness()
throws Exception {
String tableOpt = getTableOptPerTableHint();
String sql = "SELECT COUNT(*) FROM userAttributes /*+ " + tableOpt + " */ ua "
+ "JOIN userGroups /*+ " + tableOpt + " */ ug ON ua.userUUID = ug.userUUID "
+ "JOIN userFactEvents /*+ " + tableOpt + " */ ue ON ua.userUUID = ue.userUUID";
JsonNode result = postQuery(sql);
assertNoExceptions(result);
long count = getCountFromResult(result);
assertTrue(count >= 1, "Three-table join should return at least one row");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

How is this test validating join result correctness?

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO the result should be manually validated and exact counts should be asserted instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively, we can also validate against results using non colocated join queries.

startZk();
startController();
startBrokers(1);
startServers(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

How are we even testing colocated joins if there's a single server setup?

}
}

/** Two-table join with mismatched partition_size in hints: planner rejects with partition size mismatch error
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add one for mismatched partition function too?

/**
* Base integration tests for colocated joins tests(multi-stage engine).
*/
public abstract class ColocatedJoinIntegrationTestBase extends BaseClusterIntegrationTestSet {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we don't have any coverage for composite join keys (multi column)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Another case is when table is partitioned on one column but we're using a different column as the join key. We need positive / negative tests for this.

/**
* Base integration tests for colocated joins tests(multi-stage engine).
*/
public abstract class ColocatedJoinIntegrationTestBase extends BaseClusterIntegrationTestSet {
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if there are equi + non-equi join conditions with colocated join hints?


/** Two-table join with joinOptions colocated but only one table has tableOptions hint (partial config). */
@Test
public void testTwoTableJoinWithPartialTableOptionsResultCorrectness()
Copy link
Contributor

Choose a reason for hiding this comment

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

Why / how does this work?

cc - @gortiz

/** Two-table join with joinOptions(is_colocated_by_join_keys='null'): explicit 'null' disables colocated exchange
* (plan does not use [PARTITIONED]); query still succeeds with correct result. */
@Test
public void testTwoTableJoinWithJoinOptionsColocatedKeyExplicitNullResultCorrectness()
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the point of this test?

* assertion {@code [PARTITIONED]}). Adds third table (userFactEvents) and three-table colocated
* join tests.
*/
public class ColocatedJoinMultiPartitionIntegrationTest extends ColocatedJoinIntegrationTestBase {
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 make these tests also support realtime or hybrid tables? The partitioning info is calculated differently in those cases

* assertion {@code [PARTITIONED]}). Adds third table (userFactEvents) and three-table colocated
* join tests.
*/
public class ColocatedJoinMultiPartitionIntegrationTest extends ColocatedJoinIntegrationTestBase {
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 also have some tests for partition_parallelism?

Copy link
Contributor

Choose a reason for hiding this comment

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

This one supports multiple workers per partition

assertNoExceptions(result);
String plan = extractImplementationPlan(result);
assertNotNull(plan, "implementation plan should be present");
assertTrue(plan.contains(PLAN_PARTITIONED_MARKER), message + plan);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a very weak assertion. We should check it's on the correct stage / exchange, no unnecessary shuffles elsewhere in the plan, number of PARTITIONED markers etc. Also ideally we want to assert on the actual query stage stats too (validating that raw messages is 0 / there are only in-memory messages across the colocated stages) since this PARTITIONED marker is a weak assertion (you can trace the code path that adds this to the explain plan output).

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.

3 participants