Commit 1e903504 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Added OFFSET support for MySQL and PostgreSQL

parent 082f04b5
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -1077,6 +1077,7 @@ TOKEN : {
	< SELECT: "SELECT" >
|	< QUANTIFIER: "DISTINCT" | "ALL" >
|	< TOP: "TOP" >
|	< OFFSET: "OFFSET" >
}

/* ************* */
@@ -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;} {
@@ -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);
@@ -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;
	}
@@ -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);
@@ -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;
@@ -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));
		}
@@ -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);
					}
				}
@@ -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);
					}
				} 
+37 −0
Original line number Diff line number Diff line
@@ -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.
	 */
@@ -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>
	 * 
+3 −0
Original line number Diff line number Diff line
@@ -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();
	}

+29 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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();
	}
}
+27 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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();
	}
}