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; ...@@ -16,12 +16,21 @@ package adql.translator;
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with ADQLLibrary. If not, see <http://www.gnu.org/licenses/>. * 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.DBType.DBDatatype;
import adql.db.DefaultDBColumn;
import adql.db.DefaultDBTable;
import adql.db.STCS.Region; import adql.db.STCS.Region;
import adql.db.SearchColumnList;
import adql.db.exception.UnresolvedJoinException; import adql.db.exception.UnresolvedJoinException;
import adql.parser.ADQLParser; import adql.parser.ADQLParser;
import adql.parser.ParseException; import adql.parser.ParseException;
...@@ -32,10 +41,18 @@ import adql.query.IdentifierField; ...@@ -32,10 +41,18 @@ import adql.query.IdentifierField;
import adql.query.from.ADQLJoin; import adql.query.from.ADQLJoin;
import adql.query.operand.ADQLColumn; import adql.query.operand.ADQLColumn;
import adql.query.operand.function.MathFunction; import adql.query.operand.function.MathFunction;
import adql.query.operand.function.geometry.*; import adql.query.operand.function.geometry.AreaFunction;
import adql.query.operand.function.geometry.BoxFunction;
import java.util.ArrayList; import adql.query.operand.function.geometry.CentroidFunction;
import java.util.Iterator; 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> * <p>MS SQL Server translator.</p>
...@@ -59,7 +76,7 @@ import java.util.Iterator; ...@@ -59,7 +76,7 @@ import java.util.Iterator;
* </i></p> * </i></p>
* *
* @author Gr&eacute;gory Mantelet (ARI) * @author Gr&eacute;gory Mantelet (ARI)
* @version 1.4 (03/2016) * @version 1.4 (09/2017)
* @since 1.4 * @since 1.4
* *
* @see SQLServer_ADQLQueryFactory * @see SQLServer_ADQLQueryFactory
...@@ -137,9 +154,12 @@ public class SQLServerTranslator extends JDBCTranslator { ...@@ -137,9 +154,12 @@ public class SQLServerTranslator extends JDBCTranslator {
return field == null ? false : field.isCaseSensitive(caseSensitivity); 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. * For SQL Server, {@link #translate(ClauseSelect)} must be overridden for
* @see adql.translator.ADQLTranslator#translate(adql.query.ADQLQuery) * 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 @Override
public String translate(ADQLQuery query) throws TranslationException{ public String translate(ADQLQuery query) throws TranslationException{
...@@ -162,10 +182,6 @@ public class SQLServerTranslator extends JDBCTranslator { ...@@ -162,10 +182,6 @@ public class SQLServerTranslator extends JDBCTranslator {
return sql.toString(); 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 @Override
public String translate(ClauseSelect clause) throws TranslationException{ public String translate(ClauseSelect clause) throws TranslationException{
String sql = null; String sql = null;
...@@ -323,11 +339,30 @@ public class SQLServerTranslator extends JDBCTranslator { ...@@ -323,11 +339,30 @@ public class SQLServerTranslator extends JDBCTranslator {
switch(fct.getType()){ switch(fct.getType()){
case TRUNCATE: case TRUNCATE:
// third argument to round nonzero means do a 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: 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: case ATAN2:
return "ATN2(" + translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1)) + ")"; 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: default:
return getDefaultADQLFunction(fct); 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