diff --git a/src/adql/translator/SQLServerTranslator.java b/src/adql/translator/SQLServerTranslator.java index e721c557eabfd134e1cdf2dc4f186fb33de38a94..89d6629d1e88648af600e81d64ea9555738807cb 100644 --- a/src/adql/translator/SQLServerTranslator.java +++ b/src/adql/translator/SQLServerTranslator.java @@ -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é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); }