use of org.apache.druid.query.JoinDataSource in project druid by druid-io.
the class DataSourceAnalysisTest method testJoinSimpleRightLeaning.
@Test
public void testJoinSimpleRightLeaning() {
// Join of a table onto a variety of simple joinable objects (lookup, inline, subquery) with a right-leaning
// structure (no left children are joins themselves).
//
// Note that unlike the left-leaning stack, which is fully flattened, this one will not get flattened at all.
final JoinDataSource rightLeaningJoinStack = join(LOOKUP_LOOKYLOO, join(INLINE, subquery(LOOKUP_LOOKYLOO), "1.", JoinType.LEFT), "2.", JoinType.FULL);
final JoinDataSource joinDataSource = join(TABLE_FOO, rightLeaningJoinStack, "3.", JoinType.RIGHT);
final DataSourceAnalysis analysis = DataSourceAnalysis.forDataSource(joinDataSource);
Assert.assertTrue(analysis.isConcreteBased());
Assert.assertTrue(analysis.isConcreteTableBased());
Assert.assertFalse(analysis.isGlobal());
Assert.assertFalse(analysis.isQuery());
Assert.assertEquals(joinDataSource, analysis.getDataSource());
Assert.assertEquals(TABLE_FOO, analysis.getBaseDataSource());
Assert.assertEquals(Optional.of(TABLE_FOO), analysis.getBaseTableDataSource());
Assert.assertEquals(Optional.empty(), analysis.getJoinBaseTableFilter());
Assert.assertEquals(Optional.empty(), analysis.getBaseUnionDataSource());
Assert.assertEquals(Optional.empty(), analysis.getBaseQuery());
Assert.assertEquals(Optional.empty(), analysis.getBaseQuerySegmentSpec());
Assert.assertEquals(ImmutableList.of(new PreJoinableClause("3.", rightLeaningJoinStack, JoinType.RIGHT, joinClause("3."))), analysis.getPreJoinableClauses());
Assert.assertTrue(analysis.isJoin());
}
use of org.apache.druid.query.JoinDataSource in project druid by druid-io.
the class DruidQuery method getVirtualColumns.
private VirtualColumns getVirtualColumns(final boolean includeDimensions) {
// 'sourceRowSignature' could provide a list of all defined virtual columns while constructing a query, but we
// still want to collect the set of VirtualColumns this way to ensure we only add what is still being used after
// the various transforms and optimizations
Set<VirtualColumn> virtualColumns = new HashSet<>();
// rewrite any "specialized" virtual column expressions as top level virtual columns so that their native
// implementation can be used instead of being composed as part of some expression tree in an expresson virtual
// column
Set<String> specialized = new HashSet<>();
virtualColumnRegistry.visitAllSubExpressions((expression) -> {
switch(expression.getType()) {
case SPECIALIZED:
// add the expression to the top level of the registry as a standalone virtual column
final String name = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(expression, expression.getDruidType());
specialized.add(name);
// replace with an identifier expression of the new virtual column name
return DruidExpression.ofColumn(expression.getDruidType(), name);
default:
// do nothing
return expression;
}
});
// we always want to add any virtual columns used by the query level DimFilter
if (filter != null) {
for (String columnName : filter.getRequiredColumns()) {
if (virtualColumnRegistry.isVirtualColumnDefined(columnName)) {
virtualColumns.add(virtualColumnRegistry.getVirtualColumn(columnName));
}
}
}
if (selectProjection != null) {
for (String columnName : selectProjection.getVirtualColumns()) {
if (virtualColumnRegistry.isVirtualColumnDefined(columnName)) {
virtualColumns.add(virtualColumnRegistry.getVirtualColumn(columnName));
}
}
}
if (grouping != null) {
if (includeDimensions) {
for (DimensionExpression expression : grouping.getDimensions()) {
if (virtualColumnRegistry.isVirtualColumnDefined(expression.getVirtualColumn())) {
virtualColumns.add(virtualColumnRegistry.getVirtualColumn(expression.getVirtualColumn()));
}
}
}
for (Aggregation aggregation : grouping.getAggregations()) {
virtualColumns.addAll(virtualColumnRegistry.getAllVirtualColumns(aggregation.getRequiredColumns()));
}
}
if (sorting != null && sorting.getProjection() != null && grouping == null) {
for (String columnName : sorting.getProjection().getVirtualColumns()) {
if (virtualColumnRegistry.isVirtualColumnDefined(columnName)) {
virtualColumns.add(virtualColumnRegistry.getVirtualColumn(columnName));
}
}
}
if (dataSource instanceof JoinDataSource) {
for (String expression : ((JoinDataSource) dataSource).getVirtualColumnCandidates()) {
if (virtualColumnRegistry.isVirtualColumnDefined(expression)) {
virtualColumns.add(virtualColumnRegistry.getVirtualColumn(expression));
}
}
}
for (String columnName : specialized) {
if (virtualColumnRegistry.isVirtualColumnDefined(columnName)) {
virtualColumns.add(virtualColumnRegistry.getVirtualColumn(columnName));
}
}
// sort for predictable output
List<VirtualColumn> columns = new ArrayList<>(virtualColumns);
columns.sort(Comparator.comparing(VirtualColumn::getOutputName));
return VirtualColumns.create(columns);
}
Aggregations