Skip to content
Snippets Groups Projects
Commit 73630130 authored by gmantele's avatar gmantele
Browse files

[ADQL] Fix return type of some math. functions for MS-SQLServer.

In MS-SQLServer, the following functions return a value of the same
type as the given argument:
  - abs
  - ceiling
  - degrees
  - floor
  - radians
  - round.

Since ADQL requires that these functions return a DOUBLE
(i.e. a float in MS-SQLServer), it must be ensured that the given
argument is a float.

This commit partially fixes the Pull Request #16
parent a382b251
No related branches found
No related tags found
No related merge requests found
......@@ -16,12 +16,21 @@ package adql.translator;
* 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 2016 - Astronomisches Rechen Institut (ARI)
* Copyright 2016-2017 - Astronomisches Rechen Institut (ARI)
*/
import adql.db.*;
import java.util.ArrayList;
import java.util.Iterator;
import adql.db.DBChecker;
import adql.db.DBColumn;
import adql.db.DBTable;
import adql.db.DBType;
import adql.db.DBType.DBDatatype;
import adql.db.DefaultDBColumn;
import adql.db.DefaultDBTable;
import adql.db.STCS.Region;
import adql.db.SearchColumnList;
import adql.db.exception.UnresolvedJoinException;
import adql.parser.ADQLParser;
import adql.parser.ParseException;
......@@ -32,10 +41,18 @@ import adql.query.IdentifierField;
import adql.query.from.ADQLJoin;
import adql.query.operand.ADQLColumn;
import adql.query.operand.function.MathFunction;
import adql.query.operand.function.geometry.*;
import java.util.ArrayList;
import java.util.Iterator;
import adql.query.operand.function.geometry.AreaFunction;
import adql.query.operand.function.geometry.BoxFunction;
import adql.query.operand.function.geometry.CentroidFunction;
import adql.query.operand.function.geometry.CircleFunction;
import adql.query.operand.function.geometry.ContainsFunction;
import adql.query.operand.function.geometry.DistanceFunction;
import adql.query.operand.function.geometry.ExtractCoord;
import adql.query.operand.function.geometry.ExtractCoordSys;
import adql.query.operand.function.geometry.IntersectsFunction;
import adql.query.operand.function.geometry.PointFunction;
import adql.query.operand.function.geometry.PolygonFunction;
import adql.query.operand.function.geometry.RegionFunction;
/**
* <p>MS SQL Server translator.</p>
......@@ -59,7 +76,7 @@ import java.util.Iterator;
* </i></p>
*
* @author Gr&eacute;gory Mantelet (ARI)
* @version 1.4 (03/2016)
* @version 1.4 (09/2017)
* @since 1.4
*
* @see SQLServer_ADQLQueryFactory
......@@ -137,9 +154,12 @@ public class SQLServerTranslator extends JDBCTranslator {
return field == null ? false : field.isCaseSensitive(caseSensitivity);
}
/* For SQL Server, translate(ADQLQuery) must be overridden for TOP/LIMIT handling.
* We must not add "LIMIT" at the end of the query, it must go in select.
* @see adql.translator.ADQLTranslator#translate(adql.query.ADQLQuery)
/**
* For SQL Server, {@link #translate(ClauseSelect)} must be overridden for
* TOP/LIMIT handling. We must not add the LIMIT at the end of the query, it
* must go in the SELECT.
*
* @see #translate(ClauseSelect)
*/
@Override
public String translate(ADQLQuery query) throws TranslationException{
......@@ -162,10 +182,6 @@ public class SQLServerTranslator extends JDBCTranslator {
return sql.toString();
}
/* For SQL Server, translate(ClauseSelect) must be overridden for TOP/LIMIT handling.
* We must not add "LIMIT" at the end of the query, it must go in select.
* @see adql.translator.ADQLTranslator#translate(adql.query.ClauseSelect)
*/
@Override
public String translate(ClauseSelect clause) throws TranslationException{
String sql = null;
......@@ -323,11 +339,30 @@ public class SQLServerTranslator extends JDBCTranslator {
switch(fct.getType()){
case TRUNCATE:
// third argument to round nonzero means do a truncate
return "round(" + ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1))) : "") + ",1)";
return "round(convert(float, " + ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1))) : "") + "),1)";
case MOD:
return ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + "% " + translate(fct.getParameter(1))) : "");
return ((fct.getNbParameters() >= 2) ? ("convert(float, " + translate(fct.getParameter(0)) + ") % convert(float, " + translate(fct.getParameter(1)) + ")") : "");
case ATAN2:
return "ATN2(" + translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1)) + ")";
/* In MS-SQLServer, the following functions returns a value of the
* same type as the given argument. However, ADQL requires that an
* SQLServer float (so a double in ADQL) is returned. So, in order
* to follow the ADQL standard, the given parameter must be
* converted into a float: */
case ABS:
return "abs(convert(float, " + translate(fct.getParameter(0)) + "))";
case CEILING:
return "ceiling(convert(float, " + translate(fct.getParameter(0)) + "))";
case DEGREES:
return "degrees(convert(float, " + translate(fct.getParameter(0)) + "))";
case FLOOR:
return "floor(convert(float, " + translate(fct.getParameter(0)) + "))";
case RADIANS:
return "radians(convert(float, " + translate(fct.getParameter(0)) + "))";
case ROUND:
return "round(convert(float, " + translate(fct.getParameter(0)) + ")" + ", " + translate(fct.getParameter(1)) + ")";
default:
return getDefaultADQLFunction(fct);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment