mirror of https://github.com/apache/druid.git
Pushdown join filter with right side referencing columns (#12749)
This commit is contained in:
parent
378fea9517
commit
bcff35f798
|
@ -261,7 +261,9 @@ public class JoinableFactoryWrapper
|
||||||
* - the right-hand columns referenced by the condition must not have any duplicate values. If there are duplicates
|
* - the right-hand columns referenced by the condition must not have any duplicate values. If there are duplicates
|
||||||
* values in the column, then the join is tried to be converted to a filter while maintaining the join clause on top
|
* values in the column, then the join is tried to be converted to a filter while maintaining the join clause on top
|
||||||
* as well for correct results.
|
* as well for correct results.
|
||||||
* - no columns from the right-hand side can appear in "requiredColumns"
|
* - no columns from the right-hand side can appear in "requiredColumns". If the columns from right side are required
|
||||||
|
* (ie they are directly or indirectly projected in the join output), then the join is tried to be converted to a
|
||||||
|
* filter while maintaining the join clause on top as well for correct results.
|
||||||
*
|
*
|
||||||
* @return {@link JoinClauseToFilterConversion} object which contains the converted filter for the clause and a boolean
|
* @return {@link JoinClauseToFilterConversion} object which contains the converted filter for the clause and a boolean
|
||||||
* to represent whether the converted filter encapsulates the whole clause or not. More semantics of the object are
|
* to represent whether the converted filter encapsulates the whole clause or not. More semantics of the object are
|
||||||
|
@ -275,12 +277,12 @@ public class JoinableFactoryWrapper
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (clause.getJoinType() == JoinType.INNER
|
if (clause.getJoinType() == JoinType.INNER
|
||||||
&& requiredColumns.stream().noneMatch(clause::includesColumn)
|
|
||||||
&& clause.getCondition().getNonEquiConditions().isEmpty()
|
&& clause.getCondition().getNonEquiConditions().isEmpty()
|
||||||
&& clause.getCondition().getEquiConditions().size() > 0) {
|
&& clause.getCondition().getEquiConditions().size() > 0) {
|
||||||
final List<Filter> filters = new ArrayList<>();
|
final List<Filter> filters = new ArrayList<>();
|
||||||
int numValues = maxNumFilterValues;
|
int numValues = maxNumFilterValues;
|
||||||
boolean joinClauseFullyConverted = true;
|
// if the right side columns are required, the clause cannot be fully converted
|
||||||
|
boolean joinClauseFullyConverted = requiredColumns.stream().noneMatch(clause::includesColumn);
|
||||||
|
|
||||||
for (final Equality condition : clause.getCondition().getEquiConditions()) {
|
for (final Equality condition : clause.getCondition().getEquiConditions()) {
|
||||||
final String leftColumn = condition.getLeftExpr().getBindingIfIdentifier();
|
final String leftColumn = condition.getLeftExpr().getBindingIfIdentifier();
|
||||||
|
|
|
@ -674,7 +674,7 @@ public class JoinableFactoryWrapperTest extends NullHandlingTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_convertJoinsToFilters_dontConvertWhenColumnIsUsed()
|
public void test_convertJoinsToFilters_partialConvertWhenColumnIsUsed()
|
||||||
{
|
{
|
||||||
final JoinableClause clause = new JoinableClause(
|
final JoinableClause clause = new JoinableClause(
|
||||||
"j.",
|
"j.",
|
||||||
|
@ -691,7 +691,7 @@ public class JoinableFactoryWrapperTest extends NullHandlingTest
|
||||||
|
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
Pair.of(
|
Pair.of(
|
||||||
ImmutableList.of(),
|
ImmutableList.of(new InDimFilter("x", TEST_LOOKUP_KEYS)),
|
||||||
ImmutableList.of(clause)
|
ImmutableList.of(clause)
|
||||||
),
|
),
|
||||||
conversion
|
conversion
|
||||||
|
@ -799,7 +799,7 @@ public class JoinableFactoryWrapperTest extends NullHandlingTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_convertJoinsToFilters_dontConvertJoinsDependedOnByLaterJoins()
|
public void test_convertJoinsToFilters_partialConvertJoinsDependedOnByLaterJoins()
|
||||||
{
|
{
|
||||||
final ImmutableList<JoinableClause> clauses = ImmutableList.of(
|
final ImmutableList<JoinableClause> clauses = ImmutableList.of(
|
||||||
new JoinableClause(
|
new JoinableClause(
|
||||||
|
@ -830,7 +830,7 @@ public class JoinableFactoryWrapperTest extends NullHandlingTest
|
||||||
|
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
Pair.of(
|
Pair.of(
|
||||||
ImmutableList.of(),
|
ImmutableList.of(new InDimFilter("x", TEST_LOOKUP_KEYS)),
|
||||||
clauses
|
clauses
|
||||||
),
|
),
|
||||||
conversion
|
conversion
|
||||||
|
@ -838,7 +838,7 @@ public class JoinableFactoryWrapperTest extends NullHandlingTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_convertJoinsToFilters_dontConvertJoinsDependedOnByLaterJoins2()
|
public void test_convertJoinsToFilters_partialConvertJoinsDependedOnByLaterJoins2()
|
||||||
{
|
{
|
||||||
final ImmutableList<JoinableClause> clauses = ImmutableList.of(
|
final ImmutableList<JoinableClause> clauses = ImmutableList.of(
|
||||||
new JoinableClause(
|
new JoinableClause(
|
||||||
|
@ -869,7 +869,7 @@ public class JoinableFactoryWrapperTest extends NullHandlingTest
|
||||||
|
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
Pair.of(
|
Pair.of(
|
||||||
ImmutableList.of(new InDimFilter("x", TEST_LOOKUP_KEYS)),
|
ImmutableList.of(new InDimFilter("x", TEST_LOOKUP_KEYS), new InDimFilter("x", TEST_LOOKUP_KEYS)),
|
||||||
clauses.subList(1, clauses.size())
|
clauses.subList(1, clauses.size())
|
||||||
),
|
),
|
||||||
conversion
|
conversion
|
||||||
|
|
Loading…
Reference in New Issue