diff --git a/src/adql/parser/ADQLQueryFactory.java b/src/adql/parser/ADQLQueryFactory.java index d291ef4e297a1191c51e32bad90d4037f03ce605..f302459e194d51051463e8ac8d1e270a8bf9ebba 100644 --- a/src/adql/parser/ADQLQueryFactory.java +++ b/src/adql/parser/ADQLQueryFactory.java @@ -16,7 +16,7 @@ package adql.parser; * 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 2012-2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2021 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -81,6 +81,7 @@ import adql.query.operand.function.geometry.PointFunction; import adql.query.operand.function.geometry.PolygonFunction; import adql.query.operand.function.geometry.RegionFunction; import adql.query.operand.function.string.LowerFunction; +import adql.query.operand.function.string.UpperFunction; /** * This class lets the {@link ADQLParser} to build an object representation of @@ -92,7 +93,7 @@ import adql.query.operand.function.string.LowerFunction; * </p> * * @author Grégory Mantelet (CDS;ARI) - * @version 2.0 (04/2020) + * @version 2.0 (01/2021) * * @see ADQLParser */ @@ -306,6 +307,11 @@ public class ADQLQueryFactory { return new LowerFunction(op); } + /** @since 2.0 */ + public UpperFunction createUpperFunction(ADQLOperand op) throws Exception { + return new UpperFunction(op); + } + public MathFunction createMathFunction(MathFunctionType type, ADQLOperand param1, ADQLOperand param2) throws Exception { return new MathFunction(type, param1, param2); } diff --git a/src/adql/parser/feature/FeatureSet.java b/src/adql/parser/feature/FeatureSet.java index 75d7002e9977d2499c14f61e13d1165205a72279..8fe2d17d4184776d5a82b5b5a486c63b0358816a 100644 --- a/src/adql/parser/feature/FeatureSet.java +++ b/src/adql/parser/feature/FeatureSet.java @@ -16,7 +16,7 @@ package adql.parser.feature; * 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 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2019-2021 - UDS/Centre de Données astronomiques de Strasbourg (CDS) */ import java.util.Collection; @@ -45,6 +45,7 @@ import adql.query.operand.function.geometry.PointFunction; import adql.query.operand.function.geometry.PolygonFunction; import adql.query.operand.function.geometry.RegionFunction; import adql.query.operand.function.string.LowerFunction; +import adql.query.operand.function.string.UpperFunction; /** * Set of supported ADQL's language features. @@ -149,7 +150,7 @@ import adql.query.operand.function.string.LowerFunction; * </ul> * * @author Grégory Mantelet (CDS) - * @version 2.0 (11/2019) + * @version 2.0 (01/2021) * @since 2.0 */ public class FeatureSet implements Iterable<LanguageFeature> { @@ -594,7 +595,7 @@ public class FeatureSet implements Iterable<LanguageFeature> { * <p><i><b>Important note:</b> * All of them must be optional and must have a type. * </i></p> */ - static LanguageFeature[] availableFeatures = new LanguageFeature[]{ WithItem.FEATURE, InUnitFunction.FEATURE, ClauseOffset.FEATURE, ComparisonOperator.ILIKE.getFeatureDescription(), LowerFunction.FEATURE, AreaFunction.FEATURE, BoxFunction.FEATURE, CentroidFunction.FEATURE, CircleFunction.FEATURE, ContainsFunction.FEATURE, ExtractCoord.FEATURE_COORD1, ExtractCoord.FEATURE_COORD2, ExtractCoordSys.FEATURE, DistanceFunction.FEATURE, IntersectsFunction.FEATURE, PointFunction.FEATURE, PolygonFunction.FEATURE, RegionFunction.FEATURE }; + static LanguageFeature[] availableFeatures = new LanguageFeature[]{ WithItem.FEATURE, InUnitFunction.FEATURE, ClauseOffset.FEATURE, ComparisonOperator.ILIKE.getFeatureDescription(), LowerFunction.FEATURE, UpperFunction.FEATURE, AreaFunction.FEATURE, BoxFunction.FEATURE, CentroidFunction.FEATURE, CircleFunction.FEATURE, ContainsFunction.FEATURE, ExtractCoord.FEATURE_COORD1, ExtractCoord.FEATURE_COORD2, ExtractCoordSys.FEATURE, DistanceFunction.FEATURE, IntersectsFunction.FEATURE, PointFunction.FEATURE, PolygonFunction.FEATURE, RegionFunction.FEATURE }; /** * List all available language features. diff --git a/src/adql/parser/feature/default_features.md b/src/adql/parser/feature/default_features.md index e3a7eca3427accd9612010d51f1a5169bbb2ac29..d40e26e89ff84d2e95761537048d271af7029dba 100644 --- a/src/adql/parser/feature/default_features.md +++ b/src/adql/parser/feature/default_features.md @@ -22,6 +22,7 @@ Here is a sum-up of supported features for each implemented translator: | Feature | MySQL | MS-SQL Server | PostgreSQL | PgSphere | | LOWER | X | X | X | X | +| UPPER | X | X | X | X | | geometries | | | | X | | ILIKE | | | X | X | | IN_UNIT | | | | | diff --git a/src/adql/parser/grammar/adqlGrammar201.jj b/src/adql/parser/grammar/adqlGrammar201.jj index 24fef4ebb2b4fa0e575cbddc8e1b39aa1c3a152b..8cec52481ed068a3b2dad4d2eb650e17b46ec702 100644 --- a/src/adql/parser/grammar/adqlGrammar201.jj +++ b/src/adql/parser/grammar/adqlGrammar201.jj @@ -14,7 +14,7 @@ * 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 2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2020-2021 - UDS/Centre de Données astronomiques de Strasbourg (CDS) */ /* @@ -31,7 +31,7 @@ * ParseException is thrown. * * Author: Grégory Mantelet (CDS) -* Version: 2.0 (06/2020) +* Version: 2.0 (01/2021) */ /* ########### */ @@ -68,7 +68,7 @@ package adql.parser.grammar; * 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 2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2020-2021 - UDS/Centre de Données astronomiques de Strasbourg (CDS) */ import java.util.Vector; @@ -107,7 +107,7 @@ import adql.query.operand.function.geometry.GeometryFunction.GeometryValue; * @see ADQLParser * * @author Grégory Mantelet (CDS) - * @version 2.0 (06/2020) + * @version 2.0 (01/2021) * @since 2.0 */ public class ADQLGrammar201 extends ADQLGrammarBase { @@ -206,7 +206,7 @@ SKIP : { < " " | "\t" | "\n" | "\r" | "\r\n" > } /* ************************************************************************** */ TOKEN : { - < SQL_RESERVED_WORD: ("ABSOLUTE"|"ACTION"|"ADD"|"ALLOCATE"|"ALTER"|"ANY"|"ARE"|"ASSERTION"|"AT"|"AUTHORIZATION"|"BEGIN"|"BIT"|"BIT_LENGTH"|"BOTH"|"CASCADE"|"CASCADED"|"CASE"|"CAST"|"CATALOG"|"CHAR"|"CHARACTER"|"CHAR_LENGTH"|"CHARACTER_LENGTH"|"CHECK"|"CLOSE"|"COALESCE"|"COLLATE"|"COLLATION"|"COLUMN"|"COMMIT"|"CONNECT"|"CONNECTION"|"CONSTRAINT"|"CONSTRAINTS"|"CONTINUE"|"CONVERT"|"CORRESPONDING"|"CREATE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_USER"|"CURSOR"|"DATE"|"DAY"|"DEALLOCATE"|"DECIMAL"|"DECLARE"|"DEFAULT"|"DEFERRABLE"|"DEFERRED"|"DELETE"|"DESCRIBE"|"DESCRIPTOR"|"DIAGNOSTICS"|"DISCONNECT"|"DOMAIN"|"DOUBLE"|"DROP"|"ELSE"|"END"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXCEPTION"|"EXEC"|"EXECUTE"|"EXTERNAL"|"EXTRACT"|"FALSE"|"FETCH"|"FIRST"|"FLOAT"|"FOR"|"FOREIGN"|"FOUND"|"GET"|"GLOBAL"|"GO"|"GOTO"|"GRANT"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"INDICATOR"|"INITIALLY"|"INPUT"|"INSENSITIVE"|"INSERT"|"INT"|"INTEGER"|"INTERSECT"|"INTERVAL"|"INTO"|"ISOLATION"|"KEY"|"LANGUAGE"|"LAST"|"LEADING"|"LEVEL"|"LOCAL"|"MATCH"|"MINUTE"|"MODULE"|"MONTH"|"NAMES"|"NATIONAL"|"NCHAR"|"NEXT"|"NO"|"NULLIF"|"NUMERIC"|"OCTET_LENGTH"|"OF"|"ONLY"|"OPEN"|"OPTION"|"OUTPUT"|"OVERLAPS"|"PAD"|"PARTIAL"|"POSITION"|"PRECISION"|"PREPARE"|"PRESERVE"|"PRIMARY"|"PRIOR"|"PRIVILEGES"|"PROCEDURE"|"PUBLIC"|"READ"|"REAL"|"REFERENCES"|"RELATIVE"|"RESTRICT"|"REVOKE"|"ROLLBACK"|"ROWS"|"SCHEMA"|"SCROLL"|"SECOND"|"SECTION"|"SESSION"|"SESSION_USER"|"SET"|"SIZE"|"SMALLINT"|"SOME"|"SPACE"|"SQL"|"SQLCODE"|"SQLERROR"|"SQLSTATE"|"SUBSTRING"|"SYSTEM_USER"|"TABLE"|"TEMPORARY"|"THEN"|"TIME"|"TIMESTAMP"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSACTION"|"TRANSLATE"|"TRANSLATION"|"TRIM"|"TRUE"|"UNION"|"UNIQUE"|"UNKNOWN"|"UPDATE"|"UPPER"|"USAGE"|"USER"|"VALUE"|"VALUES"|"VARCHAR"|"VARYING"|"VIEW"|"WHEN"|"WHENEVER"|"WORK"|"WRITE"|"YEAR"|"ZONE") > + < SQL_RESERVED_WORD: ("ABSOLUTE"|"ACTION"|"ADD"|"ALLOCATE"|"ALTER"|"ANY"|"ARE"|"ASSERTION"|"AT"|"AUTHORIZATION"|"BEGIN"|"BIT"|"BIT_LENGTH"|"BOTH"|"CASCADE"|"CASCADED"|"CASE"|"CAST"|"CATALOG"|"CHAR"|"CHARACTER"|"CHAR_LENGTH"|"CHARACTER_LENGTH"|"CHECK"|"CLOSE"|"COALESCE"|"COLLATE"|"COLLATION"|"COLUMN"|"COMMIT"|"CONNECT"|"CONNECTION"|"CONSTRAINT"|"CONSTRAINTS"|"CONTINUE"|"CONVERT"|"CORRESPONDING"|"CREATE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_USER"|"CURSOR"|"DATE"|"DAY"|"DEALLOCATE"|"DECIMAL"|"DECLARE"|"DEFAULT"|"DEFERRABLE"|"DEFERRED"|"DELETE"|"DESCRIBE"|"DESCRIPTOR"|"DIAGNOSTICS"|"DISCONNECT"|"DOMAIN"|"DOUBLE"|"DROP"|"ELSE"|"END"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXCEPTION"|"EXEC"|"EXECUTE"|"EXTERNAL"|"EXTRACT"|"FALSE"|"FETCH"|"FIRST"|"FLOAT"|"FOR"|"FOREIGN"|"FOUND"|"GET"|"GLOBAL"|"GO"|"GOTO"|"GRANT"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"INDICATOR"|"INITIALLY"|"INPUT"|"INSENSITIVE"|"INSERT"|"INT"|"INTEGER"|"INTERSECT"|"INTERVAL"|"INTO"|"ISOLATION"|"KEY"|"LANGUAGE"|"LAST"|"LEADING"|"LEVEL"|"LOCAL"|"MATCH"|"MINUTE"|"MODULE"|"MONTH"|"NAMES"|"NATIONAL"|"NCHAR"|"NEXT"|"NO"|"NULLIF"|"NUMERIC"|"OCTET_LENGTH"|"OF"|"ONLY"|"OPEN"|"OPTION"|"OUTPUT"|"OVERLAPS"|"PAD"|"PARTIAL"|"POSITION"|"PRECISION"|"PREPARE"|"PRESERVE"|"PRIMARY"|"PRIOR"|"PRIVILEGES"|"PROCEDURE"|"PUBLIC"|"READ"|"REAL"|"REFERENCES"|"RELATIVE"|"RESTRICT"|"REVOKE"|"ROLLBACK"|"ROWS"|"SCHEMA"|"SCROLL"|"SECOND"|"SECTION"|"SESSION"|"SESSION_USER"|"SET"|"SIZE"|"SMALLINT"|"SOME"|"SPACE"|"SQL"|"SQLCODE"|"SQLERROR"|"SQLSTATE"|"SUBSTRING"|"SYSTEM_USER"|"TABLE"|"TEMPORARY"|"THEN"|"TIME"|"TIMESTAMP"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSACTION"|"TRANSLATE"|"TRANSLATION"|"TRIM"|"TRUE"|"UNION"|"UNIQUE"|"UNKNOWN"|"UPDATE"|"USAGE"|"USER"|"VALUE"|"VALUES"|"VARCHAR"|"VARYING"|"VIEW"|"WHEN"|"WHENEVER"|"WORK"|"WRITE"|"YEAR"|"ZONE") > { matchedToken.sqlReserved = true; } } @@ -341,6 +341,7 @@ TOKEN : { /* ********************** */ TOKEN : { < LOWER: "LOWER" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; } +| < UPPER: "UPPER" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; } } /* ********************** */ @@ -914,7 +915,7 @@ ADQLOperand StringValueExpressionPrimary(): {StringConstant expr; ADQLColumn col ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; Token left, right; } { try{ (LOOKAHEAD((<PLUS>|<MINUS>) | (Factor() (<PLUS>|<MINUS>|<ASTERISK>|<DIVIDE>))) valueExpr=NumericExpression() - | LOOKAHEAD(<COORDSYS> | <LOWER> | (StringFactor() <CONCAT>)) valueExpr=StringExpression() + | LOOKAHEAD(<COORDSYS> | <LOWER> | <UPPER> | (StringFactor() <CONCAT>)) valueExpr=StringExpression() | LOOKAHEAD(<LEFT_PAR>) left=<LEFT_PAR> valueExpr=ValueExpression() right=<RIGHT_PAR> { valueExpr = queryFactory.createWrappedOperand(valueExpr); ((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right)); } | LOOKAHEAD(<REGULAR_IDENTIFIER_CANDIDATE> <LEFT_PAR>) valueExpr=UserDefinedFunction() | LOOKAHEAD(2) valueExpr=GeometryValueFunction() @@ -1025,6 +1026,7 @@ ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null; ADQLOperand StringFactor(): {ADQLOperand op;} { (op=ExtractCoordSys() | op=LowerFunction() + | op=UpperFunction() | LOOKAHEAD(2) op=UserDefinedFunction() { ((UserDefinedFunction)op).setExpectedType('S'); } | op=StringValueExpressionPrimary()) {return op;} @@ -1573,6 +1575,19 @@ LowerFunction LowerFunction(): { Token start, end; ADQLOperand str; } { } } +UpperFunction UpperFunction(): { Token start, end; ADQLOperand str; } { + start=<UPPER> <LEFT_PAR> str=StringExpression() end=<RIGHT_PAR> + { + try{ + UpperFunction lf = queryFactory.createUpperFunction(str); + lf.setPosition(new TextPosition(start, end)); + return lf; + }catch(Exception ex){ + throw generateParseException(ex); + } + } +} + /* ***************** */ /* NUMERIC FUNCTIONS */ /* ***************** */ diff --git a/src/adql/query/operand/function/string/UpperFunction.java b/src/adql/query/operand/function/string/UpperFunction.java new file mode 100644 index 0000000000000000000000000000000000000000..9966ae1f3f5ff230420ccd2cec6ff12b2c4973ec --- /dev/null +++ b/src/adql/query/operand/function/string/UpperFunction.java @@ -0,0 +1,145 @@ +package adql.query.operand.function.string; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * 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 2021 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + */ + +import adql.parser.feature.LanguageFeature; +import adql.query.ADQLObject; +import adql.query.operand.ADQLOperand; +import adql.query.operand.function.ADQLFunction; + +/** + * It represents the UPPER function of ADQL. + * + * <p>This function converts its string parameter to upper case.</p> + * + * <p> + * Since case folding is a nontrivial operation in a multi-encoding world, + * ADQL requires standard behaviour for the ASCII characters, and + * recommends following algorithm R1 described in Section 3.13, + * "Default Case Algorithms" of The Unicode Consortium (2012) for characters + * outside the ASCII set. + * </p> + * + * <i> + * <p><b>Example:</b></p> + * <pre>LOWER('Francis Albert Augustus Charles Emmanuel')</pre> + * <p>which should return:</p> + * <pre>FRANCIS ALBERT AUGUSTUS CHARLES EMMANUEL</pre> + * </i> + * + * @author Grégory Mantelet (CDS) + * @version 2.0 (01/2021) + * @since 2.0 + */ +public class UpperFunction extends ADQLFunction { + + /** Description of this ADQL Feature. + * @since 2.0 */ + public static final LanguageFeature FEATURE = new LanguageFeature(LanguageFeature.TYPE_ADQL_STRING, "UPPER", true, "Convert all characters of the given string in upper case."); + + /** Constant name of this function. */ + protected final String FCT_NAME = "UPPER"; + + /** The only parameter of this function. */ + protected ADQLOperand strParam; + + /** + * Builds a UPPER function with its parameter. + * + * @param param Parameter of UPPER. + * + * @throws NullPointerException If the given operand is NULL. + * @throws IllegalArgumentException If the operand is not a string parameter. + */ + public UpperFunction(final ADQLOperand strParam) throws NullPointerException, IllegalArgumentException { + if (strParam == null) + throw new NullPointerException("The function " + FCT_NAME + " must have one non-NULL parameter!"); + + if (!strParam.isString()) + throw new IllegalArgumentException("The ADQL function " + FCT_NAME + " must have one parameter of type VARCHAR (i.e. a String)!"); + + this.strParam = strParam; + } + + @Override + public final LanguageFeature getFeatureDescription() { + return FEATURE; + } + + @Override + public final boolean isNumeric() { + return false; + } + + @Override + public final boolean isString() { + return true; + } + + @Override + public final boolean isGeometry() { + return false; + } + + @Override + public final String getName() { + return FCT_NAME; + } + + @Override + public ADQLObject getCopy() throws Exception { + return new UpperFunction((ADQLOperand)(strParam.getCopy())); + } + + @Override + public int getNbParameters() { + return 1; + } + + @Override + public final ADQLOperand[] getParameters() { + return new ADQLOperand[]{ strParam }; + } + + @Override + public ADQLOperand getParameter(final int index) throws ArrayIndexOutOfBoundsException { + if (index == 0) + return strParam; + else + throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + FCT_NAME + "\"!"); + } + + @Override + public ADQLOperand setParameter(final int index, final ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception { + if (index == 0) { + ADQLOperand replaced = strParam; + if (replacer == null) + throw new NullPointerException("Missing the new parameter of the function \"" + toADQL() + "\"!"); + else if (replacer.isString()) + strParam = replacer; + else + throw new Exception("Impossible to replace a String parameter by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ")!"); + setPosition(null); + return replaced; + } else + throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + FCT_NAME + "\"!"); + } + +} diff --git a/src/adql/translator/ADQLTranslator.java b/src/adql/translator/ADQLTranslator.java index 3814698cc566fada71f67d2f6f13d3141370c01d..641bb85dd4ca12ba2a3cc65424ef603ab8f823a1 100644 --- a/src/adql/translator/ADQLTranslator.java +++ b/src/adql/translator/ADQLTranslator.java @@ -16,7 +16,7 @@ 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 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2021 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -70,12 +70,13 @@ import adql.query.operand.function.geometry.PointFunction; import adql.query.operand.function.geometry.PolygonFunction; import adql.query.operand.function.geometry.RegionFunction; import adql.query.operand.function.string.LowerFunction; +import adql.query.operand.function.string.UpperFunction; /** * Translates ADQL objects into any language (i.e. SQL). * * @author Grégory Mantelet (CDS) - * @version 2.0 (11/2019) + * @version 2.0 (01/2021) * * @see PostgreSQLTranslator */ @@ -173,6 +174,9 @@ public interface ADQLTranslator { /** @since 2.0 */ public String translate(LowerFunction fct) throws TranslationException; + /** @since 2.0 */ + public String translate(UpperFunction fct) throws TranslationException; + /** @since 2.0 */ public String translate(InUnitFunction fct) throws TranslationException; diff --git a/src/adql/translator/JDBCTranslator.java b/src/adql/translator/JDBCTranslator.java index 1c38047f86a10c2b0cc370157367dff09897210e..800ad8802efb025dd7fae23797b30380a85c233a 100644 --- a/src/adql/translator/JDBCTranslator.java +++ b/src/adql/translator/JDBCTranslator.java @@ -16,7 +16,7 @@ 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 2017-2019 - Astronomisches Rechen Institut (ARI), + * Copyright 2017-2021 - Astronomisches Rechen Institut (ARI), * UDS/Centre de Données astronomiques de Strasbourg (CDS) */ @@ -82,6 +82,7 @@ import adql.query.operand.function.geometry.PointFunction; import adql.query.operand.function.geometry.PolygonFunction; import adql.query.operand.function.geometry.RegionFunction; import adql.query.operand.function.string.LowerFunction; +import adql.query.operand.function.string.UpperFunction; /** * Implementation of {@link ADQLTranslator} which translates ADQL queries in @@ -167,7 +168,7 @@ import adql.query.operand.function.string.LowerFunction; * </p> * * @author Grégory Mantelet (ARI;CDS) - * @version 2.0 (11/2019) + * @version 2.0 (01/2021) * @since 1.4 * * @see PostgreSQLTranslator @@ -832,6 +833,8 @@ public abstract class JDBCTranslator implements ADQLTranslator { return translate((UserDefinedFunction)fct); else if (fct instanceof LowerFunction) return translate((LowerFunction)fct); + else if (fct instanceof UpperFunction) + return translate((UpperFunction)fct); else if (fct instanceof InUnitFunction) return translate((InUnitFunction)fct); else @@ -879,6 +882,11 @@ public abstract class JDBCTranslator implements ADQLTranslator { return getDefaultADQLFunction(fct); } + @Override + public String translate(UpperFunction fct) throws TranslationException { + return getDefaultADQLFunction(fct); + } + /* *********************************** */ /* ****** GEOMETRICAL FUNCTIONS ****** */ /* *********************************** */