Loading src/adql/parser/feature/FeatureSet.java +3 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import java.util.NoSuchElementException; import java.util.Set; import adql.db.FunctionDef; import adql.query.constraint.ComparisonOperator; import adql.query.operand.function.geometry.AreaFunction; import adql.query.operand.function.geometry.BoxFunction; import adql.query.operand.function.geometry.CentroidFunction; Loading Loading @@ -574,9 +575,7 @@ public class FeatureSet implements Iterable<LanguageFeature> { * * ********************************************************************** */ /*public static final LanguageFeature ILIKE = new LanguageFeature(FeatureType.ADQL_STRING, "ILIKE"); // TODO ILIKE public static final LanguageFeature UNION = new LanguageFeature(FeatureType.ADQL_SETS, "UNION"); // TODO UNION /*public static final LanguageFeature UNION = new LanguageFeature(FeatureType.ADQL_SETS, "UNION"); // TODO UNION public static final LanguageFeature EXCEPT = new LanguageFeature(FeatureType.ADQL_SETS, "EXCEPT"); // TODO EXCEPT public static final LanguageFeature INTERSECT = new LanguageFeature(FeatureType.ADQL_SETS, "INTERSECT"); // TODO INTERSECT Loading @@ -603,7 +602,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[]{ 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[]{ 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 }; /** * List all available language features. Loading src/adql/parser/grammar/adqlGrammar201.jj +9 −0 Original line number Diff line number Diff line Loading @@ -284,6 +284,7 @@ TOKEN : { | < NULL: "NULL" > { matchedToken.adqlReserved = true; } | < BETWEEN: "BETWEEN" > { matchedToken.adqlReserved = true; } | < LIKE: "LIKE" > { matchedToken.adqlReserved = true; } | < ILIKE: "ILIKE" > { matchedToken.adqlReserved = true; } } TOKEN : { < IN: "IN" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; } Loading Loading @@ -1069,6 +1070,14 @@ ADQLConstraint Predicate(): {ADQLQuery q=null; ADQLColumn column=null; ADQLOpera return comp; } ) // ilike_predicate | LOOKAHEAD(StringExpression() [<NOT>] <ILIKE>) (strExpr1=StringExpression() [notToken=<NOT>] <ILIKE> strExpr2=StringExpression() { Comparison comp = queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.ILIKE:ComparisonOperator.NOTILIKE, strExpr2); comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition())); return comp; } ) | (op=ValueExpression() (// comparison_predicate (constraint=ComparisonEnd(op)) Loading src/adql/query/constraint/ComparisonOperator.java +25 −3 Original line number Diff line number Diff line Loading @@ -26,12 +26,23 @@ import adql.query.operand.function.SQLFunction; * Gathers all comparison operators (numeric or not). * * @author Grégory Mantelet (CDS) * @version 2.0 (07/2019) * @version 2.0 (08/2019) * * @see Comparison */ public enum ComparisonOperator { EQUAL, NOT_EQUAL, LESS_THAN, LESS_OR_EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LIKE, NOTLIKE; EQUAL, NOT_EQUAL, LESS_THAN, LESS_OR_EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LIKE, /** @since 2.0 */ ILIKE, NOTLIKE, /** @since 2.0 */ NOTILIKE; /** Description of the ADQL Feature based on this type. * @since 2.0 */ Loading @@ -39,6 +50,9 @@ public enum ComparisonOperator { /** @since 2.0 */ private ComparisonOperator() { if (name().endsWith("ILIKE")) FEATURE = new LanguageFeature(LanguageFeature.TYPE_ADQL_STRING, "ILIKE", true, "Perform a case-insensitive comparison between its string operands."); else FEATURE = new LanguageFeature(null, this.name(), false); } Loading Loading @@ -75,8 +89,12 @@ public enum ComparisonOperator { return GREATER_OR_EQUAL; else if (str.equalsIgnoreCase("LIKE")) return LIKE; else if (str.equalsIgnoreCase("ILIKE")) return ILIKE; else if (str.equalsIgnoreCase("NOT LIKE")) return NOTLIKE; else if (str.equalsIgnoreCase("NOT ILIKE")) return NOTILIKE; else throw new UnsupportedOperationException("Comparison operator unknown: \"" + str + "\" !"); } Loading @@ -97,8 +115,12 @@ public enum ComparisonOperator { return ">="; case LIKE: return "LIKE"; case ILIKE: return "ILIKE"; case NOTLIKE: return "NOT LIKE"; case NOTILIKE: return "NOT ILIKE"; default: return "???"; } Loading src/adql/translator/ADQLTranslator.java +12 −8 Original line number Diff line number Diff line Loading @@ -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,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ Loading Loading @@ -65,12 +65,13 @@ 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; import adql.query.operand.function.string.LowerFunction; /** * Translates ADQL objects into any language (i.e. SQL). * * @author Grégory Mantelet (CDS) * @version 01/2012 * @version 2.0 (08/2019) * * @see PostgreSQLTranslator */ Loading Loading @@ -143,6 +144,9 @@ public interface ADQLTranslator { public String translate(UserDefinedFunction fct) throws TranslationException; /** @since 2.0 */ public String translate(LowerFunction fct) throws TranslationException; /* ***** GEOMETRICAL FUNCTIONS ***** */ public String translate(GeometryFunction fct) throws TranslationException; Loading src/adql/translator/JDBCTranslator.java +83 −75 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ 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; import adql.query.operand.function.string.LowerFunction; /** * Implementation of {@link ADQLTranslator} which translates ADQL queries in Loading @@ -89,7 +90,7 @@ import adql.query.operand.function.geometry.RegionFunction; * {@link MySQLTranslator} and {@link SQLServerTranslator} are doing. * </p> * * <p><i>Note: * <p><i><b>Note:</b> * Its default implementation of the SQL syntax has been inspired by the * PostgreSQL one. However, it should work also with other DBMS, although some * translations might be needed (as it is has been done for PostgreSQL about Loading Loading @@ -147,8 +148,8 @@ import adql.query.operand.function.geometry.RegionFunction; * translating differently: LOG, LOG10, RAND and TRUNC. * </p> * * <p><i>Note: * Geometrical regions and types have not been managed here. They stay abstract * <p><i><b>Note:</b> * Geometric regions and types have not been managed here. They stay abstract * because it is obviously impossible to have a generic translation and * conversion ; it totally depends from the database system. * </i></p> Loading @@ -162,7 +163,7 @@ import adql.query.operand.function.geometry.RegionFunction; * </p> * * @author Grégory Mantelet (ARI;CDS) * @version 1.5 (03/2019) * @version 2.0 (08/2019) * @since 1.4 * * @see PostgreSQLTranslator Loading Loading @@ -807,6 +808,8 @@ public abstract class JDBCTranslator implements ADQLTranslator { return translate((SQLFunction)fct); else if (fct instanceof UserDefinedFunction) return translate((UserDefinedFunction)fct); else if (fct instanceof LowerFunction) return translate((LowerFunction)fct); else return getDefaultADQLFunction(fct); } Loading Loading @@ -847,6 +850,11 @@ public abstract class JDBCTranslator implements ADQLTranslator { return fct.translate(this); } @Override public String translate(LowerFunction fct) throws TranslationException { return getDefaultADQLFunction(fct); } /* *********************************** */ /* ****** GEOMETRICAL FUNCTIONS ****** */ /* *********************************** */ Loading Loading
src/adql/parser/feature/FeatureSet.java +3 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import java.util.NoSuchElementException; import java.util.Set; import adql.db.FunctionDef; import adql.query.constraint.ComparisonOperator; import adql.query.operand.function.geometry.AreaFunction; import adql.query.operand.function.geometry.BoxFunction; import adql.query.operand.function.geometry.CentroidFunction; Loading Loading @@ -574,9 +575,7 @@ public class FeatureSet implements Iterable<LanguageFeature> { * * ********************************************************************** */ /*public static final LanguageFeature ILIKE = new LanguageFeature(FeatureType.ADQL_STRING, "ILIKE"); // TODO ILIKE public static final LanguageFeature UNION = new LanguageFeature(FeatureType.ADQL_SETS, "UNION"); // TODO UNION /*public static final LanguageFeature UNION = new LanguageFeature(FeatureType.ADQL_SETS, "UNION"); // TODO UNION public static final LanguageFeature EXCEPT = new LanguageFeature(FeatureType.ADQL_SETS, "EXCEPT"); // TODO EXCEPT public static final LanguageFeature INTERSECT = new LanguageFeature(FeatureType.ADQL_SETS, "INTERSECT"); // TODO INTERSECT Loading @@ -603,7 +602,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[]{ 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[]{ 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 }; /** * List all available language features. Loading
src/adql/parser/grammar/adqlGrammar201.jj +9 −0 Original line number Diff line number Diff line Loading @@ -284,6 +284,7 @@ TOKEN : { | < NULL: "NULL" > { matchedToken.adqlReserved = true; } | < BETWEEN: "BETWEEN" > { matchedToken.adqlReserved = true; } | < LIKE: "LIKE" > { matchedToken.adqlReserved = true; } | < ILIKE: "ILIKE" > { matchedToken.adqlReserved = true; } } TOKEN : { < IN: "IN" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; } Loading Loading @@ -1069,6 +1070,14 @@ ADQLConstraint Predicate(): {ADQLQuery q=null; ADQLColumn column=null; ADQLOpera return comp; } ) // ilike_predicate | LOOKAHEAD(StringExpression() [<NOT>] <ILIKE>) (strExpr1=StringExpression() [notToken=<NOT>] <ILIKE> strExpr2=StringExpression() { Comparison comp = queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.ILIKE:ComparisonOperator.NOTILIKE, strExpr2); comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition())); return comp; } ) | (op=ValueExpression() (// comparison_predicate (constraint=ComparisonEnd(op)) Loading
src/adql/query/constraint/ComparisonOperator.java +25 −3 Original line number Diff line number Diff line Loading @@ -26,12 +26,23 @@ import adql.query.operand.function.SQLFunction; * Gathers all comparison operators (numeric or not). * * @author Grégory Mantelet (CDS) * @version 2.0 (07/2019) * @version 2.0 (08/2019) * * @see Comparison */ public enum ComparisonOperator { EQUAL, NOT_EQUAL, LESS_THAN, LESS_OR_EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LIKE, NOTLIKE; EQUAL, NOT_EQUAL, LESS_THAN, LESS_OR_EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LIKE, /** @since 2.0 */ ILIKE, NOTLIKE, /** @since 2.0 */ NOTILIKE; /** Description of the ADQL Feature based on this type. * @since 2.0 */ Loading @@ -39,6 +50,9 @@ public enum ComparisonOperator { /** @since 2.0 */ private ComparisonOperator() { if (name().endsWith("ILIKE")) FEATURE = new LanguageFeature(LanguageFeature.TYPE_ADQL_STRING, "ILIKE", true, "Perform a case-insensitive comparison between its string operands."); else FEATURE = new LanguageFeature(null, this.name(), false); } Loading Loading @@ -75,8 +89,12 @@ public enum ComparisonOperator { return GREATER_OR_EQUAL; else if (str.equalsIgnoreCase("LIKE")) return LIKE; else if (str.equalsIgnoreCase("ILIKE")) return ILIKE; else if (str.equalsIgnoreCase("NOT LIKE")) return NOTLIKE; else if (str.equalsIgnoreCase("NOT ILIKE")) return NOTILIKE; else throw new UnsupportedOperationException("Comparison operator unknown: \"" + str + "\" !"); } Loading @@ -97,8 +115,12 @@ public enum ComparisonOperator { return ">="; case LIKE: return "LIKE"; case ILIKE: return "ILIKE"; case NOTLIKE: return "NOT LIKE"; case NOTILIKE: return "NOT ILIKE"; default: return "???"; } Loading
src/adql/translator/ADQLTranslator.java +12 −8 Original line number Diff line number Diff line Loading @@ -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,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ Loading Loading @@ -65,12 +65,13 @@ 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; import adql.query.operand.function.string.LowerFunction; /** * Translates ADQL objects into any language (i.e. SQL). * * @author Grégory Mantelet (CDS) * @version 01/2012 * @version 2.0 (08/2019) * * @see PostgreSQLTranslator */ Loading Loading @@ -143,6 +144,9 @@ public interface ADQLTranslator { public String translate(UserDefinedFunction fct) throws TranslationException; /** @since 2.0 */ public String translate(LowerFunction fct) throws TranslationException; /* ***** GEOMETRICAL FUNCTIONS ***** */ public String translate(GeometryFunction fct) throws TranslationException; Loading
src/adql/translator/JDBCTranslator.java +83 −75 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ 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; import adql.query.operand.function.string.LowerFunction; /** * Implementation of {@link ADQLTranslator} which translates ADQL queries in Loading @@ -89,7 +90,7 @@ import adql.query.operand.function.geometry.RegionFunction; * {@link MySQLTranslator} and {@link SQLServerTranslator} are doing. * </p> * * <p><i>Note: * <p><i><b>Note:</b> * Its default implementation of the SQL syntax has been inspired by the * PostgreSQL one. However, it should work also with other DBMS, although some * translations might be needed (as it is has been done for PostgreSQL about Loading Loading @@ -147,8 +148,8 @@ import adql.query.operand.function.geometry.RegionFunction; * translating differently: LOG, LOG10, RAND and TRUNC. * </p> * * <p><i>Note: * Geometrical regions and types have not been managed here. They stay abstract * <p><i><b>Note:</b> * Geometric regions and types have not been managed here. They stay abstract * because it is obviously impossible to have a generic translation and * conversion ; it totally depends from the database system. * </i></p> Loading @@ -162,7 +163,7 @@ import adql.query.operand.function.geometry.RegionFunction; * </p> * * @author Grégory Mantelet (ARI;CDS) * @version 1.5 (03/2019) * @version 2.0 (08/2019) * @since 1.4 * * @see PostgreSQLTranslator Loading Loading @@ -807,6 +808,8 @@ public abstract class JDBCTranslator implements ADQLTranslator { return translate((SQLFunction)fct); else if (fct instanceof UserDefinedFunction) return translate((UserDefinedFunction)fct); else if (fct instanceof LowerFunction) return translate((LowerFunction)fct); else return getDefaultADQLFunction(fct); } Loading Loading @@ -847,6 +850,11 @@ public abstract class JDBCTranslator implements ADQLTranslator { return fct.translate(this); } @Override public String translate(LowerFunction fct) throws TranslationException { return getDefaultADQLFunction(fct); } /* *********************************** */ /* ****** GEOMETRICAL FUNCTIONS ****** */ /* *********************************** */ Loading