Commit c85a8b7c authored by gmantele's avatar gmantele
Browse files

ADQL: Fix 2 bugs:

1/ let the function ROUND having 2 parameters
2/ wrap Operations (WrappedOperand) with brackets when there are brackets in the ADQL query
parent b9c7b197
Loading
Loading
Loading
Loading
+410 −429

File changed.

Preview size limit exceeded, changes collapsed.

+16 −16
Original line number Diff line number Diff line
@@ -1012,20 +1012,20 @@ String SignedInteger(): {Token sign=null, number;} {
/* EXPRESSIONS */
/* *********** */
ADQLOperand ValueExpressionPrimary(): {String expr; ADQLColumn column; ADQLOperand op;} {
	(
	try{
	// unsigned_value_specification
		(// unsigned_value_specification
		  expr=UnsignedNumeric() {return queryFactory.createNumericConstant(expr);}
		// string
		| expr=String() {return queryFactory.createStringConstant(expr);}
		}catch(Exception ex){
			throw generateParseException(ex);
		}
		// column_reference
		| column=Column() {return column;}
		// set_function_specification
		| op=SqlFunction() {return op;}
		// LEFT_PAR value_expression RIGHT_PAR
	| (<LEFT_PAR> op=ValueExpression() <RIGHT_PAR>) {return op;})
		| (<LEFT_PAR> op=ValueExpression() <RIGHT_PAR>) {return queryFactory.createWrappedOperand(op);})
	}catch(Exception ex){
		throw generateParseException(ex);
	}
}

ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; } {
@@ -1414,9 +1414,9 @@ MathFunction MathFunction(): {Token fct=null; ADQLOperand param1=null, param2=nu
		| (fct=<POWER> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() <RIGHT_PAR>)
		| (fct=<RADIANS> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
		| (fct=<RAND> <LEFT_PAR> (param1=NumericExpression())? <RIGHT_PAR>)
		| (fct=<ROUND> <LEFT_PAR> param1=NumericExpression() (<COMMA> integerValue=SignedInteger() {param2 = queryFactory.createOperation(queryFactory.createNumericConstant(integerValue), null, null);})? <RIGHT_PAR>)
		| (fct=<ROUND> <LEFT_PAR> param1=NumericExpression() (<COMMA> integerValue=SignedInteger() {param2 = queryFactory.createNumericConstant(integerValue);})? <RIGHT_PAR>)
		| (fct=<SQRT> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
		| (fct=<TRUNCATE> <LEFT_PAR> param1=NumericExpression() (<COMMA> integerValue=SignedInteger() {param2 = queryFactory.createOperation(queryFactory.createNumericConstant(integerValue), null, null);})? <RIGHT_PAR>))
		| (fct=<TRUNCATE> <LEFT_PAR> param1=NumericExpression() (<COMMA> integerValue=SignedInteger() {param2 = queryFactory.createNumericConstant(integerValue);})? <RIGHT_PAR>))
		{
			if (param1 != null)
				return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+43 −28
Original line number Diff line number Diff line
@@ -16,18 +16,18 @@ package adql.query.operand.function;
 * You should have received a copy of the GNU Lesser General Public License
 * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
 * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institute (ARI)
 */

import adql.query.ADQLObject;

import adql.query.operand.ADQLOperand;

/**
 * It represents any basic mathematical function.
 * 
 * @author Gr&eacute;gory Mantelet (CDS)
 * @version 06/2011
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 1.2 (03/2014)
 * 
 * @see MathFunctionType
 */
@@ -42,6 +42,10 @@ public class MathFunction extends ADQLFunction {
	/** Second parameter of this function (may be null). */
	private ADQLOperand param2 = null;

	/** Number of given parameters.
	 * @since 1.2*/
	private int nbParams;

	/**
	 * Creates a mathematical function without parameter.
	 * 
@@ -75,23 +79,29 @@ public class MathFunction extends ADQLFunction {
	 * @throws Exception	If the given function parameters are incorrect.
	 */
	public MathFunction(MathFunctionType t, ADQLOperand parameter1, ADQLOperand parameter2) throws Exception{
		// Set the function type:
		type = t;
		switch(type.nbParams()){
		// Only two parameters can be managed inside this class.
		if (type.nbMaxParams() > 2)
			throw new Exception("Impossible for MathFunction object to have " + type.nbMaxParams() + " ! It is limited to 2 parameters !");
		// Compute the number of given parameters:
		nbParams = ((parameter1 != null) ? 1 : 0) + ((parameter2 != null) ? 1 : 0);
		// Check it and throw immediately an exception if incorrect:
		if (nbParams < type.nbMinParams() || nbParams > type.nbMaxParams()){
			if (type.nbMinParams() == type.nbMaxParams())
				throw new Exception("The function " + type.name() + " must have " + ((type.nbMaxParams() == 0) ? "no parameter!" : ("exactly " + type.nbMaxParams() + " parameters!")));
			else{
				switch(type.nbMaxParams()){
					case 0:
				if (parameter1 != null || parameter2 != null)
						throw new Exception("The function " + type.name() + " must have no parameter !");
				break;
					case 1:
				if (parameter1 == null || parameter2 != null)
						throw new Exception("The function " + type.name() + " must have only one parameter !");
				break;
					case 2:
				if (parameter1 == null || parameter2 == null)
						throw new Exception("The function " + type.name() + " must have two parameters !");
				break;
			default:
				throw new Exception("Impossible for MathFunction object to have " + type.nbParams() + " ! It is limited to 2 parameters !");
				}
			}
		}
		// Set the function parameters:
		param1 = parameter1;
		param2 = parameter2;
	}
@@ -119,42 +129,47 @@ public class MathFunction extends ADQLFunction {
		return type;
	}

	@Override
	public ADQLObject getCopy() throws Exception{
		return new MathFunction(this);
	}

	@Override
	public String getName(){
		return type.name();
	}

	@Override
	public final boolean isNumeric(){
		return true;
	}

	@Override
	public final boolean isString(){
		return false;
	}

	@Override
	public ADQLOperand[] getParameters(){
		if (param1 != null){
			if (param2 != null)
				return new ADQLOperand[]{param1,param2};
			else
		switch(getNbParameters()){
			case 1:
				return new ADQLOperand[]{param1};
		}else
			case 2:
				return new ADQLOperand[]{param1,param2};
			default:
				return new ADQLOperand[0];
		}
	}

	@Override
	public int getNbParameters(){
		return type.nbParams();
		return nbParams;
	}

	@Override
	public ADQLOperand getParameter(int index) throws ArrayIndexOutOfBoundsException{
		if (index < 0 || index >= getNbParameters())
			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + type.name() + "\" (nb required params = " + type.nbParams() + ") !");
			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + type.name() + "\" (nb required params = " + type.nbMaxParams() + ") !");

		switch(index){
			case 0:
@@ -169,7 +184,7 @@ public class MathFunction extends ADQLFunction {
	@Override
	public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception{
		if (index < 0 || index >= getNbParameters())
			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + type.name() + "\" (nb required params = " + type.nbParams() + ") !");
			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + type.name() + "\" (nb required params = " + type.nbMaxParams() + ") !");
		else if (replacer == null)
			throw new NullPointerException("Impossible to remove any parameter from a mathematical function ! All parameters are required !");
		else{
+22 −7
Original line number Diff line number Diff line
@@ -22,25 +22,40 @@ package adql.query.operand.function;
/**
 * All types of managed mathematical functions.
 * 
 * @author Gr&eacute;gory Mantelet (CDS)
 * @version 11/2010
 * @author Gr&eacute;gory Mantelet (CDS,ARI)
 * @version 03/2014
 * 
 * @see MathFunction
 */
public enum MathFunctionType{
	ABS(1), CEILING(1), DEGREES(1), EXP(1), FLOOR(1), LOG(1),		// returns the natural logarithm (base e) of a double value.
	LOG10(1),	// returns the base 10 logarithm of a double value.
	MOD(2), PI(0), POWER(2), RADIANS(1), SQRT(1), RAND(1), ROUND(2), TRUNCATE(2),
	MOD(2), PI(0), POWER(2), RADIANS(1), SQRT(1), RAND(0,1), ROUND(1,2), TRUNCATE(1,2),

	ACOS(1), ASIN(1), ATAN(1), ATAN2(2), COS(1), COT(1), SIN(1), TAN(1);

	private final int nbRequiredParameters;
	/** @since 1.2 */
	private final int nbMinRequiredParameters;
	/** @since 1.2 */
	private final int nbMaxRequiredParameters;

	private MathFunctionType(int nbParams){
		nbRequiredParameters = nbParams;
		this(nbParams, nbParams);
	}

	public final int nbParams(){
		return nbRequiredParameters;
	/** @since 1.2 */
	private MathFunctionType(int nbMinParams, int nbMaxParams){
		nbMinRequiredParameters = nbMinParams;
		nbMaxRequiredParameters = nbMaxParams;
	}

	/** @since 1.2 */
	public final int nbMinParams(){
		return nbMinRequiredParameters;
	}

	/** @since 1.2 */
	public final int nbMaxParams(){
		return nbMaxRequiredParameters;
	}
}