Commit 61b1a079 authored by Grégory Mantelet's avatar Grégory Mantelet
Browse files

[ADQL] Improve error report in case of incorrect argument for numeric functions.

parent bccfe162
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -133,7 +133,11 @@ public abstract class ADQLGrammarBase implements ADQLGrammar {
	@Override
	public final ParseException generateParseException(Exception ex) {
		if (!(ex instanceof ParseException)) {
			ParseException pex = new ParseException("[" + ex.getClass().getName() + "] " + ex.getMessage());
			ParseException pex;
			if (ex instanceof IllegalArgumentException)
				pex = new ParseException("Incorrect argument: " + ex.getMessage());
			else
				pex = new ParseException("[" + ex.getClass().getName() + "] " + ex.getMessage());
			pex.setStackTrace(ex.getStackTrace());
			return pex;
		} else
+10 −6
Original line number Diff line number Diff line
@@ -892,14 +892,16 @@ ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; Token left, right;
		| LOOKAHEAD(3) valueExpr=Factor()

		/* At this position in this switch, all possibilities (including
		 * Column()) have already been tested and failed.
		 * Column() and NumericFunction) have already been tested and failed.
		 * 
		 * So, this final choice actually aims to throw an error set with the
		 * So, these final choices actually aim to throw an error set with the
		 * current token and with an error message implying that a column name
		 * was expected (which is generally the case in an ADQL query).
		 *
		 * Note: This choice will generally be reached if an unexpected ADQL/SQL
		 *       word is ending the query. */
		 * was expected (which is generally the case in an ADQL query) or that
		 * the parameters of the numeric function are incorrect. */
		| LOOKAHEAD(2) valueExpr=NumericFunction()
		/*
		 * Note: Besides, this particular choice will generally be reached if an
		 *       unexpected ADQL/SQL word is ending the query. */
		| valueExpr=Column() )
		{return valueExpr;}
	}catch(Exception ex){
@@ -1003,6 +1005,8 @@ ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null;
		if (leftOp instanceof Concatenation){
			Concatenation concat = (Concatenation)leftOp;
			concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition()));
		}else if (leftOp instanceof ADQLColumn){
			((ADQLColumn)leftOp).setExpectedType('S');
		}
	  return leftOp;
	}
+26 −0
Original line number Diff line number Diff line
@@ -55,6 +55,32 @@ public class TestADQLParser {
	public void tearDown() throws Exception {
	}

	@Test
	public void testNumericFunctionParams() {

		ADQLParser parser = new ADQLParser(ADQLVersion.V2_1);

		/* CASE: LOWER can only take a string in parameter, but according to the
		 *       grammar (and BNF), an unsigned numeric is a string (??).
		 *       In such case, an error should be raised: */
		try {
			parser.parseQuery("SELECT LOWER(123) FROM foo");
			fail("LOWER can not take a numeric in parameter.");
		} catch(Exception ex) {
			assertEquals(ParseException.class, ex.getClass());
			assertEquals("Incorrect argument: The ADQL function LOWER must have one parameter of type VARCHAR (i.e. a String)!", ex.getMessage());
		}

		// CASE: Idem for a second parameter:
		try {
			parser.parseQuery("SELECT IN_UNIT(12.3, 123) FROM foo");
			fail("IN_UNIT can not take a numeric in 2nd parameter.");
		} catch(Exception ex) {
			assertEquals(ParseException.class, ex.getClass());
			assertEquals("Incorrect argument: The 2nd argument of the ADQL function IN_UNIT (i.e. target unit) must be of type VARCHAR (i.e. a string)!", ex.getMessage());
		}
	}

	@Test
	public void testOperatorsPrecedence() {