diff --git a/src/adql/translator/PostgreSQLTranslator.java b/src/adql/translator/PostgreSQLTranslator.java index 9c500b35584efed7da1a4b1c4b35fa9a9c170fa0..8e3b9225ab17a109a2894d34f798cba3c5a83bc4 100644 --- a/src/adql/translator/PostgreSQLTranslator.java +++ b/src/adql/translator/PostgreSQLTranslator.java @@ -50,7 +50,7 @@ import adql.query.operand.function.geometry.RegionFunction; * </i></p> * * @author Gré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 + ")"; } } diff --git a/test/adql/translator/TestPostgreSQLTranslator.java b/test/adql/translator/TestPostgreSQLTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..01fef8e2fea34d1ab87e8f9224ba78e56f8e5e67 --- /dev/null +++ b/test/adql/translator/TestPostgreSQLTranslator.java @@ -0,0 +1,62 @@ +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()); + } + } + } + +}