Loading src/adql/parser/adqlGrammar.jj +26 −8 Original line number Diff line number Diff line Loading @@ -1077,6 +1077,7 @@ TOKEN : { < SELECT: "SELECT" > | < QUANTIFIER: "DISTINCT" | "ALL" > | < TOP: "TOP" > | < OFFSET: "OFFSET" > } /* ************* */ Loading Loading @@ -1300,12 +1301,22 @@ void Select(): {ClauseSelect select = query.getSelect(); SelectItem item=null; T } } ] [<OFFSET> t=<UNSIGNED_INTEGER> { try{ select.setOffset(Integer.parseInt(t.image)); }catch(NumberFormatException nfe){ throw new ParseException("[l."+t.beginLine+";c."+t.beginColumn+"] The OFFSET limit (\""+t.image+"\") isn't a regular unsigned integer !"); } } ] item=SelectItem() {select.add(item);} (<COMMA> item=SelectItem() {select.add(item);})* { TextPosition lastItemPos = query.getSelect().get(query.getSelect().size()-1).getPosition(); select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn)); } select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn)); } } SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null; SelectItem item; Token starToken;} { Loading Loading @@ -1349,7 +1360,8 @@ SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true if (label != null){ item.setCaseSensitive(label.caseSensitivity); item.setPosition(new TextPosition(op.getPosition(), label.position)); }else item.setPosition(new TextPosition(op.getPosition())); }else item.setPosition(new TextPosition(op.getPosition())); return item; }catch(Exception ex){ throw generateParseException(ex); Loading Loading @@ -1772,7 +1784,8 @@ ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null; )* { if (leftOp instanceof Concatenation){ Concatenation concat = (Concatenation)leftOp; concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition())); Concatenation concat = (Concatenation)leftOp; concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition())); } return leftOp; } Loading @@ -1788,7 +1801,8 @@ ADQLOperand StringFactor(): {ADQLOperand op;} { GeometryValue<GeometryFunction> GeometryExpression(): {ADQLColumn col = null; GeometryFunction gf = null;} { (col=Column() | gf=GeometryValueFunction()) { if (col != null){ col.setExpectedType('G'); if (col != null){ col.setExpectedType('G'); return new GeometryValue<GeometryFunction>(col); }else return new GeometryValue<GeometryFunction>(gf); Loading @@ -1804,7 +1818,8 @@ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint cons constraint=Constraint() { if (notOp){ TextPosition oldPos = constraint.getPosition(); constraint = queryFactory.createNot(constraint); TextPosition oldPos = constraint.getPosition(); constraint = queryFactory.createNot(constraint); ((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn)); } notOp = false; Loading Loading @@ -1836,7 +1851,8 @@ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint cons throw generateParseException(ex); } { if (!clause.isEmpty()){ TextPosition start = clause.get(0).getPosition(); if (!clause.isEmpty()){ TextPosition start = clause.get(0).getPosition(); TextPosition end = clause.get(clause.size()-1).getPosition(); clause.setPosition(new TextPosition(start, end)); } Loading Loading @@ -2013,7 +2029,8 @@ GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<Geometr { if (p1 != null) gvp1 = new GeometryValue<PointFunction>(p1); else{ col1.setExpectedType('G'); else{ col1.setExpectedType('G'); gvp1 = new GeometryValue<PointFunction>(col1); } } Loading @@ -2022,7 +2039,8 @@ GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<Geometr { if (p2 != null) gvp2 = new GeometryValue<PointFunction>(p2); else{ col2.setExpectedType('G'); else{ col2.setExpectedType('G'); gvp2 = new GeometryValue<PointFunction>(col2); } } Loading src/adql/query/ClauseSelect.java +37 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ public class ClauseSelect extends ClauseADQL<SelectItem> { /** The maximum number of returned rows. */ private int limit = -1; /** The number of rows to skip before selection. */ private int offset = -1; /** * Builds an empty SELECT clause. */ Loading Loading @@ -144,6 +147,40 @@ public class ClauseSelect extends ClauseADQL<SelectItem> { this.limit = limit; } /** * Indicates whether this SELECT clause sets an offset. * * @return <i>true</i> this clause has an OFFSET flag, <i>false</i> otherwise. */ public final boolean hasOffset(){ return offset >= 0; } /** * Gets the offset set by this SELECT clause. * * @return Number of rows the query must skip before selection (SELECT OFFSET offset). */ public final int getOffset(){ return offset; } /** * Sets no offset (classic SELECT). */ public final void setNoOffset(){ offset = -1; } /** * Changes the number of rows to skip this clause imposes. * * @param limit The number of rows to skip before selection (SELECT OFFSET offset). */ public final void setOffset(int newOffset){ this.offset = newOffset; } /** * <p>Adds an operand to this SELECT clause.</p> * Loading src/adql/translator/JDBCTranslator.java +3 −0 Original line number Diff line number Diff line Loading @@ -376,6 +376,9 @@ public abstract class JDBCTranslator implements ADQLTranslator { if (query.getSelect().hasLimit()) sql.append("\nLimit ").append(query.getSelect().getLimit()); if(query.getSelect().hasLimit() && query.getSelect().hasOffset()) sql.append(",").append(query.getSelect().getOffset()); return sql.toString(); } Loading src/adql/translator/MySQLTranslator.java +29 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import adql.db.DBType; import adql.db.DBType.DBDatatype; import adql.db.STCS.Region; import adql.parser.ParseException; import adql.query.ADQLQuery; import adql.query.IdentifierField; import adql.query.operand.ADQLOperand; import adql.query.operand.Concatenation; Loading Loading @@ -329,4 +330,32 @@ public class MySQLTranslator extends JDBCTranslator { return getDefaultADQLFunction(region); } @Override public String translate(ADQLQuery query) throws TranslationException{ StringBuilder sql = new StringBuilder(translate(query.getSelect())); sql.append("\nFROM ").append(translate(query.getFrom())); if (!query.getWhere().isEmpty()) sql.append('\n').append(translate(query.getWhere())); if (!query.getGroupBy().isEmpty()) sql.append('\n').append(translate(query.getGroupBy())); if (!query.getHaving().isEmpty()) sql.append('\n').append(translate(query.getHaving())); if (!query.getOrderBy().isEmpty()) sql.append('\n').append(translate(query.getOrderBy())); if (query.getSelect().hasLimit()) { sql.append("\n LIMIT "); if(query.getSelect().hasOffset()) { sql.append(query.getSelect().getOffset()).append(","); } sql.append(query.getSelect().getLimit()); } return sql.toString(); } } src/adql/translator/PostgreSQLTranslator.java +27 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import adql.db.DBType; import adql.db.DBType.DBDatatype; import adql.db.STCS.Region; import adql.parser.ParseException; import adql.query.ADQLQuery; import adql.query.IdentifierField; import adql.query.operand.StringConstant; import adql.query.operand.function.ADQLFunction; Loading Loading @@ -329,4 +330,30 @@ public class PostgreSQLTranslator extends JDBCTranslator { throw new ParseException("Geometries can not be uploaded in the database in this implementation!"); } @Override public String translate(ADQLQuery query) throws TranslationException{ StringBuffer sql = new StringBuffer(translate(query.getSelect())); sql.append("\nFROM ").append(translate(query.getFrom())); if (!query.getWhere().isEmpty()) sql.append('\n').append(translate(query.getWhere())); if (!query.getGroupBy().isEmpty()) sql.append('\n').append(translate(query.getGroupBy())); if (!query.getHaving().isEmpty()) sql.append('\n').append(translate(query.getHaving())); if (!query.getOrderBy().isEmpty()) sql.append('\n').append(translate(query.getOrderBy())); if (query.getSelect().hasLimit()) sql.append("\nLimit ").append(query.getSelect().getLimit()); if(query.getSelect().hasLimit() && query.getSelect().hasOffset()) sql.append(" offset ").append(query.getSelect().getOffset()); return sql.toString(); } } Loading
src/adql/parser/adqlGrammar.jj +26 −8 Original line number Diff line number Diff line Loading @@ -1077,6 +1077,7 @@ TOKEN : { < SELECT: "SELECT" > | < QUANTIFIER: "DISTINCT" | "ALL" > | < TOP: "TOP" > | < OFFSET: "OFFSET" > } /* ************* */ Loading Loading @@ -1300,12 +1301,22 @@ void Select(): {ClauseSelect select = query.getSelect(); SelectItem item=null; T } } ] [<OFFSET> t=<UNSIGNED_INTEGER> { try{ select.setOffset(Integer.parseInt(t.image)); }catch(NumberFormatException nfe){ throw new ParseException("[l."+t.beginLine+";c."+t.beginColumn+"] The OFFSET limit (\""+t.image+"\") isn't a regular unsigned integer !"); } } ] item=SelectItem() {select.add(item);} (<COMMA> item=SelectItem() {select.add(item);})* { TextPosition lastItemPos = query.getSelect().get(query.getSelect().size()-1).getPosition(); select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn)); } select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn)); } } SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null; SelectItem item; Token starToken;} { Loading Loading @@ -1349,7 +1360,8 @@ SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true if (label != null){ item.setCaseSensitive(label.caseSensitivity); item.setPosition(new TextPosition(op.getPosition(), label.position)); }else item.setPosition(new TextPosition(op.getPosition())); }else item.setPosition(new TextPosition(op.getPosition())); return item; }catch(Exception ex){ throw generateParseException(ex); Loading Loading @@ -1772,7 +1784,8 @@ ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null; )* { if (leftOp instanceof Concatenation){ Concatenation concat = (Concatenation)leftOp; concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition())); Concatenation concat = (Concatenation)leftOp; concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition())); } return leftOp; } Loading @@ -1788,7 +1801,8 @@ ADQLOperand StringFactor(): {ADQLOperand op;} { GeometryValue<GeometryFunction> GeometryExpression(): {ADQLColumn col = null; GeometryFunction gf = null;} { (col=Column() | gf=GeometryValueFunction()) { if (col != null){ col.setExpectedType('G'); if (col != null){ col.setExpectedType('G'); return new GeometryValue<GeometryFunction>(col); }else return new GeometryValue<GeometryFunction>(gf); Loading @@ -1804,7 +1818,8 @@ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint cons constraint=Constraint() { if (notOp){ TextPosition oldPos = constraint.getPosition(); constraint = queryFactory.createNot(constraint); TextPosition oldPos = constraint.getPosition(); constraint = queryFactory.createNot(constraint); ((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn)); } notOp = false; Loading Loading @@ -1836,7 +1851,8 @@ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint cons throw generateParseException(ex); } { if (!clause.isEmpty()){ TextPosition start = clause.get(0).getPosition(); if (!clause.isEmpty()){ TextPosition start = clause.get(0).getPosition(); TextPosition end = clause.get(clause.size()-1).getPosition(); clause.setPosition(new TextPosition(start, end)); } Loading Loading @@ -2013,7 +2029,8 @@ GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<Geometr { if (p1 != null) gvp1 = new GeometryValue<PointFunction>(p1); else{ col1.setExpectedType('G'); else{ col1.setExpectedType('G'); gvp1 = new GeometryValue<PointFunction>(col1); } } Loading @@ -2022,7 +2039,8 @@ GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<Geometr { if (p2 != null) gvp2 = new GeometryValue<PointFunction>(p2); else{ col2.setExpectedType('G'); else{ col2.setExpectedType('G'); gvp2 = new GeometryValue<PointFunction>(col2); } } Loading
src/adql/query/ClauseSelect.java +37 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ public class ClauseSelect extends ClauseADQL<SelectItem> { /** The maximum number of returned rows. */ private int limit = -1; /** The number of rows to skip before selection. */ private int offset = -1; /** * Builds an empty SELECT clause. */ Loading Loading @@ -144,6 +147,40 @@ public class ClauseSelect extends ClauseADQL<SelectItem> { this.limit = limit; } /** * Indicates whether this SELECT clause sets an offset. * * @return <i>true</i> this clause has an OFFSET flag, <i>false</i> otherwise. */ public final boolean hasOffset(){ return offset >= 0; } /** * Gets the offset set by this SELECT clause. * * @return Number of rows the query must skip before selection (SELECT OFFSET offset). */ public final int getOffset(){ return offset; } /** * Sets no offset (classic SELECT). */ public final void setNoOffset(){ offset = -1; } /** * Changes the number of rows to skip this clause imposes. * * @param limit The number of rows to skip before selection (SELECT OFFSET offset). */ public final void setOffset(int newOffset){ this.offset = newOffset; } /** * <p>Adds an operand to this SELECT clause.</p> * Loading
src/adql/translator/JDBCTranslator.java +3 −0 Original line number Diff line number Diff line Loading @@ -376,6 +376,9 @@ public abstract class JDBCTranslator implements ADQLTranslator { if (query.getSelect().hasLimit()) sql.append("\nLimit ").append(query.getSelect().getLimit()); if(query.getSelect().hasLimit() && query.getSelect().hasOffset()) sql.append(",").append(query.getSelect().getOffset()); return sql.toString(); } Loading
src/adql/translator/MySQLTranslator.java +29 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import adql.db.DBType; import adql.db.DBType.DBDatatype; import adql.db.STCS.Region; import adql.parser.ParseException; import adql.query.ADQLQuery; import adql.query.IdentifierField; import adql.query.operand.ADQLOperand; import adql.query.operand.Concatenation; Loading Loading @@ -329,4 +330,32 @@ public class MySQLTranslator extends JDBCTranslator { return getDefaultADQLFunction(region); } @Override public String translate(ADQLQuery query) throws TranslationException{ StringBuilder sql = new StringBuilder(translate(query.getSelect())); sql.append("\nFROM ").append(translate(query.getFrom())); if (!query.getWhere().isEmpty()) sql.append('\n').append(translate(query.getWhere())); if (!query.getGroupBy().isEmpty()) sql.append('\n').append(translate(query.getGroupBy())); if (!query.getHaving().isEmpty()) sql.append('\n').append(translate(query.getHaving())); if (!query.getOrderBy().isEmpty()) sql.append('\n').append(translate(query.getOrderBy())); if (query.getSelect().hasLimit()) { sql.append("\n LIMIT "); if(query.getSelect().hasOffset()) { sql.append(query.getSelect().getOffset()).append(","); } sql.append(query.getSelect().getLimit()); } return sql.toString(); } }
src/adql/translator/PostgreSQLTranslator.java +27 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import adql.db.DBType; import adql.db.DBType.DBDatatype; import adql.db.STCS.Region; import adql.parser.ParseException; import adql.query.ADQLQuery; import adql.query.IdentifierField; import adql.query.operand.StringConstant; import adql.query.operand.function.ADQLFunction; Loading Loading @@ -329,4 +330,30 @@ public class PostgreSQLTranslator extends JDBCTranslator { throw new ParseException("Geometries can not be uploaded in the database in this implementation!"); } @Override public String translate(ADQLQuery query) throws TranslationException{ StringBuffer sql = new StringBuffer(translate(query.getSelect())); sql.append("\nFROM ").append(translate(query.getFrom())); if (!query.getWhere().isEmpty()) sql.append('\n').append(translate(query.getWhere())); if (!query.getGroupBy().isEmpty()) sql.append('\n').append(translate(query.getGroupBy())); if (!query.getHaving().isEmpty()) sql.append('\n').append(translate(query.getHaving())); if (!query.getOrderBy().isEmpty()) sql.append('\n').append(translate(query.getOrderBy())); if (query.getSelect().hasLimit()) sql.append("\nLimit ").append(query.getSelect().getLimit()); if(query.getSelect().hasLimit() && query.getSelect().hasOffset()) sql.append(" offset ").append(query.getSelect().getOffset()); return sql.toString(); } }