public Object visit(PropertyIsNotEqualTo filter, Object extraData) { return guardAgainstNulls((BinaryComparisonOperator) super.visit(filter, extraData)); }
Filter[] splitFilter(Filter original, FeatureSource source) { JDBCFeatureSource featureSource = null; if (source instanceof JDBCFeatureSource) { featureSource = (JDBCFeatureSource) source; } else { featureSource = ((JDBCFeatureStore) source).getFeatureSource(); } Filter[] split = new Filter[2]; if (original != null) { split = getDataStore().getSQLDialect().splitFilter(original, featureSource.getSchema()); } // handle three-valued logic differences by adding "is not null" checks in the filter, // the simplifying filter visitor will take care of them if they are redundant NullHandlingVisitor nhv = new NullHandlingVisitor(source.getSchema()); split[0] = (Filter) split[0].accept(nhv, null); SimplifyingFilterVisitor visitor = new SimplifyingFilterVisitor(); visitor.setFIDValidator(new PrimaryKeyFIDValidator(featureSource)); visitor.setFeatureType(getSchema()); split[0] = (Filter) split[0].accept(visitor, null); split[1] = (Filter) split[1].accept(visitor, null); return split; }
/** * Guards the filter against potential null values in the target property name (if it is a * property name, to start with) */ private Filter guardAgainstNulls(Filter filter, Expression potentialPropertyName) { if (potentialPropertyName instanceof PropertyName) { PropertyName pn = (PropertyName) potentialPropertyName; String name = pn.getPropertyName(); if (isNillable(name)) { Not notNull = ff.not(ff.isNull(ff.property(name))); if (filter instanceof And) { And and = (And) filter; List<Filter> children = new ArrayList<Filter>(and.getChildren()); children.add(notNull); return ff.and(children); } else { return ff.and(filter, notNull); } } } return filter; }
@Test public void testLike() { PropertyIsLike like = ff.like(ff.property("a"), "*A*"); NullHandlingVisitor visitor = new NullHandlingVisitor(); Filter result = (Filter) like.accept(visitor, null); assertTrue(result instanceof And); Filter expected = ff.and(like, propertyNotNull("a")); assertEquals(expected, result); like = ff.like(ff.literal("a"), "*A*"); result = (Filter) like.accept(visitor, null); assertEquals(like, result); }
@Test public void testSimplifyRedundant() { PropertyIsBetween between = ff.between(ff.property("a"), ff.property("b"), ff.property("c")); PropertyIsEqualTo equal = ff.equal(ff.property("a"), ff.property("b"), false); And and = ff.and(between, equal); NullHandlingVisitor nh = new NullHandlingVisitor(); Filter nhResult = (Filter) and.accept(nh, null); SimplifyingFilterVisitor simplifier = new SimplifyingFilterVisitor(); Filter simplified = (Filter) nhResult.accept(simplifier, null); assertTrue(simplified instanceof And); Filter expected = ff.and( Arrays.asList( between, equal, propertyNotNull("a"), propertyNotNull("b"), propertyNotNull("c"))); assertEquals(expected, simplified); }
private Object guardAgainstNulls(BinaryComparisonOperator clone) { Filter result = guardAgainstNulls(clone, clone.getExpression1()); result = guardAgainstNulls(result, clone.getExpression2()); return result; }
@Test public void testBinaryComparison() { PropertyIsEqualTo equal = ff.equal(ff.property("a"), ff.property("b"), false); NullHandlingVisitor visitor = new NullHandlingVisitor(); Filter result = (Filter) equal.accept(visitor, null); assertTrue(result instanceof And); Filter expected = ff.and(Arrays.asList(equal, propertyNotNull("a"), propertyNotNull("b"))); assertEquals(expected, result); equal = ff.equal(ff.property("a"), ff.literal(10), false); result = (Filter) equal.accept(visitor, null); assertTrue(result instanceof And); expected = ff.and(Arrays.asList(equal, propertyNotNull("a"))); assertEquals(expected, result); equal = ff.equal(ff.literal(10), ff.property("b"), false); result = (Filter) equal.accept(visitor, null); assertTrue(result instanceof And); expected = ff.and(Arrays.asList(equal, propertyNotNull("b"))); assertEquals(expected, result); equal = ff.equal(ff.literal(10), ff.literal(20), false); result = (Filter) equal.accept(visitor, null); assertEquals(equal, result); }
public Object visit(PropertyIsEqualTo filter, Object extraData) { return guardAgainstNulls((BinaryComparisonOperator) super.visit(filter, extraData)); }
@Test public void testNullableAttributes() { SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); tb.nillable(true); tb.add("a", String.class); tb.nillable(false); tb.add("b", String.class); tb.nillable(true); tb.add("c", String.class); tb.setName("test"); SimpleFeatureType schema = tb.buildFeatureType(); PropertyIsBetween between = ff.between(ff.property("a"), ff.property("b"), ff.property("c")); NullHandlingVisitor visitor = new NullHandlingVisitor(schema); Filter result = (Filter) between.accept(visitor, null); assertTrue(result instanceof And); Filter expected = ff.and(Arrays.asList(between, propertyNotNull("a"), propertyNotNull("c"))); assertEquals(expected, result); }
public Object visit(PropertyIsLessThan filter, Object extraData) { return guardAgainstNulls((BinaryComparisonOperator) super.visit(filter, extraData)); }
@Test public void testBetween() { PropertyIsBetween between = ff.between(ff.property("a"), ff.property("b"), ff.property("c")); NullHandlingVisitor visitor = new NullHandlingVisitor(); Filter result = (Filter) between.accept(visitor, null); assertTrue(result instanceof And); Filter expected = ff.and( Arrays.asList( between, propertyNotNull("a"), propertyNotNull("b"), propertyNotNull("c"))); assertEquals(expected, result); between = ff.between(ff.property("a"), ff.property("b"), ff.literal(10)); result = (Filter) between.accept(visitor, null); assertTrue(result instanceof And); expected = ff.and(Arrays.asList(between, propertyNotNull("a"), propertyNotNull("b"))); assertEquals(expected, result); between = ff.between(ff.property("a"), ff.literal(5), ff.literal(10)); result = (Filter) between.accept(visitor, null); assertTrue(result instanceof And); expected = ff.and(Arrays.asList(between, propertyNotNull("a"))); assertEquals(expected, result); between = ff.between(ff.literal(7), ff.literal(5), ff.literal(10)); result = (Filter) between.accept(visitor, null); assertEquals(between, result); }
public Object visit(PropertyIsLessThanOrEqualTo filter, Object extraData) { return guardAgainstNulls((BinaryComparisonOperator) super.visit(filter, extraData)); }
public Object visit(PropertyIsGreaterThan filter, Object extraData) { return guardAgainstNulls((BinaryComparisonOperator) super.visit(filter, extraData)); }
public Object visit(PropertyIsGreaterThanOrEqualTo filter, Object extraData) { return guardAgainstNulls((BinaryComparisonOperator) super.visit(filter, extraData)); }
public Object visit(PropertyIsBetween filter, Object extraData) { PropertyIsBetween clone = (PropertyIsBetween) super.visit(filter, extraData); Filter f = guardAgainstNulls(clone, clone.getExpression()); f = guardAgainstNulls(f, clone.getLowerBoundary()); f = guardAgainstNulls(f, clone.getUpperBoundary()); return f; }
@Override public Object visit(PropertyIsLike filter, Object extraData) { PropertyIsLike clone = (PropertyIsLike) super.visit(filter, extraData); return guardAgainstNulls(filter, clone.getExpression()); }