use of org.apache.druid.segment.join.JoinConditionAnalysis in project druid by druid-io.
the class JoinFilterCorrelations method findCorrelatedBaseTableColumns.
/**
* For each rhs column that appears in the equiconditions for a table's JoinableClause,
* we try to determine what base table columns are related to the rhs column through the total set of equiconditions.
* We do this by searching backwards through the chain of join equiconditions using the provided equicondition map.
* <p>
* For example, suppose we have 3 tables, A,B,C, joined with the following conditions, where A is the base table:
* A.joinColumn == B.joinColumn
* B.joinColum == C.joinColumnenableRewriteValueColumnFilters
* <p>
* We would determine that C.joinColumn is correlated with A.joinColumn: we first see that
* C.joinColumn is linked to B.joinColumn which in turn is linked to A.joinColumn
* <p>
* Suppose we had the following join conditions instead:
* f(A.joinColumn) == B.joinColumn
* B.joinColum == C.joinColumn
* In this case, the JoinFilterColumnCorrelationAnalysis for C.joinColumn would be linked to f(A.joinColumn).
* <p>
* Suppose we had the following join conditions instead:
* A.joinColumn == B.joinColumn
* f(B.joinColum) == C.joinColumn
* <p>
* Because we cannot reverse the function f() applied to the second table B in all cases,
* we cannot relate C.joinColumn to A.joinColumn, and we would not generate a correlation for C.joinColumn
*
* @param joinableClauses List of joinable clauses for the query
* @param tablePrefix Prefix for a join table
* @param rhsRewriteCandidate RHS rewrite candidate that we find correlated base table columns for
* @param equiConditions Map of equiconditions, keyed by the right hand columns
* @return A list of correlatation analyses for the equicondition RHS columns that reside in the table associated with
* the tablePrefix
*/
private static Optional<Map<String, JoinFilterColumnCorrelationAnalysis>> findCorrelatedBaseTableColumns(JoinableClauses joinableClauses, String tablePrefix, RhsRewriteCandidate rhsRewriteCandidate, Equiconditions equiConditions) {
JoinableClause clauseForTablePrefix = rhsRewriteCandidate.getJoinableClause();
JoinConditionAnalysis jca = clauseForTablePrefix.getCondition();
Set<String> rhsColumns = new HashSet<>();
if (rhsRewriteCandidate.isDirectRewrite()) {
// If we filter on a RHS join column, we only need to consider that column from the RHS side
rhsColumns.add(rhsRewriteCandidate.getRhsColumn());
} else {
for (Equality eq : jca.getEquiConditions()) {
rhsColumns.add(tablePrefix + eq.getRightColumn());
}
}
Map<String, JoinFilterColumnCorrelationAnalysis> correlations = new LinkedHashMap<>();
for (String rhsColumn : rhsColumns) {
Set<String> correlatedBaseColumns = new HashSet<>();
Set<Expr> correlatedBaseExpressions = new HashSet<>();
getCorrelationForRHSColumn(joinableClauses, equiConditions, rhsColumn, correlatedBaseColumns, correlatedBaseExpressions);
if (correlatedBaseColumns.isEmpty() && correlatedBaseExpressions.isEmpty()) {
continue;
}
correlations.put(rhsColumn, new JoinFilterColumnCorrelationAnalysis(rhsColumn, correlatedBaseColumns, correlatedBaseExpressions));
}
if (correlations.size() == 0) {
return Optional.empty();
} else {
return Optional.of(correlations);
}
}
use of org.apache.druid.segment.join.JoinConditionAnalysis in project druid by druid-io.
the class DruidSchemaTestCommon method setUpCommon.
@Before
public void setUpCommon() {
segmentDataSourceNames = Sets.newConcurrentHashSet();
joinableDataSourceNames = Sets.newConcurrentHashSet();
segmentManager = new SegmentManager(EasyMock.createMock(SegmentLoader.class)) {
@Override
public Set<String> getDataSourceNames() {
getDatasourcesLatch.countDown();
return segmentDataSourceNames;
}
};
globalTableJoinable = new JoinableFactory() {
@Override
public boolean isDirectlyJoinable(DataSource dataSource) {
return dataSource instanceof GlobalTableDataSource && joinableDataSourceNames.contains(((GlobalTableDataSource) dataSource).getName());
}
@Override
public Optional<Joinable> build(DataSource dataSource, JoinConditionAnalysis condition) {
return Optional.empty();
}
};
}
Aggregations