Commit 335515dd authored by gmantele's avatar gmantele
Browse files

[ADQL] Fix PSQL translation bug: DOUBLE and REAL parameters of mathematical

functions must be casted into NUMERIC. Otherwise Postgres rejects the query.
parent f4f05986
Loading
Loading
Loading
Loading
+24 −5
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ import adql.query.operand.function.geometry.RegionFunction;
 * </i></p>
 * 
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 1.4 (07/2015)
 * @version 1.4 (12/2015)
 * 
 * @see PgSphereTranslator
 */
@@ -120,15 +120,34 @@ public class PostgreSQLTranslator extends JDBCTranslator {
	public String translate(MathFunction fct) throws TranslationException{
		switch(fct.getType()){
			case LOG:
				return "ln(" + ((fct.getNbParameters() >= 1) ? translate(fct.getParameter(0)) : "") + ")";
				return "ln(" + ((fct.getNbParameters() >= 1) ? "CAST(" + translate(fct.getParameter(0)) + " AS numeric)" : "") + ")";
			case LOG10:
				return "log(10, " + ((fct.getNbParameters() >= 1) ? translate(fct.getParameter(0)) : "") + ")";
				return "log(10, " + ((fct.getNbParameters() >= 1) ? "CAST(" + translate(fct.getParameter(0)) + " AS numeric)" : "") + ")";
			case RAND:
				return "random()";
			case TRUNCATE:
				return "trunc(" + ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1))) : "") + ")";
			default:
				if (fct.getNbParameters() >= 2)
					return "trunc(CAST(" + translate(fct.getParameter(0)) + " AS numeric), " + translate(fct.getParameter(1)) + ")";
				else if (fct.getNbParameters() >= 1)
					return "trunc(CAST(" + translate(fct.getParameter(0)) + " AS numeric)" + ")";
				else
					return "trunc()";
			case ROUND:
				if (fct.getNbParameters() >= 2)
					return "round(CAST(" + translate(fct.getParameter(0)) + " AS numeric), " + translate(fct.getParameter(1)) + ")";
				else if (fct.getNbParameters() >= 1)
					return "round(CAST(" + translate(fct.getParameter(0)) + " AS numeric))";
				else
					return "round()";
			case PI:
				return getDefaultADQLFunction(fct);
			default:
				String sql = fct.getName() + "(";

				for(int i = 0; i < fct.getNbParameters(); i++)
					sql += ((i == 0) ? "" : ", ") + "CAST(" + translate(fct.getParameter(i)) + " AS numeric)";

				return sql + ")";
		}
	}

+62 −0
Original line number Diff line number Diff line
package adql.translator;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import org.junit.Before;
import org.junit.Test;

import adql.query.operand.NumericConstant;
import adql.query.operand.function.MathFunction;
import adql.query.operand.function.MathFunctionType;

public class TestPostgreSQLTranslator {

	@Before
	public void setUp() throws Exception{}

	@Test
	public void testTranslateMathFunction(){
		// Check that all math functions, except PI, operates a cast to their DOUBLE/REAL parameters:
		PostgreSQLTranslator trans = new PostgreSQLTranslator();
		MathFunctionType[] types = MathFunctionType.values();
		NumericConstant num = new NumericConstant("1.234"), prec = new NumericConstant("2");
		for(MathFunctionType type : types){
			try{
				switch(type){
					case PI:
						assertEquals("PI()", trans.translate(new MathFunction(type)));
						break;
					case RAND:
						assertEquals("random()", trans.translate(new MathFunction(type)));
						assertEquals("random()", trans.translate(new MathFunction(type, num)));
						break;
					case LOG:
						assertEquals("ln(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num)));
						break;
					case LOG10:
						assertEquals("log(10, CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num)));
						break;
					case TRUNCATE:
						assertEquals("trunc(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num)));
						assertEquals("trunc(CAST(1.234 AS numeric), 2)", trans.translate(new MathFunction(type, num, prec)));
						break;
					case ROUND:
						assertEquals("round(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num)));
						assertEquals("round(CAST(1.234 AS numeric), 2)", trans.translate(new MathFunction(type, num, prec)));
						break;
					default:
						if (type.nbMaxParams() == 1 || type.nbMinParams() == 1)
							assertEquals(type + "(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num)));
						if (type.nbMaxParams() == 2)
							assertEquals(type + "(CAST(1.234 AS numeric), CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num, num)));
						break;
				}
			}catch(Exception ex){
				ex.printStackTrace();
				fail("Translation exception for the type \"" + type + "\": " + ex.getMessage());
			}
		}
	}

}