Skip to content

Commit

Permalink
Do not push down nondeterministic predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
joyyao8 committed Feb 5, 2015
1 parent ba82073 commit c70fb33
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,26 @@ public PlanNode visitPlan(PlanNode node, RewriteContext<Expression> context)
@Override
public PlanNode visitProject(ProjectNode node, RewriteContext<Expression> context)
{
Expression inlinedPredicate = ExpressionTreeRewriter.rewriteWith(new ExpressionSymbolInliner(node.getAssignments()), context.get());
return context.defaultRewrite(node, inlinedPredicate);
Set<Symbol> deterministicSymbols = node.getAssignments().entrySet().stream()
.filter(entry -> DeterminismEvaluator.isDeterministic(entry.getValue()))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());

java.util.function.Predicate<Expression> deterministic = conjunct -> DependencyExtractor.extractAll(conjunct).stream()
.allMatch(deterministicSymbols::contains);

Map<Boolean, List<Expression>> conjuncts = extractConjuncts(context.get()).stream().collect(Collectors.partitioningBy(deterministic));

// Push down conjuncts from the inherited predicate that don't depend on non-deterministic assignments
PlanNode rewrittenNode = context.defaultRewrite(node,
ExpressionTreeRewriter.rewriteWith(new ExpressionSymbolInliner(node.getAssignments()), combineConjuncts(conjuncts.get(true))));

// All non-deterministic conjuncts, if any, will be in the filter node.
if (!conjuncts.get(false).isEmpty()) {
rewrittenNode = new FilterNode(idAllocator.getNextId(), rewrittenNode, combineConjuncts(conjuncts.get(false)));
}

return rewrittenNode;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ public void selectNull()
assertQuery("SELECT NULL", "SELECT NULL FROM (SELECT * FROM ORDERS LIMIT 1)");
}

@Test
public void testNonDeterministicFilter()
{
MaterializedResult materializedResult = computeActual("SELECT u FROM ( SELECT if(rand() > 0.5, 0, 1) AS u ) WHERE u <> u");
assertEquals(materializedResult.getRowCount(), 0);

materializedResult = computeActual("SELECT u, v FROM ( SELECT if(rand() > 0.5, 0, 1) AS u, 4*4 as v ) WHERE u <> u and v > 10");
assertEquals(materializedResult.getRowCount(), 0);

materializedResult = computeActual("SELECT u, v, w FROM ( SELECT if(rand() > 0.5, 0, 1) AS u, 4*4 as v, 'abc' as w ) WHERE v > 10");
assertEquals(materializedResult.getRowCount(), 1);
}

@Test
public void testVarbinary()
throws Exception
Expand Down

0 comments on commit c70fb33

Please sign in to comment.