Commit 9f845f0b authored by Grégory Mantelet's avatar Grégory Mantelet
Browse files

[ADQL] Support DISTANCE also with 4 parameters (i.e. lon1, lat1, lon2, lat2).

parent 046ac691
Loading
Loading
Loading
Loading
+62 −26
Original line number Diff line number Diff line
@@ -1181,7 +1181,7 @@ ADQLOperand[] Coordinates(): {ADQLOperand[] ops = new ADQLOperand[2];} {
	{return ops;}
}

GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<GeometryFunction> gvf1, gvf2; GeometryValue<PointFunction> gvp1, gvp2; GeometryFunction gf = null; PointFunction p1=null, p2=null; ADQLColumn col1 = null, col2 = null;} {
GeometryFunction GeometryFunction(): {Token fct=null, end=null; GeometryValue<GeometryFunction> gvf1, gvf2; GeometryValue<PointFunction> gvp1, gvp2; GeometryFunction gf = null; PointFunction p1=null, p2=null; ADQLColumn col1 = null, col2 = null;} {
	try{
		// predicate_geometry_function
		(
@@ -1196,8 +1196,47 @@ GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<Geometr
		|	(fct=<AREA> <LEFT_PAR> gvf1=GeometryExpression() end=<RIGHT_PAR>) {gf = queryFactory.createArea(gvf1);}
		|	(fct=<COORD1> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord1(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord1(col1);}) end=<RIGHT_PAR>)
		|	(fct=<COORD2> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord2(col1);}) end=<RIGHT_PAR>)
		|	(fct=<DISTANCE>
				<LEFT_PAR>
		|	(gf=DistanceFunction())
		)
	}catch(Exception ex){
		throw generateParseException(ex);
	}
	
	{
	  if (fct != null)
	  	gf.setPosition(new TextPosition(fct, end));
	  return gf;
	}
}

DistanceFunction DistanceFunction(): { Token fct=null, end=null; DistanceFunction gf; ADQLOperand lon, lat; GeometryValue<PointFunction> gvp1, gvp2; } {
	try {
		// DISTANCE(POINT,POINT)
		(LOOKAHEAD(DistanceFunction2())
			gf=DistanceFunction2()
		|
		// DISTANCE(lon1, lat1, lon2, lat2)
			fct=<DISTANCE> <LEFT_PAR>
			lon=NumericExpression() <COMMA> lat=NumericExpression() 
			{ gvp1 = new GeometryValue<PointFunction>(queryFactory.createPoint(null, lon, lat)); }
			<COMMA>
			lon=NumericExpression() <COMMA> lat=NumericExpression() 
			{ gvp2 = new GeometryValue<PointFunction>(queryFactory.createPoint(null, lon, lat)); } 
			end=<RIGHT_PAR>
			{
				gf = queryFactory.createDistance(gvp1, gvp2);
				gf.setPosition(new TextPosition(fct, end));
			}
		)
		{ return gf; }
	}catch(Exception ex){
		throw generateParseException(ex);
	}
}

DistanceFunction DistanceFunction2(): { Token fct=null, end=null; DistanceFunction gf; GeometryValue<PointFunction> gvp1, gvp2; PointFunction p1=null, p2=null; ADQLColumn col1=null, col2=null; } {
	try {
		fct=<DISTANCE> <LEFT_PAR>
		(p1=Point()|col1=Column()) 
		{
			if (p1 != null)
@@ -1218,16 +1257,13 @@ GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<Geometr
			}
		} 
		end=<RIGHT_PAR>
				{gf = queryFactory.createDistance(gvp1, gvp2);}
			)
		)
	}catch(Exception ex){
		throw generateParseException(ex);
	}
	
		{
			gf = queryFactory.createDistance(gvp1, gvp2);
			gf.setPosition(new TextPosition(fct, end));
	  return gf;
		}
		{ return gf; }
	}catch(Exception ex){
		throw generateParseException(ex);
	}
}

+32 −0
Original line number Diff line number Diff line
@@ -735,4 +735,36 @@ public class TestADQLParser {
		}
	}

	@Test
	public void testDistance() {
		// CASE: In ADQL-2.0, DISTANCE(POINT, POINT) is allowed:
		ADQLParser parser = new ADQLParser(ADQLVersion.V2_0);
		try {
			assertEquals("DISTANCE(POINT('', ra, dec), POINT('', ra2, dec2))", parser.parseSelect("SELECT DISTANCE(POINT('', ra, dec), POINT('', ra2, dec2))").get(0).toADQL());
		} catch(Exception ex) {
			ex.printStackTrace();
			fail("Unexpected error! All ADQL expressions were composed of correct tokens. (see console for more details)");
		}

		// CASE: ...BUT not DISTANCE(lon1, lat1, lon2, lat2)
		try {
			parser.parseSelect("SELECT DISTANCE(ra, dec, ra2, dec2)");
			fail("In ADQL-2.0, DISTANCE(lon1, lat1, lon2, lat2) should not be allowed!");
		} catch(Exception ex) {
			assertEquals(ParseException.class, ex.getClass());
			assertEquals(" Encountered \",\". Was expecting one of: \")\" \".\" \".\" \")\" ", ex.getMessage());
		}

		/* CASE: In ADQL-2.1 (and more), DISTANCE(POINT, POINT) and
		 *       DISTANCE(lon1, lat1, lon2, lat2) are both allowed: */
		parser = new ADQLParser(ADQLVersion.V2_1);
		try {
			assertEquals("DISTANCE(POINT('', ra, dec), POINT('', ra2, dec2))", parser.parseSelect("SELECT DISTANCE(POINT('', ra, dec), POINT('', ra2, dec2))").get(0).toADQL());
			assertEquals("DISTANCE(POINT('', ra, dec), POINT('', ra2, dec2))", parser.parseSelect("SELECT DISTANCE(ra, dec, ra2, dec2)").get(0).toADQL());
		} catch(Exception ex) {
			ex.printStackTrace();
			fail("Unexpected error! All ADQL expressions were composed of correct tokens. (see console for more details)");
		}
	}

}