def test_like(): # allow reduction result = optimize(parse("'This is a test' LIKE 'This is %' AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) result = optimize( parse("'This is a test' LIKE 'This is . test' AND attr = 1") ) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # don't reduction when an attribute is referenced result = optimize(parse("attr LIKE 'This is %'")) assert result == ast.Like( ast.Attribute('attr'), 'This is %', False, '%', '.', '\\', False )
def test_in(): # allow reduction when the left hand side and all options # are certain result = optimize(parse("1 IN (1, 2, 3) AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) result = optimize(parse("5 NOT IN (1, 2, 3) AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # don't allow reduction if either left hand side or either option # is uncertain result = optimize(parse("attr IN (1, 2, 3)")) assert result == ast.In( ast.Attribute('attr'), [1, 2, 3], False ) result = optimize(parse("1 IN (attr, 2, 3)")) assert result == ast.In( 1, [ast.Attribute('attr'), 2, 3], False )
def test_between(): # allow reduction result = optimize(parse("5 BETWEEN 1 AND 6 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) result = optimize(parse("10 NOT BETWEEN 1 AND 6 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # don't reduce if either lhs, low or high are uncertain result = optimize(parse("attr BETWEEN 1 AND 6")) assert result == ast.Between( ast.Attribute("attr"), 1, 6, False ) result = optimize(parse("5 BETWEEN attr AND 6")) assert result == ast.Between( 5, ast.Attribute("attr"), 6, False ) result = optimize(parse("5 BETWEEN 1 AND attr")) assert result == ast.Between( 5, 1, ast.Attribute("attr"), False )
def test_comparison(): # reduce less than result = optimize(parse("1 < 2 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # reduce greater than result = optimize(parse("2 > 1 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # reduce less or equal result = optimize(parse("1 <= 2 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # reduce greater or equal result = optimize(parse("2 >= 1 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 ) # reduce not equal result = optimize(parse("2 <> 1 AND attr = 1")) assert result == ast.Equal( ast.Attribute('attr'), 1 )
def test_null(data): result = filter_(parse('maybe_str_attr IS NULL'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0 result = filter_(parse('maybe_str_attr IS NOT NULL'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 1
def test_in(data): result = filter_(parse('int_attr IN ( 1, 2, 3, 4, 5 )'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0 result = filter_(parse('int_attr NOT IN ( 1, 2, 3, 4, 5 )'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 1
def test_combination(data): result = filter_(parse('int_attr = 5 AND float_attr < 6.0'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0 result = filter_(parse('int_attr = 5 AND float_attr < 6.0'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0
def test_between(data): result = filter_(parse('float_attr BETWEEN 4 AND 6'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0 result = filter_(parse('int_attr NOT BETWEEN 4 AND 6'), data) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 1
def test_arithmetic(data): result = filter_( parse('int_attr = float_attr - 0.5'), data, ) assert len(result) == 2 result = filter_( parse('int_attr = 5 + 20 / 2 - 10'), data, ) assert len(result) == 1 and result.index[0] == 0
def test_spatial(data): result = filter_( parse('INTERSECTS(point_attr, ENVELOPE (0 1 0 1))'), data, ) assert len(result) == 1 and result.index[0] == 0 result = filter_( parse('EQUALS(point_attr, POINT(2 2))'), data, ) assert len(result) == 1 and result.index[0] == 1
def test_arithmetic(data): result = filter_( parse('int_attr = float_attr - 0.5'), data, ) assert result.GetFeatureCount() == 2 result = filter_( parse('int_attr = 5 + 20 / 2 - 10'), data, ) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0
def test_spatial(data): result = filter_( parse('INTERSECTS(point_attr, ENVELOPE (0 1 0 1))'), data, ) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0 result = filter_( parse('EQUALS(point_attr, POINT(2 2))'), data, ) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 1
def test_arithmetic(): # test possible optimizations result = optimize(parse("attr = 10 + 10")) assert result == ast.Equal( ast.Attribute('attr'), 20 ) result = optimize(parse("attr = 30 - 10")) assert result == ast.Equal( ast.Attribute('attr'), 20 ) result = optimize(parse("attr = 10 * 2")) assert result == ast.Equal( ast.Attribute('attr'), 20 ) result = optimize(parse("attr = 40 / 2")) assert result == ast.Equal( ast.Attribute('attr'), 20 ) # test imppossible optimizations result = optimize(parse("attr = other + 10")) assert result == ast.Equal( ast.Attribute('attr'), ast.Add( ast.Attribute('other'), 10 ), ) result = optimize(parse("attr = other - 10")) assert result == ast.Equal( ast.Attribute('attr'), ast.Sub( ast.Attribute('other'), 10 ), ) result = optimize(parse("attr = other * 2")) assert result == ast.Equal( ast.Attribute('attr'), ast.Mul( ast.Attribute('other'), 2 ), ) result = optimize(parse("attr = other / 2")) assert result == ast.Equal( ast.Attribute('attr'), ast.Div( ast.Attribute('other'), 2 ), )
def test_disjoint_linestring_attr(): result = parse('DISJOINT(LINESTRING(1 1,2 2), geometry)') assert result == ast.GeometryDisjoint( values.Geometry( geometry.LineString([(1, 1), (2, 2)]).__geo_interface__, ), ast.Attribute('geometry'), )
def test_function(data): result = filter_( parse('sin(float_attr) BETWEEN -0.75 AND -0.70'), data, ) assert result.GetFeatureCount() == 1 and \ result.GetFeature(0).GetField(0) == 0
def test_contains_attr_polygon(): result = parse('CONTAINS(geometry, POLYGON((1 1,2 2,0 3,1 1)))') assert result == ast.GeometryContains( ast.Attribute('geometry'), values.Geometry( geometry.Polygon([(1, 1), (2, 2), (0, 3), (1, 1)]).__geo_interface__, ), )
def test_attribute_in_list(): result = parse('attr IN (1, 2, 3, 4)') assert result == ast.In(ast.Attribute('attr'), [ 1, 2, 3, 4, ], False)
def test_attribute_between_negative_positive(): result = parse('attr BETWEEN -1 AND 1') assert result == ast.Between( ast.Attribute('attr'), -1, 1, False, )
def test_function(): def myadder(a, b): return a + b result = optimize(parse("attr = myadder(1, 2)"), {"myadder": myadder}) assert result == ast.Equal( ast.Attribute('attr'), 3, ) # can't optimize a function referencing an attribute result = optimize(parse("attr = myadder(other, 2)"), {"myadder": myadder}) assert result == ast.Equal( ast.Attribute('attr'), ast.Function( "myadder", [ ast.Attribute("other"), 2 ] ) ) # can't optimize a function with a nested reference to an attribute result = optimize( parse("attr = myadder(other + 2, 2)"), {"myadder": myadder} ) assert result == ast.Equal( ast.Attribute('attr'), ast.Function( "myadder", [ ast.Add(ast.Attribute("other"), 2), 2 ] ) ) # can't optimize an unknown functions result = optimize(parse("attr = unkown(1, 2)"), {"myadder": myadder}) assert result == ast.Equal( ast.Attribute('attr'), ast.Function( "unkown", [ 1, 2, ] ) )
def evaluate(session, cql_expr, expected_ids): ast = parse(cql_expr) filters = to_filter(ast, FIELD_MAPPING) q = session.query(Record).join(RecordMeta).filter(filters) results = [row.identifier for row in q] assert expected_ids == type(expected_ids)(results)
def test_intersects_attr_point_ewkt(): result = parse('INTERSECTS(geometry, SRID=4326;POINT(1 1))') assert result.rhs.geometry['crs']['properties']['name'] == \ "urn:ogc:def:crs:EPSG::4326" assert result == ast.GeometryIntersects( ast.Attribute('geometry'), values.Geometry(geometry.Point(1, 1).__geo_interface__), )
def test_attribute_not_between(): result = parse('attr NOT BETWEEN 2 AND 5') assert result == ast.Between( ast.Attribute('attr'), 2, 5, True, )
def test_attribute_not_in_list(): result = parse('attr NOT IN (\'A\', \'B\', \'C\', \'D\')') assert result == ast.In(ast.Attribute('attr'), [ "A", "B", "C", "D", ], True)
def test_function_single_arg(): result = parse('attr = myfunc(1)') assert result == ast.Equal( ast.Attribute('attr'), ast.Function('myfunc', [ 1, ]), )
def test_attribute_between(): result = parse('attr BETWEEN 2 AND 5') assert result == ast.Between( ast.Attribute('attr'), 2, 5, False, )
def test_function_attr_string_arg(): result = parse('attr = myfunc(other_attr, \'abc\')') assert result == ast.Equal( ast.Attribute('attr'), ast.Function('myfunc', [ ast.Attribute('other_attr'), "abc", ]), )
def test_attribute_arithmetic_div(): result = parse('attr = 5 / 2') assert result == ast.Equal( ast.Attribute('attr'), ast.Div( 5, 2, ), )
def test_attribute_arithmetic_mul(): result = parse('attr = 5 * 2') assert result == ast.Equal( ast.Attribute('attr'), ast.Mul( 5, 2, ), )
def test_attribute_arithmetic_sub(): result = parse('attr = 5 - 2') assert result == ast.Equal( ast.Attribute('attr'), ast.Sub( 5, 2, ), )
def test_attribute_arithmetic_add(): result = parse('attr = 5 + 2') assert result == ast.Equal( ast.Attribute('attr'), ast.Add( 5, 2, ), )