Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
...@@ -50,7 +50,7 @@ import adql.query.operand.function.geometry.RegionFunction; ...@@ -50,7 +50,7 @@ import adql.query.operand.function.geometry.RegionFunction;
* </i></p> * </i></p>
* *
* @author Gr&eacute;gory Mantelet (CDS;ARI) * @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 1.4 (07/2015) * @version 1.4 (12/2015)
* *
* @see PgSphereTranslator * @see PgSphereTranslator
*/ */
...@@ -120,15 +120,34 @@ public class PostgreSQLTranslator extends JDBCTranslator { ...@@ -120,15 +120,34 @@ public class PostgreSQLTranslator extends JDBCTranslator {
public String translate(MathFunction fct) throws TranslationException{ public String translate(MathFunction fct) throws TranslationException{
switch(fct.getType()){ switch(fct.getType()){
case LOG: 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: 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: case RAND:
return "random()"; return "random()";
case TRUNCATE: case TRUNCATE:
return "trunc(" + ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1))) : "") + ")"; if (fct.getNbParameters() >= 2)
default: 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); 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 + ")";
} }
} }
......
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());
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment