use of org.apache.druid.math.expr.Expr in project druid by druid-io.
the class JoinFilterAnalyzer method splitFilter.
/**
* @param joinFilterPreAnalysis The pre-analysis computed by {@link #computeJoinFilterPreAnalysis)}
* @param baseFilter - Filter on base table that was specified in the query itself
*
* @return A JoinFilterSplit indicating what parts of the filter should be applied pre-join and post-join
*/
public static JoinFilterSplit splitFilter(JoinFilterPreAnalysis joinFilterPreAnalysis, @Nullable Filter baseFilter) {
if (joinFilterPreAnalysis.getOriginalFilter() == null || !joinFilterPreAnalysis.isEnableFilterPushDown()) {
return new JoinFilterSplit(baseFilter, joinFilterPreAnalysis.getOriginalFilter(), ImmutableSet.of());
}
// Pushdown filters, rewriting if necessary
List<Filter> leftFilters = new ArrayList<>();
List<Filter> rightFilters = new ArrayList<>();
Map<Expr, VirtualColumn> pushDownVirtualColumnsForLhsExprs = new HashMap<>();
if (null != baseFilter) {
leftFilters.add(baseFilter);
}
for (Filter baseTableFilter : joinFilterPreAnalysis.getNormalizedBaseTableClauses()) {
if (!Filters.filterMatchesNull(baseTableFilter)) {
leftFilters.add(baseTableFilter);
} else {
rightFilters.add(baseTableFilter);
}
}
for (Filter orClause : joinFilterPreAnalysis.getNormalizedJoinTableClauses()) {
JoinFilterAnalysis joinFilterAnalysis = analyzeJoinFilterClause(orClause, joinFilterPreAnalysis, pushDownVirtualColumnsForLhsExprs);
if (joinFilterAnalysis.isCanPushDown()) {
// noinspection OptionalGetWithoutIsPresent isCanPushDown checks isPresent
leftFilters.add(joinFilterAnalysis.getPushDownFilter().get());
}
if (joinFilterAnalysis.isRetainAfterJoin()) {
rightFilters.add(joinFilterAnalysis.getOriginalFilter());
}
}
return new JoinFilterSplit(Filters.maybeAnd(leftFilters).orElse(null), Filters.maybeAnd(rightFilters).orElse(null), new HashSet<>(pushDownVirtualColumnsForLhsExprs.values()));
}
use of org.apache.druid.math.expr.Expr in project druid by druid-io.
the class JoinFilterAnalyzer method rewriteFilterDirect.
private static JoinFilterAnalysis rewriteFilterDirect(Filter filterClause, JoinFilterPreAnalysis joinFilterPreAnalysis, Map<Expr, VirtualColumn> pushDownVirtualColumnsForLhsExprs) {
if (!filterClause.supportsRequiredColumnRewrite()) {
return JoinFilterAnalysis.createNoPushdownFilterAnalysis(filterClause);
}
List<Filter> newFilters = new ArrayList<>();
// we only support direct rewrites of filters that reference a single column
String reqColumn = filterClause.getRequiredColumns().iterator().next();
List<JoinFilterColumnCorrelationAnalysis> correlationAnalyses = joinFilterPreAnalysis.getCorrelationsByDirectFilteringColumn().get(reqColumn);
if (correlationAnalyses == null) {
return JoinFilterAnalysis.createNoPushdownFilterAnalysis(filterClause);
}
for (JoinFilterColumnCorrelationAnalysis correlationAnalysis : correlationAnalyses) {
if (correlationAnalysis.supportsPushDown()) {
for (String correlatedBaseColumn : correlationAnalysis.getBaseColumns()) {
Filter rewrittenFilter = filterClause.rewriteRequiredColumns(ImmutableMap.of(reqColumn, correlatedBaseColumn));
newFilters.add(rewrittenFilter);
}
for (Expr correlatedBaseExpr : correlationAnalysis.getBaseExpressions()) {
// We need to create a virtual column for the expressions when pushing down
VirtualColumn pushDownVirtualColumn = pushDownVirtualColumnsForLhsExprs.computeIfAbsent(correlatedBaseExpr, (expr) -> {
String vcName = getCorrelatedBaseExprVirtualColumnName(pushDownVirtualColumnsForLhsExprs.size());
return new ExpressionVirtualColumn(vcName, correlatedBaseExpr, ColumnType.STRING);
});
Filter rewrittenFilter = filterClause.rewriteRequiredColumns(ImmutableMap.of(reqColumn, pushDownVirtualColumn.getOutputName()));
newFilters.add(rewrittenFilter);
}
}
}
if (newFilters.isEmpty()) {
return JoinFilterAnalysis.createNoPushdownFilterAnalysis(filterClause);
}
return new JoinFilterAnalysis(false, filterClause, Filters.maybeAnd(newFilters).orElse(null));
}
use of org.apache.druid.math.expr.Expr in project druid by druid-io.
the class ExprMacroTest method assertExpr.
private void assertExpr(final String expression, final Object expectedResult) {
final Expr expr = Parser.parse(expression, TestExprMacroTable.INSTANCE);
Assert.assertEquals(expression, expectedResult, expr.eval(BINDINGS).value());
final Expr exprNotFlattened = Parser.parse(expression, TestExprMacroTable.INSTANCE, false);
final Expr roundTripNotFlattened = Parser.parse(exprNotFlattened.stringify(), TestExprMacroTable.INSTANCE);
Assert.assertEquals(exprNotFlattened.stringify(), expectedResult, roundTripNotFlattened.eval(BINDINGS).value());
final Expr roundTrip = Parser.parse(expr.stringify(), TestExprMacroTable.INSTANCE);
Assert.assertEquals(exprNotFlattened.stringify(), expectedResult, roundTrip.eval(BINDINGS).value());
}
use of org.apache.druid.math.expr.Expr in project druid by druid-io.
the class IPv4AddressParseExprMacroTest method testInvalidStringArgIPv6Compatible.
@Test
public void testInvalidStringArgIPv6Compatible() {
Expr ipv6Compatible = ExprEval.of("::192.168.0.1").toExpr();
Assert.assertEquals(NULL, eval(ipv6Compatible));
}
use of org.apache.druid.math.expr.Expr in project druid by druid-io.
the class IPv4AddressParseExprMacroTest method testInvalidLongArgTooLow.
@Test
public void testInvalidLongArgTooLow() {
Expr tooLow = ExprEval.ofLong(-1L).toExpr();
Assert.assertEquals(NULL, eval(tooLow));
}
Aggregations