public PropertyPattern<F, C, T> matching(Predicate<? super T> predicate) { return matching((t, context) -> predicate.test(t)); }
public PropertyPattern<F, T> matching(Predicate<? super T> predicate) { return matching(new FilterPattern<>(predicate, null)); } }
public PropertyPattern<F, C, T> matching(BiPredicate<? super T, ?> predicate) { return matching(new FilterPattern<>(predicate, Optional.empty())); } }
public static <F, C, T extends Iterable<S>, S> PropertyPattern<F, C, T> nonEmpty(Property<F, C, T> property) { return PropertyPattern.upcast(property.matching(not(Iterables::isEmpty))); }
public static <F, T extends Iterable<S>, S> PropertyPattern<F, T> nonEmpty(Property<F, T> property) { return PropertyPattern.upcast(property.matching(not(Iterables::isEmpty))); }
public PropertyPattern<F, C, T> equalTo(T expectedValue) { return matching(new EqualsPattern<>(expectedValue, Optional.empty())); }
public static <F, C, T extends Iterable<S>, S> PropertyPattern<F, C, T> empty(Property<F, C, T> property) { return PropertyPattern.upcast(property.matching(Iterables::isEmpty)); }
public static <F, T extends Iterable<S>, S> PropertyPattern<F, T> empty(Property<F, T> property) { return PropertyPattern.upcast(property.matching(Iterables::isEmpty)); }
public PropertyPattern<F, T> equalTo(T expectedValue) { return matching(new EqualsPattern<>(expectedValue, null)); }
public PropertyPattern<F, T> capturedAs(Capture<T> capture) { Pattern<T> matchAll = (Pattern<T>) Pattern.any(); return matching(matchAll.capturedAs(capture)); }
public PropertyPattern<F, C, T> capturedAs(Capture<T> capture) { Pattern<T> matchAll = (Pattern<T>) Pattern.any(); return matching(matchAll.capturedAs(capture)); }
protected ManipulateAdjacentWindowsOverProjects(int numProjects) { PropertyPattern<PlanNode, ?, ?> childPattern = source().matching(window().capturedAs(childCapture)); ImmutableList.Builder<Capture<ProjectNode>> projectCapturesBuilder = ImmutableList.builder(); for (int i = 0; i < numProjects; ++i) { Capture<ProjectNode> projectCapture = newCapture(); projectCapturesBuilder.add(projectCapture); childPattern = source().matching(project().capturedAs(projectCapture).with(childPattern)); } this.projectCaptures = projectCapturesBuilder.build(); this.pattern = window().with(childPattern); }
protected ManipulateAdjacentWindowsOverProjects(int numProjects) { PropertyPattern<PlanNode, ?> childPattern = source().matching(window().capturedAs(childCapture)); ImmutableList.Builder<Capture<ProjectNode>> projectCapturesBuilder = ImmutableList.builder(); for (int i = 0; i < numProjects; ++i) { Capture<ProjectNode> projectCapture = newCapture(); projectCapturesBuilder.add(projectCapture); childPattern = source().matching(project().capturedAs(projectCapture).with(childPattern)); } this.projectCaptures = projectCapturesBuilder.build(); this.pattern = window().with(childPattern); }
@Override public Pattern<ProjectNode> getPattern() { return project() .with(source().matching(targetPattern.capturedAs(targetCapture))); }
@Override public Pattern<ProjectNode> getPattern() { return project() .with(source().matching(targetPattern.capturedAs(targetCapture))); }
@Test public void optionalProperties() { Property<RelNode, RelNode> onlySource = Property.optionalProperty("onlySource", node -> Optional.of(node.getSources()) .filter(sources -> sources.size() == 1) .map((List<RelNode> sources) -> sources.get(0))); Pattern<RelNode> relNodeWithExactlyOneSource = plan() .with(onlySource.matching(any())); assertMatch(relNodeWithExactlyOneSource, new ProjectNode(new ScanNode("t"))); assertNoMatch(relNodeWithExactlyOneSource, new ScanNode("t")); assertNoMatch(relNodeWithExactlyOneSource, new JoinNode(new ScanNode("t"), new ScanNode("t"))); }
@Test public void propertyMatchers() { Pattern<String> aString = typeOf(String.class); Property<String, Integer> length = Property.property("length", String::length); String string = "a"; assertMatch(aString.with(length.equalTo(1)), string); assertMatch(project().with(source().matching(scan())), new ProjectNode(new ScanNode("T"))); assertMatch(aString.with(length.matching(any())), string); assertMatch(aString.with(length.matching(x -> x > 0)), string); assertMatch(aString.with(length.matching((Number x) -> x.intValue() > 0)), string); assertNoMatch(aString.with(length.equalTo(0)), string); assertNoMatch(project().with(source().matching(scan())), new ProjectNode(new ProjectNode(new ScanNode("T")))); assertNoMatch(aString.with(length.matching(typeOf(Void.class))), string); assertNoMatch(aString.with(length.matching(x -> x < 1)), string); assertNoMatch(aString.with(length.matching((Number x) -> x.intValue() < 1)), string); }
@Test public void capturingMatchesInATypesafeManner() { Capture<FilterNode> filter = newCapture(); Capture<ScanNode> scan = newCapture(); Capture<String> name = newCapture(); Pattern<ProjectNode> pattern = project() .with(source().matching(filter().capturedAs(filter) .with(source().matching(scan().capturedAs(scan) .with(tableName().capturedAs(name)))))); ProjectNode tree = new ProjectNode(new FilterNode(new ScanNode("orders"), null)); Match<ProjectNode> match = assertMatch(pattern, tree); //notice the concrete type despite no casts: FilterNode capturedFilter = match.capture(filter); assertEquals(tree.getSource(), capturedFilter); assertEquals(((FilterNode) tree.getSource()).getSource(), match.capture(scan)); assertEquals("orders", match.capture(name)); }
@Test public void matchNestedProperties() { Pattern<ProjectNode> pattern = project().with(source().matching(scan())); assertMatch(pattern, new ProjectNode(new ScanNode("t"))); assertNoMatch(pattern, new ScanNode("t")); //TODO this needs a custom Option type to work , or NPEs will happen. //Optional does not allow null values. //assertNoMatch(pattern, new ProjectNode(null)); assertNoMatch(pattern, new ProjectNode(new ProjectNode(null))); }