/* ADQLParser.java */
/* Generated By:JavaCC: Do not edit this line. ADQLParser.java */
package adql.parser;

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Vector;

import adql.db.exception.UnresolvedIdentifiersException;
import adql.parser.ADQLQueryFactory.JoinType;
import adql.parser.IdentifierItems.IdentifierItem;
import adql.query.ADQLOrder;
import adql.query.ADQLQuery;
import adql.query.ClauseADQL;
import adql.query.ClauseConstraints;
import adql.query.ClauseSelect;
import adql.query.SelectAllColumns;
import adql.query.SelectItem;
import adql.query.TextPosition;
import adql.query.constraint.ADQLConstraint;
import adql.query.constraint.Between;
import adql.query.constraint.Comparison;
import adql.query.constraint.ComparisonOperator;
import adql.query.constraint.ConstraintsGroup;
import adql.query.constraint.Exists;
import adql.query.constraint.In;
import adql.query.constraint.IsNull;
import adql.query.constraint.NotConstraint;
import adql.query.from.ADQLJoin;
import adql.query.from.FromContent;
import adql.query.operand.ADQLColumn;
import adql.query.operand.ADQLOperand;
import adql.query.operand.Concatenation;
import adql.query.operand.NegativeOperand;
import adql.query.operand.NumericConstant;
import adql.query.operand.Operation;
import adql.query.operand.OperationType;
import adql.query.operand.StringConstant;
import adql.query.operand.WrappedOperand;
import adql.query.operand.function.ADQLFunction;
import adql.query.operand.function.MathFunction;
import adql.query.operand.function.MathFunctionType;
import adql.query.operand.function.SQLFunction;
import adql.query.operand.function.SQLFunctionType;
import adql.query.operand.function.UserDefinedFunction;
import adql.query.operand.function.geometry.GeometryFunction;
import adql.query.operand.function.geometry.GeometryFunction.GeometryValue;
import adql.query.operand.function.geometry.PointFunction;
import adql.translator.PostgreSQLTranslator;
import adql.translator.TranslationException;

/**
* Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.
*
* <p>
*   This parser is able, thanks to a {@link QueryChecker} object, to check each
*   {@link ADQLQuery} just after its generation. It could be used to check the
*   consistency between the ADQL query to parse and the "database" on which the
*   query must be executed. By default, there is no {@link QueryChecker}. Thus
*   you must extend {@link QueryChecker} to check semantically all generated
*   ADQLQuery objects.
* </p>
*
* <p>
*   To create an object representation of the given ADQL query, this parser uses
*   a {@link ADQLQueryFactory} object. So if you want customize some object
*   (ie. CONTAINS) of this representation you just have to extend the
*   corresponding default object (ie. ContainsFunction) and to extend the
*   corresponding function of {@link ADQLQueryFactory}
*   (ie. createContains(...)).
* </p>
*
* <p><b><u>WARNING:</u>
*   To modify this class it's strongly encouraged to modify the .jj file in the
*   section between <i>PARSER_BEGIN</i> and <i>PARSER_END</i> and to re-compile
*   it with JavaCC.
* </b></p>
*
* @see QueryChecker
* @see ADQLQueryFactory
*
* @author Gr&eacute;gory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de
* @version 1.4 (01/2018)
*/
public class ADQLParser implements ADQLParserConstants {

	/** Tools to build the object representation of the ADQL query. */
	private ADQLQueryFactory queryFactory = new ADQLQueryFactory();

	/** The stack of queries (because there may be some sub-queries). */
	private Stack<ADQLQuery> stackQuery = new Stack<ADQLQuery>();

	/** The object representation of the ADQL query to parse.
	* (ONLY USED DURING THE PARSING, else it is always <i>null</i>). */
	private ADQLQuery query = null;

	/** Checks each {@link ADQLQuery} (sub-query or not) just after their
	* generation. */
	private QueryChecker queryChecker = null;

	/** The first token of a table/column name. This token is extracted by
	* {@link #Identifier()}. */
	private Token currentIdentifierToken = null;

	/**
	* Builds an ADQL parser without a query to parse.
	*/
	public ADQLParser(){
		this(new java.io.ByteArrayInputStream("".getBytes()));
		setDebug(false);
	}

	/**
	* Builds an ADQL parser without a query to parse but with a
	* {@link QueryChecker} and a {@link ADQLQueryFactory}.
	*
	* @param checker	The object to use to check each {@link ADQLQuery}.
	* @param factory	The object to use to build an object representation of
	*               	the given ADQL query.
	*/
	public ADQLParser(QueryChecker checker, ADQLQueryFactory factory){
		this();

		queryChecker = checker;

		if (factory != null)
			queryFactory = factory;
	}

	/**
	* Builds an ADQL parser without a query to parse but with a
	* {@link QueryChecker}.
	*
	* @param checker	The object to use to check each {@link ADQLQuery}.
	*/
	public ADQLParser(QueryChecker checker){
		this(checker, null);
	}

	/**
	* Builds an ADQL parser without a query to parse but with a
	* {@link ADQLQueryFactory}.
	*
	* @param factory	The object to use to build an object representation of
	*               	the given ADQL query.
	*/
	public ADQLParser(ADQLQueryFactory factory){
		this((QueryChecker)null, factory);
	}

	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	* @param factory	The object to use to build an object representation of
	*               	the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory){
		this(stream);
		setDebug(false);

		setDebug(false);

		queryChecker = checker;

		if (factory != null)
			queryFactory = factory;
	}

	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	*/
	public ADQLParser(java.io.InputStream stream, QueryChecker checker){
		this(stream, checker, null);
	}

	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param factory	The object to use to build an object representation of
	*               	the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory){
		this(stream, (QueryChecker)null, factory);
	}

	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param encoding	The supplied encoding.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	* @param factory	The object to use to build an object representation
	*               	of the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory){
		this(stream, encoding);
		setDebug(false);

		queryChecker = checker;

		if (factory != null)
			queryFactory = factory;
	}

	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param encoding	The supplied encoding.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	*/
	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker){
		this(stream, encoding, checker, null);
	}

	/**
	* Builds a parser with a stream containing the query to parse.
	*
	* @param stream		The stream in which the ADQL query to parse is given.
	* @param encoding	The supplied encoding.
	* @param factory	The object to use to build an object representation
	*               	of the given ADQL query.
	*/
	public ADQLParser(java.io.InputStream stream, String encoding, ADQLQueryFactory factory){
		this(stream, encoding, null, factory);
	}

	/**
	* Builds a parser with a reader containing the query to parse.
	*
	* @param reader		The reader in which the ADQL query to parse is given.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	* @param factory	The object to use to build an object representation
	*               	of the given ADQL query.
	*/
	public ADQLParser(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory){
		this(reader);
		setDebug(false);

		setDebug(false);

		queryChecker = checker;

		if (factory != null)
			queryFactory = factory;
	}

	/**
	* Builds a parser with a reader containing the query to parse.
	*
	* @param reader		The reader in which the ADQL query to parse is given.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	*/
	public ADQLParser(java.io.Reader reader, QueryChecker checker){
		this(reader, checker, null);
	}

	/**
	* Builds a parser with a reader containing the query to parse.
	*
	* @param reader		The reader in which the ADQL query to parse is given.
	* @param factory	The object to use to build an object representation
	*               	of the given ADQL query.
	*/
	public ADQLParser(java.io.Reader reader, ADQLQueryFactory factory){
		this(reader, null, factory);
	}

	/**
	* Builds a parser with another token manager.
	*
	* @param tm			The manager which associates a token to a numeric code.
	* @param checker	The object to use to check each {@link ADQLQuery }.
	* @param factory	The object to use to build an object representation
	*               	of the given ADQL query.
	*/
	public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker, ADQLQueryFactory factory){
		this(tm);
		setDebug(false);

		setDebug(false);

		queryChecker = checker;

		if (factory != null)
			queryFactory = factory;
	}

	/**
	* Builds a parser with another token manager.
	*
	* @param tm			The manager which associates a token to a numeric code.
	* @param checker	The object to use to check each {@link ADQLQuery}.
	*/
	public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker){
		this(tm, checker, null);
	}

	/**
	* Builds a parser with another token manager.
	*
	* @param tm			The manager which associates a token to a numeric code.
	* @param factory	The object to use to build an object representation of
	*               	the given ADQL query.
	*/
	public ADQLParser(ADQLParserTokenManager tm, ADQLQueryFactory factory){
		this(tm, null, factory);
	}

	/**
	* Parses the query given at the creation of this parser or in the
	* <i>ReInit</i> functions.
	*
	* @return 	The object representation of the given ADQL query.
	*
	* @throws ParseException	If there is at least one syntactic error.
	*
	* @see ADQLParser#Query()
	*/
	public final ADQLQuery parseQuery() throws ParseException{
		stackQuery.clear();
		query = null;
		try{
			return Query();
		}catch(TokenMgrError tme){
			throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn()));
		}
	}

	/**
	* Parses the query given in parameter.
	*
	* @param q	The ADQL query to parse.
	*
	* @return	The object representation of the given ADQL query.
	*
	* @throws ParseException	If there is at least one syntactic error.
	*
	* @see ADQLParser#ReInit(java.io.InputStream)
	* @see ADQLParser#setDebug(boolean)
	* @see ADQLParser#Query()
	*/
	public final ADQLQuery parseQuery(String q) throws ParseException{
		stackQuery.clear();
		query = null;
		ReInit(new java.io.ByteArrayInputStream(q.getBytes()));
		try{
			return Query();
		}catch(TokenMgrError tme){
			throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn()));
		}
	}

	/**
	* Parses the query contained in the stream given in parameter.
	*
	* @param stream		The stream which contains the ADQL query to parse.
	*
	* @return	The object representation of the given ADQL query.
	*
	* @throws ParseException	If there is at least one syntactic error.
	*
	* @see ADQLParser#ReInit(java.io.InputStream)
	* @see ADQLParser#setDebug(boolean)
	* @see ADQLParser#Query()
	*/
	public final ADQLQuery parseQuery(java.io.InputStream stream) throws ParseException{
		stackQuery.clear();
		query = null;
		ReInit(stream);
		try{
			return Query();
		}catch(TokenMgrError tme){
			throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn()));
		}
	}

	public final void setDebug(boolean debug){
		if (debug)
			enable_tracing();
		else
			disable_tracing();
	}

	public final QueryChecker getQueryChecker(){
		return queryChecker;
	}

	public final void setQueryChecker(QueryChecker checker){
		queryChecker = checker;
	}

	public final ADQLQueryFactory getQueryFactory(){
		return queryFactory;
	}

	public final void setQueryFactory(ADQLQueryFactory factory){
		queryFactory = (factory != null) ? factory : (new ADQLQueryFactory());
	}

	private final ParseException generateParseException(Exception ex){
		if (!(ex instanceof ParseException)){
			ParseException pex = new ParseException("[" + ex.getClass().getName() + "] " + ex.getMessage());
			pex.setStackTrace(ex.getStackTrace());
			return pex;
		}else
			return (ParseException)ex;
	}

	/**
	* Gets the specified ADQL query and parses the given ADQL query. The SQL
	* translation is then printed if the syntax is correct.
	*
	* <p>
	*     <b>ONLY the syntax is checked: the query is NOT EXECUTED !</b>
	* </p>
	*
	* <p>Supplied parameters are:
	*     <ul>
	*       <li>[-debug] -url http://...</li>
	*       <li>[-debug] -file ...</li>
	*       <li>[-debug] -query SELECT...</li>
	*     </ul>
	* </p>
	*
	* @param args

	* @throws Exception
	*/
	public static final void main(String[] args) throws Exception{
		final String USAGE = "Usage:\u005cn\u005ctadqlParser.jar [-d] [-v] [-e] [-a|-s] [<FILE>|<URL>]\u005cn\u005cnNOTE: If no file or URL is given, the ADQL query is expected in the standard input. This query must end with a ';' !\u005cn\u005cnParameters:\u005cn\u005ct-v or --verbose : Print the main steps of the parsing\u005cn\u005ct-d or --debug   : Print stack traces when a grave error occurs\u005cn\u005ct-e or --explain : Explain the ADQL parsing (or Expand the parsing tree)\u005cn\u005ct-a or --adql    : Display the understood ADQL query\u005cn\u005ct-s or --sql     : Ask the SQL translation of the given ADQL query (SQL compatible with PostgreSQL)\u005cn\u005cnReturn:\u005cn\u005ctBy default: nothing if the query is correct. Otherwise a message explaining why the query is not correct is displayed.\u005cn\u005ctWith the -s option, the SQL translation of the given ADQL query will be returned.\u005cn\u005ctWith the -a option, the ADQL query is returned as it has been understood.\u005cn\u005cnExit status:\u005cn\u005ct0\u005ctOK !\u005cn\u005ct1\u005ctParameter error (missing or incorrect parameter)\u005cn\u005ct2\u005ctFile error (incorrect file/url, reading error, ...)\u005cn\u005ct3\u005ctParsing error (syntactic or semantic error)\u005cn\u005ct4\u005ctTranslation error (a problem has occurred during the translation of the given ADQL query in SQL).";

		ADQLParser parser;

		final String urlRegex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

		String file = null, metaFile = null;
		short mode = -1;
		boolean verbose = false, debug = false, explain = false;

		// Parameters reading:
		for(int i = 0; i < args.length; i++){
			if (args[i].equalsIgnoreCase("-d") || args[i].equalsIgnoreCase("--debug"))
				debug = true;
			else if (args[i].equalsIgnoreCase("-v") || args[i].equalsIgnoreCase("--verbose"))
				verbose = true;
			else if (args[i].equalsIgnoreCase("-e") || args[i].equalsIgnoreCase("--explain"))
				explain = true;
			else if (args[i].equalsIgnoreCase("-a") || args[i].equalsIgnoreCase("--adql")){
				if (mode != -1){
					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\u005cn" + USAGE);
					System.exit(1);
				}else
					mode = 1;
			}else if (args[i].equalsIgnoreCase("-s") || args[i].equalsIgnoreCase("--sql")){
				if (mode != -1){
					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\u005cn" + USAGE);
					System.exit(1);
				}else
					mode = 2;
			}else if (args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("--help")){
				System.out.println(USAGE);
				System.exit(0);
			}else if (args[i].startsWith("-")){
				System.err.println("((!)) Unknown parameter: \u005c"" + args[i] + "\u005c" ((!))\u005cn" + USAGE);
				System.exit(1);
			}else
				file = args[i].trim();
		}

		try{

			if (file == null || file.length() == 0)
				parser = new ADQLParser(System.in);
			else if (file.matches(urlRegex))
				parser = new ADQLParser((new java.net.URL(file)).openStream());
			else
				parser = new ADQLParser(new FileReader(file));

			parser.setDebug(explain);

			// Query parsing:
			try{
				if (verbose)
					System.out.print("((i)) Parsing ADQL query...");
				ADQLQuery q = parser.parseQuery();
				if (verbose)
					System.out.println("((i)) CORRECT ADQL QUERY ((i))");
				if (mode == 2){
					PostgreSQLTranslator translator = new PostgreSQLTranslator();
					if (verbose)
						System.out.print("((i)) Translating in SQL...");
					String sql = translator.translate(q);
					if (verbose)
						System.out.println("ok");
					System.out.println(sql);
				}else if (mode == 1){
					System.out.println(q.toADQL());
				}
			}catch(UnresolvedIdentifiersException uie){
				System.err.println("((X)) " + uie.getNbErrors() + " unresolved identifiers:");
				for(ParseException pe : uie)
					System.err.println("\u005ct - at " + pe.getPosition() + ": " + uie.getMessage());
				if (debug)
					uie.printStackTrace(System.err);
				System.exit(3);
			}catch(ParseException pe){
				System.err.println("((X)) Syntax error: " + pe.getMessage() + " ((X))");
				if (debug)
					pe.printStackTrace(System.err);
				System.exit(3);
			}catch(TranslationException te){
				if (verbose)
					System.out.println("error");
				System.err.println("((X)) Translation error: " + te.getMessage() + " ((X))");
				if (debug)
					te.printStackTrace(System.err);
				System.exit(4);
			}

		}catch(IOException ioe){
			System.err.println("\u005cn((X)) Error while reading the file \u005c"" + file + "\u005c": " + ioe.getMessage() + " ((X))");
			if (debug)
				ioe.printStackTrace(System.err);
			System.exit(2);
		}

	}

	/* ########## */
	/* # SYNTAX # */
	/* ########## */

	/* ******************* */
	/* GENERAL ADQL SYNTAX */
	/* ******************* */
	/**
	* Parses the ADQL query given at the parser creation or in the {@link ADQLParser#ReInit(java.io.InputStream)}
	* or in the <i>parseQuery</i> functions.
	*
	* @return					The object representation of the query.
	* @throws ParseException	If the query syntax is incorrect.
	*/
	final public ADQLQuery Query() throws ParseException{
		trace_call("Query");
		try{
			ADQLQuery q = null;
			q = QueryExpression();
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case 0:{
					jj_consume_token(0);
					break;
				}
				case EOQ:{
					jj_consume_token(EOQ);
					break;
				}
				default:
					jj_la1[0] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			// check the query:
			if (queryChecker != null)
				queryChecker.check(q);

			{
				if ("" != null)
					return q;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Query");
		}
	}

	final public ADQLQuery QueryExpression() throws ParseException{
		trace_call("QueryExpression");
		try{
			TextPosition endPos = null;
			try{
				// create the query:
				query = queryFactory.createQuery();
				stackQuery.push(query);
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			Select();
			From();
			endPos = query.getFrom().getPosition();
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case WHERE:{
					Where();
					endPos = query.getWhere().getPosition();
					break;
				}
				default:
					jj_la1[1] = jj_gen;;
			}
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case GROUP:{
					GroupBy();
					endPos = query.getGroupBy().getPosition();
					break;
				}
				default:
					jj_la1[2] = jj_gen;;
			}
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case HAVING:{
					Having();
					endPos = query.getHaving().getPosition();
					break;
				}
				default:
					jj_la1[3] = jj_gen;;
			}
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case ORDER:{
					OrderBy();
					endPos = query.getOrderBy().getPosition();
					break;
				}
				default:
					jj_la1[4] = jj_gen;;
			}
			// set the position of the query:
			query.setPosition(new TextPosition(query.getSelect().getPosition(), endPos));

			// get the previous query (!= null if the current query is a sub-query):
			ADQLQuery previousQuery = stackQuery.pop();
			if (stackQuery.isEmpty())
				query = null;
			else
				query = stackQuery.peek();

			{
				if ("" != null)
					return previousQuery;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("QueryExpression");
		}
	}

	final public ADQLQuery SubQueryExpression() throws ParseException{
		trace_call("SubQueryExpression");
		try{
			ADQLQuery q = null;
			Token start, end;
			start = jj_consume_token(LEFT_PAR);
			q = QueryExpression();
			end = jj_consume_token(RIGHT_PAR);
			q.setPosition(new TextPosition(start, end));
			{
				if ("" != null)
					return q;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("SubQueryExpression");
		}
	}

	final public void Select() throws ParseException{
		trace_call("Select");
		try{
			ClauseSelect select = query.getSelect();
			SelectItem item = null;
			Token start, t = null;
			start = jj_consume_token(SELECT);
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case QUANTIFIER:{
					t = jj_consume_token(QUANTIFIER);
					select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT"));
					break;
				}
				default:
					jj_la1[5] = jj_gen;;
			}
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case TOP:{
					jj_consume_token(TOP);
					t = jj_consume_token(UNSIGNED_INTEGER);
					try{
						select.setLimit(Integer.parseInt(t.image));
					}catch(NumberFormatException nfe){
						{
							if (true)
								throw new ParseException("[l." + t.beginLine + ";c." + t.beginColumn + "] The TOP limit (\u005c"" + t.image + "\u005c") isn't a regular unsigned integer !");
						}
					}
					break;
				}
				default:
					jj_la1[6] = jj_gen;;
			}
			item = SelectItem();
			select.add(item);
			label_1: while(true){
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case COMMA:{
						;
						break;
					}
					default:
						jj_la1[7] = jj_gen;
						break label_1;
				}
				jj_consume_token(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));
		}finally{
			trace_return("Select");
		}
	}

	final public SelectItem SelectItem() throws ParseException{
		trace_call("SelectItem");
		try{
			IdentifierItems identifiers = new IdentifierItems(true);
			IdentifierItem id = null, label = null;
			ADQLOperand op = null;
			SelectItem item;
			Token starToken;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case ASTERISK:{
					starToken = jj_consume_token(ASTERISK);
					item = new SelectAllColumns(query);
					item.setPosition(new TextPosition(starToken));
					{
						if ("" != null)
							return item;
					}
					break;
				}
				default:
					jj_la1[12] = jj_gen;
					if (jj_2_1(7)){
						id = Identifier();
						jj_consume_token(DOT);
						identifiers.append(id);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:{
								id = Identifier();
								jj_consume_token(DOT);
								identifiers.append(id);
								switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
									case DELIMITED_IDENTIFIER:
									case REGULAR_IDENTIFIER:{
										id = Identifier();
										jj_consume_token(DOT);
										identifiers.append(id);
										break;
									}
									default:
										jj_la1[8] = jj_gen;;
								}
								break;
							}
							default:
								jj_la1[9] = jj_gen;;
						}
						starToken = jj_consume_token(ASTERISK);
						try{
							item = new SelectAllColumns(queryFactory.createTable(identifiers, null));
							TextPosition firstPos = identifiers.get(0).position;
							item.setPosition(new TextPosition(firstPos.beginLine, firstPos.beginColumn, starToken.endLine, (starToken.endColumn < 0) ? -1 : (starToken.endColumn + 1)));
							{
								if ("" != null)
									return item;
							}
						}catch(Exception ex){
							{
								if (true)
									throw generateParseException(ex);
							}
						}
					}else{
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case LEFT_PAR:
							case PLUS:
							case MINUS:
							case AVG:
							case MAX:
							case MIN:
							case SUM:
							case COUNT:
							case BOX:
							case CENTROID:
							case CIRCLE:
							case POINT:
							case POLYGON:
							case REGION:
							case CONTAINS:
							case INTERSECTS:
							case AREA:
							case COORD1:
							case COORD2:
							case COORDSYS:
							case DISTANCE:
							case ABS:
							case CEILING:
							case DEGREES:
							case EXP:
							case FLOOR:
							case LOG:
							case LOG10:
							case MOD:
							case PI:
							case POWER:
							case RADIANS:
							case RAND:
							case ROUND:
							case SQRT:
							case TRUNCATE:
							case ACOS:
							case ASIN:
							case ATAN:
							case ATAN2:
							case COS:
							case COT:
							case SIN:
							case TAN:
							case STRING_LITERAL:
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:
							case SCIENTIFIC_NUMBER:
							case UNSIGNED_FLOAT:
							case UNSIGNED_INTEGER:{
								op = ValueExpression();
								switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
									case AS:
									case DELIMITED_IDENTIFIER:
									case REGULAR_IDENTIFIER:{
										switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
											case AS:{
												jj_consume_token(AS);
												break;
											}
											default:
												jj_la1[10] = jj_gen;;
										}
										label = Identifier();
										break;
									}
									default:
										jj_la1[11] = jj_gen;;
								}
								break;
							}
							default:
								jj_la1[13] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
					}
			}
			try{
				item = queryFactory.createSelectItem(op, (label == null) ? null : label.identifier);
				if (label != null){
					item.setCaseSensitive(label.caseSensitivity);
					item.setPosition(new TextPosition(op.getPosition(), label.position));
				}else
					item.setPosition(new TextPosition(op.getPosition()));
				{
					if ("" != null)
						return item;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("SelectItem");
		}
	}

	final public void From() throws ParseException{
		trace_call("From");
		try{
			FromContent content = null, content2 = null;
			try{
				jj_consume_token(FROM);
				content = TableRef();
				label_2: while(true){
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case COMMA:{
							;
							break;
						}
						default:
							jj_la1[14] = jj_gen;
							break label_2;
					}
					jj_consume_token(COMMA);
					content2 = TableRef();
					TextPosition startPos = content.getPosition(),
							endPos = content2.getPosition();
					content = queryFactory.createJoin(JoinType.CROSS, content, content2);
					content.setPosition(new TextPosition(startPos, endPos));
				}
				query.setFrom(content);
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
		}finally{
			trace_return("From");
		}
	}

	final public void Where() throws ParseException{
		trace_call("Where");
		try{
			ClauseConstraints where = query.getWhere();
			ADQLConstraint condition;
			Token start;
			start = jj_consume_token(WHERE);
			ConditionsList(where);
			TextPosition endPosition = where.getPosition();
			where.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
		}finally{
			trace_return("Where");
		}
	}

	final public void GroupBy() throws ParseException{
		trace_call("GroupBy");
		try{
			ClauseADQL<ADQLColumn> groupBy = query.getGroupBy();
			ADQLColumn colRef = null;
			Token start;
			start = jj_consume_token(GROUP);
			jj_consume_token(BY);
			colRef = Column();
			groupBy.add(colRef);
			label_3: while(true){
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case COMMA:{
						;
						break;
					}
					default:
						jj_la1[15] = jj_gen;
						break label_3;
				}
				jj_consume_token(COMMA);
				colRef = Column();
				groupBy.add(colRef);
			}
			groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn));
		}finally{
			trace_return("GroupBy");
		}
	}

	final public void Having() throws ParseException{
		trace_call("Having");
		try{
			ClauseConstraints having = query.getHaving();
			Token start;
			start = jj_consume_token(HAVING);
			ConditionsList(having);
			TextPosition endPosition = having.getPosition();
			having.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
		}finally{
			trace_return("Having");
		}
	}

	final public void OrderBy() throws ParseException{
		trace_call("OrderBy");
		try{
			ClauseADQL<ADQLOrder> orderBy = query.getOrderBy();
			ADQLOrder order = null;
			Token start;
			start = jj_consume_token(ORDER);
			jj_consume_token(BY);
			order = OrderItem();
			orderBy.add(order);
			label_4: while(true){
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case COMMA:{
						;
						break;
					}
					default:
						jj_la1[16] = jj_gen;
						break label_4;
				}
				jj_consume_token(COMMA);
				order = OrderItem();
				orderBy.add(order);
			}
			orderBy.setPosition(new TextPosition(start, token));
		}finally{
			trace_return("OrderBy");
		}
	}

	/* *************************** */
	/* COLUMN AND TABLE REFERENCES */
	/* *************************** */
	final public IdentifierItem Identifier() throws ParseException{
		trace_call("Identifier");
		try{
			Token t;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case REGULAR_IDENTIFIER:{
					t = jj_consume_token(REGULAR_IDENTIFIER);
					{
						if ("" != null)
							return new IdentifierItem(t, false);
					}
					break;
				}
				case DELIMITED_IDENTIFIER:{
					t = jj_consume_token(DELIMITED_IDENTIFIER);
					{
						if ("" != null)
							return new IdentifierItem(t, true);
					}
					break;
				}
				default:
					jj_la1[17] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Identifier");
		}
	}

	/**
	 * Extracts the name of a table with its possible catalog and schema prefixes.
	 * 
	 * @return A {@link IdentifierItems} which contains at most three items: catalogName, schemaName and tableName.
	 */
	final public IdentifierItems TableName() throws ParseException{
		trace_call("TableName");
		try{
			IdentifierItems identifiers = new IdentifierItems(true);
			IdentifierItem id = null;
			id = Identifier();
			identifiers.append(id);
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case DOT:{
					jj_consume_token(DOT);
					id = Identifier();
					identifiers.append(id);
					break;
				}
				default:
					jj_la1[18] = jj_gen;;
			}
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case DOT:{
					jj_consume_token(DOT);
					id = Identifier();
					identifiers.append(id);
					break;
				}
				default:
					jj_la1[19] = jj_gen;;
			}
			{
				if ("" != null)
					return identifiers;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("TableName");
		}
	}

	/**
	 * Extracts the name of a column with its possible catalog, schema and table prefixes.
	 * 
	 * @return A {@link IdentifierItems} which contains at most four items: catalogName, schemaName, tableName and columnName.
	 */
	final public IdentifierItems ColumnName() throws ParseException{
		trace_call("ColumnName");
		try{
			IdentifierItem id;
			IdentifierItems table = null,
					identifiers = new IdentifierItems(false);
			id = Identifier();
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case DOT:{
					jj_consume_token(DOT);
					table = TableName();
					break;
				}
				default:
					jj_la1[20] = jj_gen;;
			}
			identifiers.append(id);
			if (table != null){
				for(int i = 0; i < table.size(); i++)
					identifiers.append(table.get(i));
			}
			{
				if ("" != null)
					return identifiers;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("ColumnName");
		}
	}

	final public ADQLColumn Column() throws ParseException{
		trace_call("Column");
		try{
			IdentifierItems identifiers;
			identifiers = ColumnName();
			try{
				{
					if ("" != null)
						return queryFactory.createColumn(identifiers);
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Column");
		}
	}

	final public ADQLOrder OrderItem() throws ParseException{
		trace_call("OrderItem");
		try{
			IdentifierItem identifier = null;
			Token ind = null, desc = null;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case DELIMITED_IDENTIFIER:
				case REGULAR_IDENTIFIER:{
					identifier = Identifier();
					break;
				}
				case UNSIGNED_INTEGER:{
					ind = jj_consume_token(UNSIGNED_INTEGER);
					break;
				}
				default:
					jj_la1[21] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case ASC:
				case DESC:{
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case ASC:{
							jj_consume_token(ASC);
							break;
						}
						case DESC:{
							desc = jj_consume_token(DESC);
							break;
						}
						default:
							jj_la1[22] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
					break;
				}
				default:
					jj_la1[23] = jj_gen;;
			}
			try{
				ADQLOrder order = null;
				if (identifier != null){
					order = queryFactory.createOrder(identifier, desc != null);
					order.setPosition(identifier.position);
				}else{
					order = queryFactory.createOrder(Integer.parseInt(ind.image), desc != null);
					order.setPosition(new TextPosition(ind));
				}
				{
					if ("" != null)
						return order;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("OrderItem");
		}
	}

	final public FromContent SimpleTableRef() throws ParseException{
		trace_call("SimpleTableRef");
		try{
			IdentifierItem alias = null;
			IdentifierItems identifiers = null;
			ADQLQuery subQuery = null;
			FromContent content = null;
			Token start, end;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case DELIMITED_IDENTIFIER:
					case REGULAR_IDENTIFIER:{
						identifiers = TableName();
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case AS:
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:{
								switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
									case AS:{
										jj_consume_token(AS);
										break;
									}
									default:
										jj_la1[24] = jj_gen;;
								}
								alias = Identifier();
								break;
							}
							default:
								jj_la1[25] = jj_gen;;
						}
						content = queryFactory.createTable(identifiers, alias);
						if (alias == null)
							content.setPosition(new TextPosition(identifiers.get(0).position, identifiers.get(identifiers.size() - 1).position));
						else
							content.setPosition(new TextPosition(identifiers.get(0).position, alias.position));
						{
							if ("" != null)
								return content;
						}
						break;
					}
					default:
						jj_la1[27] = jj_gen;
						if (jj_2_2(2)){
							subQuery = SubQueryExpression();
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case AS:{
									jj_consume_token(AS);
									break;
								}
								default:
									jj_la1[26] = jj_gen;;
							}
							alias = Identifier();
							content = queryFactory.createTable(subQuery, alias);
							if (alias == null)
								content.setPosition(new TextPosition(subQuery.getPosition()));
							else
								content.setPosition(new TextPosition(subQuery.getPosition(), alias.position));
							{
								if ("" != null)
									return content;
							}
						}else{
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case LEFT_PAR:{
									start = jj_consume_token(LEFT_PAR);
									content = JoinedTable();
									end = jj_consume_token(RIGHT_PAR);
									content.setPosition(new TextPosition(start, end));
									{
										if ("" != null)
											return content;
									}
									break;
								}
								default:
									jj_la1[28] = jj_gen;
									jj_consume_token(-1);
									throw new ParseException();
							}
						}
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("SimpleTableRef");
		}
	}

	final public FromContent TableRef() throws ParseException{
		trace_call("TableRef");
		try{
			FromContent content;
			content = SimpleTableRef();
			label_5: while(true){
				if (jj_2_3(2)){
					;
				}else{
					break label_5;
				}
				content = JoinSpecification(content);
			}
			{
				if ("" != null)
					return content;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("TableRef");
		}
	}

	final public FromContent JoinedTable() throws ParseException{
		trace_call("JoinedTable");
		try{
			FromContent content;
			content = SimpleTableRef();
			label_6: while(true){
				content = JoinSpecification(content);
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case NATURAL:
					case INNER:
					case RIGHT:
					case LEFT:
					case FULL:
					case JOIN:{
						;
						break;
					}
					default:
						jj_la1[29] = jj_gen;
						break label_6;
				}
			}
			{
				if ("" != null)
					return content;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("JoinedTable");
		}
	}

	final public ADQLJoin JoinSpecification(FromContent leftTable) throws ParseException{
		trace_call("JoinSpecification");
		try{
			boolean natural = false;
			JoinType type = JoinType.INNER;
			ClauseConstraints condition = new ClauseConstraints("ON");
			ArrayList<ADQLColumn> lstColumns = new ArrayList<ADQLColumn>();
			IdentifierItem id;
			FromContent rightTable;
			ADQLJoin join;
			Token lastPar;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case NATURAL:{
						jj_consume_token(NATURAL);
						natural = true;
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case INNER:
							case RIGHT:
							case LEFT:
							case FULL:{
								switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
									case INNER:{
										jj_consume_token(INNER);
										break;
									}
									case RIGHT:
									case LEFT:
									case FULL:{
										switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
											case LEFT:{
												jj_consume_token(LEFT);
												type = JoinType.OUTER_LEFT;
												break;
											}
											case RIGHT:{
												jj_consume_token(RIGHT);
												type = JoinType.OUTER_RIGHT;
												break;
											}
											case FULL:{
												jj_consume_token(FULL);
												type = JoinType.OUTER_FULL;
												break;
											}
											default:
												jj_la1[30] = jj_gen;
												jj_consume_token(-1);
												throw new ParseException();
										}
										switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
											case OUTER:{
												jj_consume_token(OUTER);
												break;
											}
											default:
												jj_la1[31] = jj_gen;;
										}
										break;
									}
									default:
										jj_la1[32] = jj_gen;
										jj_consume_token(-1);
										throw new ParseException();
								}
								break;
							}
							default:
								jj_la1[33] = jj_gen;;
						}
						jj_consume_token(JOIN);
						rightTable = SimpleTableRef();
						join = queryFactory.createJoin(type, leftTable, rightTable);
						join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition()));
						{
							if ("" != null)
								return join;
						}
						break;
					}
					case INNER:
					case RIGHT:
					case LEFT:
					case FULL:
					case JOIN:{
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case INNER:
							case RIGHT:
							case LEFT:
							case FULL:{
								switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
									case INNER:{
										jj_consume_token(INNER);
										break;
									}
									case RIGHT:
									case LEFT:
									case FULL:{
										switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
											case LEFT:{
												jj_consume_token(LEFT);
												type = JoinType.OUTER_LEFT;
												break;
											}
											case RIGHT:{
												jj_consume_token(RIGHT);
												type = JoinType.OUTER_RIGHT;
												break;
											}
											case FULL:{
												jj_consume_token(FULL);
												type = JoinType.OUTER_FULL;
												break;
											}
											default:
												jj_la1[34] = jj_gen;
												jj_consume_token(-1);
												throw new ParseException();
										}
										switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
											case OUTER:{
												jj_consume_token(OUTER);
												break;
											}
											default:
												jj_la1[35] = jj_gen;;
										}
										break;
									}
									default:
										jj_la1[36] = jj_gen;
										jj_consume_token(-1);
										throw new ParseException();
								}
								break;
							}
							default:
								jj_la1[37] = jj_gen;;
						}
						jj_consume_token(JOIN);
						rightTable = SimpleTableRef();
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case ON:{
								jj_consume_token(ON);
								ConditionsList(condition);
								join = queryFactory.createJoin(type, leftTable, rightTable, condition);
								join.setPosition(new TextPosition(leftTable.getPosition(), condition.getPosition()));
								{
									if ("" != null)
										return join;
								}
								break;
							}
							case USING:{
								jj_consume_token(USING);
								jj_consume_token(LEFT_PAR);
								id = Identifier();
								lstColumns.add(queryFactory.createColumn(id));
								label_7: while(true){
									switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
										case COMMA:{
											;
											break;
										}
										default:
											jj_la1[38] = jj_gen;
											break label_7;
									}
									jj_consume_token(COMMA);
									id = Identifier();
									lstColumns.add(queryFactory.createColumn(id));
								}
								lastPar = jj_consume_token(RIGHT_PAR);
								join = queryFactory.createJoin(type, leftTable, rightTable, lstColumns);
								join.setPosition(new TextPosition(leftTable.getPosition().beginLine, leftTable.getPosition().beginColumn, lastPar.endLine, (lastPar.endColumn < 0) ? -1 : (lastPar.endColumn + 1)));
								{
									if ("" != null)
										return join;
								}
								break;
							}
							default:
								jj_la1[39] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						break;
					}
					default:
						jj_la1[40] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("JoinSpecification");
		}
	}

	/* ****** */
	/* STRING */
	/* ****** */
	final public StringConstant String() throws ParseException{
		trace_call("String");
		try{
			Token t, start = null;
			String str = "";
			StringConstant cst;
			label_8: while(true){
				t = jj_consume_token(STRING_LITERAL);
				str += t.image.substring(1, t.image.length() - 1).replaceAll("''", "'");
				if (start == null)
					start = t;
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case STRING_LITERAL:{
						;
						break;
					}
					default:
						jj_la1[41] = jj_gen;
						break label_8;
				}
			}
			try{
				cst = queryFactory.createStringConstant(str);
				cst.setPosition(new TextPosition(start, t));
				{
					if ("" != null)
						return cst;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("String");
		}
	}

	/* ************* */
	/* NUMERIC TYPES */
	/* ************* */
	final public NumericConstant UnsignedNumeric() throws ParseException{
		trace_call("UnsignedNumeric");
		try{
			Token t;
			NumericConstant cst;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case SCIENTIFIC_NUMBER:{
					t = jj_consume_token(SCIENTIFIC_NUMBER);
					break;
				}
				case UNSIGNED_FLOAT:{
					t = jj_consume_token(UNSIGNED_FLOAT);
					break;
				}
				case UNSIGNED_INTEGER:{
					t = jj_consume_token(UNSIGNED_INTEGER);
					break;
				}
				default:
					jj_la1[42] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			try{
				cst = queryFactory.createNumericConstant(t.image);
				cst.setPosition(new TextPosition(t));
				{
					if ("" != null)
						return cst;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("UnsignedNumeric");
		}
	}

	final public NumericConstant UnsignedFloat() throws ParseException{
		trace_call("UnsignedFloat");
		try{
			Token t;
			NumericConstant cst;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case UNSIGNED_INTEGER:{
					t = jj_consume_token(UNSIGNED_INTEGER);
					break;
				}
				case UNSIGNED_FLOAT:{
					t = jj_consume_token(UNSIGNED_FLOAT);
					break;
				}
				default:
					jj_la1[43] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			try{
				cst = queryFactory.createNumericConstant(t.image);
				cst.setPosition(new TextPosition(t));
				{
					if ("" != null)
						return cst;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("UnsignedFloat");
		}
	}

	final public NumericConstant SignedInteger() throws ParseException{
		trace_call("SignedInteger");
		try{
			Token sign = null, number;
			NumericConstant cst;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case PLUS:
				case MINUS:{
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case PLUS:{
							sign = jj_consume_token(PLUS);
							break;
						}
						case MINUS:{
							sign = jj_consume_token(MINUS);
							break;
						}
						default:
							jj_la1[44] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
					break;
				}
				default:
					jj_la1[45] = jj_gen;;
			}
			number = jj_consume_token(UNSIGNED_INTEGER);
			try{
				if (sign == null){
					cst = queryFactory.createNumericConstant(number.image);
					cst.setPosition(new TextPosition(number));
				}else{
					cst = queryFactory.createNumericConstant(sign.image + number.image);
					cst.setPosition(new TextPosition(sign, number));
				}
				{
					if ("" != null)
						return cst;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("SignedInteger");
		}
	}

	/* *********** */
	/* EXPRESSIONS */
	/* *********** */
	final public ADQLOperand NumericValueExpressionPrimary() throws ParseException{
		trace_call("NumericValueExpressionPrimary");
		try{
			ADQLColumn column;
			ADQLOperand op;
			Token left, right;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case SCIENTIFIC_NUMBER:
					case UNSIGNED_FLOAT:
					case UNSIGNED_INTEGER:{
						// unsigned_value_specification
						op = UnsignedNumeric();
						{
							if ("" != null)
								return op;
						}
						break;
					}
					case DELIMITED_IDENTIFIER:
					case REGULAR_IDENTIFIER:{
						column = Column();
						column.setExpectedType('N');
						{
							if ("" != null)
								return column;
						}
						break;
					}
					case AVG:
					case MAX:
					case MIN:
					case SUM:
					case COUNT:{
						op = SqlFunction();
						{
							if ("" != null)
								return op;
						}
						break;
					}
					case LEFT_PAR:{
						left = jj_consume_token(LEFT_PAR);
						op = NumericExpression();
						right = jj_consume_token(RIGHT_PAR);
						WrappedOperand wop = queryFactory.createWrappedOperand(op);
						wop.setPosition(new TextPosition(left, right));
						{
							if ("" != null)
								return wop;
						}
						break;
					}
					default:
						jj_la1[46] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("NumericValueExpressionPrimary");
		}
	}

	final public ADQLOperand StringValueExpressionPrimary() throws ParseException{
		trace_call("StringValueExpressionPrimary");
		try{
			StringConstant expr;
			ADQLColumn column;
			ADQLOperand op;
			Token left, right;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case STRING_LITERAL:{
						// string
						expr = String();
						{
							if ("" != null)
								return expr;
						}
						break;
					}
					case SCIENTIFIC_NUMBER:
					case UNSIGNED_FLOAT:
					case UNSIGNED_INTEGER:{
						op = UnsignedNumeric();
						{
							if ("" != null)
								return op;
						}
						break;
					}
					case AVG:
					case MAX:
					case MIN:
					case SUM:
					case COUNT:{
						op = SqlFunction();
						{
							if ("" != null)
								return op;
						}
						break;
					}
					case DELIMITED_IDENTIFIER:
					case REGULAR_IDENTIFIER:{
						column = Column();
						column.setExpectedType('*');
						{
							if ("" != null)
								return column;
						}
						break;
					}
					case LEFT_PAR:{
						left = jj_consume_token(LEFT_PAR);
						op = ValueExpression();
						right = jj_consume_token(RIGHT_PAR);
						WrappedOperand wop = queryFactory.createWrappedOperand(op);
						wop.setPosition(new TextPosition(left, right));
						{
							if ("" != null)
								return wop;
						}
						break;
					}
					default:
						jj_la1[47] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("StringValueExpressionPrimary");
		}
	}

	final public ADQLOperand ValueExpression() throws ParseException{
		trace_call("ValueExpression");
		try{
			ADQLOperand valueExpr = null;
			Token left, right;
			try{
				if (jj_2_4(2147483647)){
					valueExpr = NumericExpression();
				}else if (jj_2_5(2147483647)){
					valueExpr = StringExpression();
				}else if (jj_2_6(2147483647)){
					left = jj_consume_token(LEFT_PAR);
					valueExpr = ValueExpression();
					right = jj_consume_token(RIGHT_PAR);
					valueExpr = queryFactory.createWrappedOperand(valueExpr);
					((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right));
				}else if (jj_2_7(2147483647)){
					valueExpr = UserDefinedFunction();
				}else if (jj_2_8(2)){
					valueExpr = GeometryValueFunction();
				}else if (jj_2_9(2147483647)){
					valueExpr = Column();
				}else if (jj_2_10(2147483647)){
					valueExpr = StringFactor();
				}else if (jj_2_11(3)){
					valueExpr = Factor();
				}else{
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case DELIMITED_IDENTIFIER:
						case REGULAR_IDENTIFIER:{
							valueExpr = Column();
							break;
						}
						default:
							jj_la1[48] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
				}
				{
					if ("" != null)
						return valueExpr;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("ValueExpression");
		}
	}

	final public ADQLOperand NumericExpression() throws ParseException{
		trace_call("NumericExpression");
		try{
			Token sign = null;
			ADQLOperand leftOp, rightOp = null;
			leftOp = NumericTerm();
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case PLUS:
				case MINUS:{
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case PLUS:{
							sign = jj_consume_token(PLUS);
							break;
						}
						case MINUS:{
							sign = jj_consume_token(MINUS);
							break;
						}
						default:
							jj_la1[49] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
					rightOp = NumericExpression();
					break;
				}
				default:
					jj_la1[50] = jj_gen;;
			}
			if (sign == null){
				if ("" != null)
					return leftOp;
			}else{
				try{
					Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
					operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
					{
						if ("" != null)
							return operation;
					}
				}catch(Exception ex){
					{
						if (true)
							throw generateParseException(ex);
					}
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("NumericExpression");
		}
	}

	final public ADQLOperand NumericTerm() throws ParseException{
		trace_call("NumericTerm");
		try{
			Token sign = null;
			ADQLOperand leftOp, rightOp = null;
			leftOp = Factor();
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case ASTERISK:
				case DIVIDE:{
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case ASTERISK:{
							sign = jj_consume_token(ASTERISK);
							break;
						}
						case DIVIDE:{
							sign = jj_consume_token(DIVIDE);
							break;
						}
						default:
							jj_la1[51] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
					rightOp = NumericTerm();
					break;
				}
				default:
					jj_la1[52] = jj_gen;;
			}
			if (sign == null){
				if ("" != null)
					return leftOp;
			}else{
				try{
					Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
					operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
					{
						if ("" != null)
							return operation;
					}
				}catch(Exception ex){
					{
						if (true)
							throw generateParseException(ex);
					}
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("NumericTerm");
		}
	}

	final public ADQLOperand Factor() throws ParseException{
		trace_call("Factor");
		try{
			boolean negative = false;
			Token minusSign = null;
			ADQLOperand op;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case PLUS:
				case MINUS:{
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case PLUS:{
							jj_consume_token(PLUS);
							break;
						}
						case MINUS:{
							minusSign = jj_consume_token(MINUS);
							negative = true;
							break;
						}
						default:
							jj_la1[53] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
					break;
				}
				default:
					jj_la1[54] = jj_gen;;
			}
			if (jj_2_12(2)){
				op = NumericFunction();
			}else{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case LEFT_PAR:
					case AVG:
					case MAX:
					case MIN:
					case SUM:
					case COUNT:
					case DELIMITED_IDENTIFIER:
					case REGULAR_IDENTIFIER:
					case SCIENTIFIC_NUMBER:
					case UNSIGNED_FLOAT:
					case UNSIGNED_INTEGER:{
						op = NumericValueExpressionPrimary();
						break;
					}
					default:
						jj_la1[55] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}
			if (negative){
				try{
					TextPosition position = op.getPosition();
					op = queryFactory.createNegativeOperand(op);
					NegativeOperand negativeOp = (NegativeOperand)op;
					if (minusSign != null)
						negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, position.endLine, position.endColumn));
					else
						negativeOp.setPosition(position);
				}catch(Exception ex){
					{
						if (true)
							throw generateParseException(ex);
					}
				}
			}

			{
				if ("" != null)
					return op;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Factor");
		}
	}

	final public ADQLOperand StringExpression() throws ParseException{
		trace_call("StringExpression");
		try{
			ADQLOperand leftOp;
			ADQLOperand rightOp = null;
			leftOp = StringFactor();
			label_9: while(true){
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case CONCAT:{
						;
						break;
					}
					default:
						jj_la1[56] = jj_gen;
						break label_9;
				}
				jj_consume_token(CONCAT);
				rightOp = StringFactor();
				if (!(leftOp instanceof Concatenation)){
					try{
						ADQLOperand temp = leftOp;
						leftOp = queryFactory.createConcatenation();
						((Concatenation)leftOp).add(temp);
					}catch(Exception ex){
						{
							if (true)
								throw generateParseException(ex);
						}
					}
				}
				((Concatenation)leftOp).add(rightOp);
			}
			if (leftOp instanceof Concatenation){
				Concatenation concat = (Concatenation)leftOp;
				concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size() - 1).getPosition()));
			}
			{
				if ("" != null)
					return leftOp;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("StringExpression");
		}
	}

	final public ADQLOperand StringFactor() throws ParseException{
		trace_call("StringFactor");
		try{
			ADQLOperand op;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case COORDSYS:{
					op = ExtractCoordSys();
					break;
				}
				default:
					jj_la1[57] = jj_gen;
					if (jj_2_13(2)){
						op = UserDefinedFunction();
						((UserDefinedFunction)op).setExpectedType('S');
					}else{
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case LEFT_PAR:
							case AVG:
							case MAX:
							case MIN:
							case SUM:
							case COUNT:
							case STRING_LITERAL:
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:
							case SCIENTIFIC_NUMBER:
							case UNSIGNED_FLOAT:
							case UNSIGNED_INTEGER:{
								op = StringValueExpressionPrimary();
								break;
							}
							default:
								jj_la1[58] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
					}
			}
			{
				if ("" != null)
					return op;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("StringFactor");
		}
	}

	final public GeometryValue<GeometryFunction> GeometryExpression() throws ParseException{
		trace_call("GeometryExpression");
		try{
			ADQLColumn col = null;
			GeometryFunction gf = null;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case DELIMITED_IDENTIFIER:
				case REGULAR_IDENTIFIER:{
					col = Column();
					break;
				}
				case BOX:
				case CENTROID:
				case CIRCLE:
				case POINT:
				case POLYGON:
				case REGION:{
					gf = GeometryValueFunction();
					break;
				}
				default:
					jj_la1[59] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			if (col != null){
				col.setExpectedType('G');
				{
					if ("" != null)
						return new GeometryValue<GeometryFunction>(col);
				}
			}else{
				if ("" != null)
					return new GeometryValue<GeometryFunction>(gf);
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("GeometryExpression");
		}
	}

	/* ********************************** */
	/* BOOLEAN EXPRESSIONS (WHERE clause) */
	/* ********************************** */
	final public ClauseConstraints ConditionsList(ClauseConstraints clause) throws ParseException{
		trace_call("ConditionsList");
		try{
			ADQLConstraint constraint = null;
			Token op = null;
			boolean notOp = false;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case NOT:{
						op = jj_consume_token(NOT);
						notOp = true;
						break;
					}
					default:
						jj_la1[60] = jj_gen;;
				}
				constraint = Constraint();
				if (notOp){
					TextPosition oldPos = constraint.getPosition();
					constraint = queryFactory.createNot(constraint);
					((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn));
				}
				notOp = false;

				if (clause instanceof ADQLConstraint)
					clause.add(constraint);
				else
					clause.add(constraint);
				label_10: while(true){
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case AND:
						case OR:{
							;
							break;
						}
						default:
							jj_la1[61] = jj_gen;
							break label_10;
					}
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case AND:{
							op = jj_consume_token(AND);
							break;
						}
						case OR:{
							op = jj_consume_token(OR);
							break;
						}
						default:
							jj_la1[62] = jj_gen;
							jj_consume_token(-1);
							throw new ParseException();
					}
					switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
						case NOT:{
							jj_consume_token(NOT);
							notOp = true;
							break;
						}
						default:
							jj_la1[63] = jj_gen;;
					}
					constraint = Constraint();
					if (notOp){
						TextPosition oldPos = constraint.getPosition();
						constraint = queryFactory.createNot(constraint);
						((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn));
					}
					notOp = false;

					if (clause instanceof ADQLConstraint)
						clause.add(op.image, constraint);
					else
						clause.add(op.image, constraint);
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			if (!clause.isEmpty()){
				TextPosition start = clause.get(0).getPosition();
				TextPosition end = clause.get(clause.size() - 1).getPosition();
				clause.setPosition(new TextPosition(start, end));
			}
			{
				if ("" != null)
					return clause;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("ConditionsList");
		}
	}

	final public ADQLConstraint Constraint() throws ParseException{
		trace_call("Constraint");
		try{
			ADQLConstraint constraint = null;
			Token start, end;
			if (jj_2_14(2147483647)){
				constraint = Predicate();
			}else{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case LEFT_PAR:{
						start = jj_consume_token(LEFT_PAR);
						try{
							constraint = queryFactory.createGroupOfConstraints();
						}catch(Exception ex){
							{
								if (true)
									throw generateParseException(ex);
							}
						}
						ConditionsList((ConstraintsGroup)constraint);
						end = jj_consume_token(RIGHT_PAR);
						((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end));
						break;
					}
					default:
						jj_la1[64] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}
			{
				if ("" != null)
					return constraint;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Constraint");
		}
	}

	final public ADQLConstraint Predicate() throws ParseException{
		trace_call("Predicate");
		try{
			ADQLQuery q = null;
			ADQLColumn column = null;
			ADQLOperand strExpr1 = null, strExpr2 = null;
			ADQLOperand op;
			Token start, notToken = null, end;
			ADQLConstraint constraint = null;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case EXISTS:{
						start = jj_consume_token(EXISTS);
						q = SubQueryExpression();
						Exists e = queryFactory.createExists(q);
						e.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));
						{
							if ("" != null)
								return e;
						}
						break;
					}
					default:
						jj_la1[69] = jj_gen;
						if (jj_2_16(2147483647)){
							column = Column();
							jj_consume_token(IS);
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case NOT:{
									notToken = jj_consume_token(NOT);
									break;
								}
								default:
									jj_la1[65] = jj_gen;;
							}
							end = jj_consume_token(NULL);
							IsNull in = queryFactory.createIsNull((notToken != null), column);
							in.setPosition(new TextPosition(column.getPosition().beginLine, column.getPosition().beginColumn, end.endLine, (end.endColumn < 0) ? -1 : (end.endColumn + 1)));
							{
								if ("" != null)
									return in;
							}
						}else if (jj_2_17(2147483647)){
							strExpr1 = StringExpression();
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case NOT:{
									notToken = jj_consume_token(NOT);
									break;
								}
								default:
									jj_la1[66] = jj_gen;;
							}
							jj_consume_token(LIKE);
							strExpr2 = StringExpression();
							Comparison comp = queryFactory.createComparison(strExpr1, (notToken == null) ? ComparisonOperator.LIKE : ComparisonOperator.NOTLIKE, strExpr2);
							comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition()));
							{
								if ("" != null)
									return comp;
							}
						}else{
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case LEFT_PAR:
								case PLUS:
								case MINUS:
								case AVG:
								case MAX:
								case MIN:
								case SUM:
								case COUNT:
								case BOX:
								case CENTROID:
								case CIRCLE:
								case POINT:
								case POLYGON:
								case REGION:
								case CONTAINS:
								case INTERSECTS:
								case AREA:
								case COORD1:
								case COORD2:
								case COORDSYS:
								case DISTANCE:
								case ABS:
								case CEILING:
								case DEGREES:
								case EXP:
								case FLOOR:
								case LOG:
								case LOG10:
								case MOD:
								case PI:
								case POWER:
								case RADIANS:
								case RAND:
								case ROUND:
								case SQRT:
								case TRUNCATE:
								case ACOS:
								case ASIN:
								case ATAN:
								case ATAN2:
								case COS:
								case COT:
								case SIN:
								case TAN:
								case STRING_LITERAL:
								case DELIMITED_IDENTIFIER:
								case REGULAR_IDENTIFIER:
								case SCIENTIFIC_NUMBER:
								case UNSIGNED_FLOAT:
								case UNSIGNED_INTEGER:{
									op = ValueExpression();
									switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
										case EQUAL:
										case NOT_EQUAL:
										case LESS_THAN:
										case LESS_EQUAL_THAN:
										case GREATER_THAN:
										case GREATER_EQUAL_THAN:{
											constraint = ComparisonEnd(op);
											break;
										}
										default:
											jj_la1[67] = jj_gen;
											if (jj_2_15(2)){
												constraint = BetweenEnd(op);
											}else{
												switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
													case NOT:
													case IN:{
														constraint = InEnd(op);
														break;
													}
													default:
														jj_la1[68] = jj_gen;
														jj_consume_token(-1);
														throw new ParseException();
												}
											}
									}
									break;
								}
								default:
									jj_la1[70] = jj_gen;
									jj_consume_token(-1);
									throw new ParseException();
							}
						}
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			{
				if ("" != null)
					return constraint;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Predicate");
		}
	}

	final public Comparison ComparisonEnd(ADQLOperand leftOp) throws ParseException{
		trace_call("ComparisonEnd");
		try{
			Token comp;
			ADQLOperand rightOp;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case EQUAL:{
					comp = jj_consume_token(EQUAL);
					break;
				}
				case NOT_EQUAL:{
					comp = jj_consume_token(NOT_EQUAL);
					break;
				}
				case LESS_THAN:{
					comp = jj_consume_token(LESS_THAN);
					break;
				}
				case LESS_EQUAL_THAN:{
					comp = jj_consume_token(LESS_EQUAL_THAN);
					break;
				}
				case GREATER_THAN:{
					comp = jj_consume_token(GREATER_THAN);
					break;
				}
				case GREATER_EQUAL_THAN:{
					comp = jj_consume_token(GREATER_EQUAL_THAN);
					break;
				}
				default:
					jj_la1[71] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			rightOp = ValueExpression();
			try{
				Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
				comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
				{
					if ("" != null)
						return comparison;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("ComparisonEnd");
		}
	}

	final public Between BetweenEnd(ADQLOperand leftOp) throws ParseException{
		trace_call("BetweenEnd");
		try{
			Token start, notToken = null;
			ADQLOperand min, max;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case NOT:{
					notToken = jj_consume_token(NOT);
					break;
				}
				default:
					jj_la1[72] = jj_gen;;
			}
			start = jj_consume_token(BETWEEN);
			min = ValueExpression();
			jj_consume_token(AND);
			max = ValueExpression();
			try{
				Between bet = queryFactory.createBetween((notToken != null), leftOp, min, max);
				if (notToken != null)
					start = notToken;
				bet.setPosition(new TextPosition(start.beginLine, start.beginColumn, max.getPosition().endLine, max.getPosition().endColumn));
				{
					if ("" != null)
						return bet;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("BetweenEnd");
		}
	}

	final public In InEnd(ADQLOperand leftOp) throws ParseException{
		trace_call("InEnd");
		try{
			Token not = null, start;
			ADQLQuery q = null;
			ADQLOperand item;
			Vector<ADQLOperand> items = new Vector<ADQLOperand>();
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case NOT:{
					not = jj_consume_token(NOT);
					break;
				}
				default:
					jj_la1[73] = jj_gen;;
			}
			start = jj_consume_token(IN);
			if (jj_2_18(2)){
				q = SubQueryExpression();
			}else{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case LEFT_PAR:{
						jj_consume_token(LEFT_PAR);
						item = ValueExpression();
						items.add(item);
						label_11: while(true){
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case COMMA:{
									;
									break;
								}
								default:
									jj_la1[74] = jj_gen;
									break label_11;
							}
							jj_consume_token(COMMA);
							item = ValueExpression();
							items.add(item);
						}
						jj_consume_token(RIGHT_PAR);
						break;
					}
					default:
						jj_la1[75] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}
			try{
				In in;
				start = (not != null) ? not : start;
				if (q != null){
					in = queryFactory.createIn(leftOp, q, not != null);
					in.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));
				}else{
					ADQLOperand[] list = new ADQLOperand[items.size()];
					int i = 0;
					for(ADQLOperand op : items)
						list[i++] = op;
					in = queryFactory.createIn(leftOp, list, not != null);
					in.setPosition(new TextPosition(start.beginLine, start.beginColumn, list[list.length - 1].getPosition().endLine, list[list.length - 1].getPosition().endColumn));
				}
				{
					if ("" != null)
						return in;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("InEnd");
		}
	}

	/* ************* */
	/* SQL FUNCTIONS */
	/* ************* */
	final public SQLFunction SqlFunction() throws ParseException{
		trace_call("SqlFunction");
		try{
			Token fct, all = null, distinct = null, end;
			ADQLOperand op = null;
			SQLFunction funct = null;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case COUNT:{
						fct = jj_consume_token(COUNT);
						jj_consume_token(LEFT_PAR);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case QUANTIFIER:{
								distinct = jj_consume_token(QUANTIFIER);
								break;
							}
							default:
								jj_la1[76] = jj_gen;;
						}
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case ASTERISK:{
								all = jj_consume_token(ASTERISK);
								break;
							}
							case LEFT_PAR:
							case PLUS:
							case MINUS:
							case AVG:
							case MAX:
							case MIN:
							case SUM:
							case COUNT:
							case BOX:
							case CENTROID:
							case CIRCLE:
							case POINT:
							case POLYGON:
							case REGION:
							case CONTAINS:
							case INTERSECTS:
							case AREA:
							case COORD1:
							case COORD2:
							case COORDSYS:
							case DISTANCE:
							case ABS:
							case CEILING:
							case DEGREES:
							case EXP:
							case FLOOR:
							case LOG:
							case LOG10:
							case MOD:
							case PI:
							case POWER:
							case RADIANS:
							case RAND:
							case ROUND:
							case SQRT:
							case TRUNCATE:
							case ACOS:
							case ASIN:
							case ATAN:
							case ATAN2:
							case COS:
							case COT:
							case SIN:
							case TAN:
							case STRING_LITERAL:
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:
							case SCIENTIFIC_NUMBER:
							case UNSIGNED_FLOAT:
							case UNSIGNED_INTEGER:{
								op = ValueExpression();
								break;
							}
							default:
								jj_la1[77] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						end = jj_consume_token(RIGHT_PAR);
						funct = queryFactory.createSQLFunction((all != null) ? SQLFunctionType.COUNT_ALL : SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
						funct.setPosition(new TextPosition(fct, end));
						break;
					}
					case AVG:
					case MAX:
					case MIN:
					case SUM:{
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case AVG:{
								fct = jj_consume_token(AVG);
								break;
							}
							case MAX:{
								fct = jj_consume_token(MAX);
								break;
							}
							case MIN:{
								fct = jj_consume_token(MIN);
								break;
							}
							case SUM:{
								fct = jj_consume_token(SUM);
								break;
							}
							default:
								jj_la1[78] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						jj_consume_token(LEFT_PAR);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case QUANTIFIER:{
								distinct = jj_consume_token(QUANTIFIER);
								break;
							}
							default:
								jj_la1[79] = jj_gen;;
						}
						op = ValueExpression();
						end = jj_consume_token(RIGHT_PAR);
						funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
						funct.setPosition(new TextPosition(fct, end));
						break;
					}
					default:
						jj_la1[80] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			{
				if ("" != null)
					return funct;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("SqlFunction");
		}
	}

	/* ************** */
	/* ADQL FUNCTIONS */
	/* ************** */
	final public ADQLOperand[] Coordinates() throws ParseException{
		trace_call("Coordinates");
		try{
			ADQLOperand[] ops = new ADQLOperand[2];
			ops[0] = NumericExpression();
			jj_consume_token(COMMA);
			ops[1] = NumericExpression();
			{
				if ("" != null)
					return ops;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Coordinates");
		}
	}

	final public GeometryFunction GeometryFunction() throws ParseException{
		trace_call("GeometryFunction");
		try{
			Token fct = null, end;
			GeometryValue<GeometryFunction> gvf1, gvf2;
			GeometryValue<PointFunction> gvp1, gvp2;
			GeometryFunction gf = null;
			PointFunction p1 = null, p2 = null;
			ADQLColumn col1 = null, col2 = null;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case CONTAINS:
					case INTERSECTS:{
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case CONTAINS:{
								fct = jj_consume_token(CONTAINS);
								break;
							}
							case INTERSECTS:{
								fct = jj_consume_token(INTERSECTS);
								break;
							}
							default:
								jj_la1[81] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						jj_consume_token(LEFT_PAR);
						gvf1 = GeometryExpression();
						jj_consume_token(COMMA);
						gvf2 = GeometryExpression();
						end = jj_consume_token(RIGHT_PAR);
						if (fct.image.equalsIgnoreCase("contains"))
							gf = queryFactory.createContains(gvf1, gvf2);
						else
							gf = queryFactory.createIntersects(gvf1, gvf2);
						break;
					}
					case AREA:{
						fct = jj_consume_token(AREA);
						jj_consume_token(LEFT_PAR);
						gvf1 = GeometryExpression();
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createArea(gvf1);
						break;
					}
					case COORD1:{
						fct = jj_consume_token(COORD1);
						jj_consume_token(LEFT_PAR);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case POINT:{
								p1 = Point();
								gf = queryFactory.createCoord1(p1);
								break;
							}
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:{
								col1 = Column();
								col1.setExpectedType('G');
								gf = queryFactory.createCoord1(col1);
								break;
							}
							default:
								jj_la1[82] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case COORD2:{
						fct = jj_consume_token(COORD2);
						jj_consume_token(LEFT_PAR);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case POINT:{
								p1 = Point();
								gf = queryFactory.createCoord2(p1);
								break;
							}
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:{
								col1 = Column();
								col1.setExpectedType('G');
								gf = queryFactory.createCoord2(col1);
								break;
							}
							default:
								jj_la1[83] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case DISTANCE:{
						fct = jj_consume_token(DISTANCE);
						jj_consume_token(LEFT_PAR);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case POINT:{
								p1 = Point();
								break;
							}
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:{
								col1 = Column();
								break;
							}
							default:
								jj_la1[84] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						if (p1 != null)
							gvp1 = new GeometryValue<PointFunction>(p1);
						else{
							col1.setExpectedType('G');
							gvp1 = new GeometryValue<PointFunction>(col1);
						}
						jj_consume_token(COMMA);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case POINT:{
								p2 = Point();
								break;
							}
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:{
								col2 = Column();
								break;
							}
							default:
								jj_la1[85] = jj_gen;
								jj_consume_token(-1);
								throw new ParseException();
						}
						if (p2 != null)
							gvp2 = new GeometryValue<PointFunction>(p2);
						else{
							col2.setExpectedType('G');
							gvp2 = new GeometryValue<PointFunction>(col2);
						}
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createDistance(gvp1, gvp2);
						break;
					}
					default:
						jj_la1[86] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			gf.setPosition(new TextPosition(fct, end));
			{
				if ("" != null)
					return gf;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("GeometryFunction");
		}
	}

	final public ADQLOperand CoordinateSystem() throws ParseException{
		trace_call("CoordinateSystem");
		try{
			ADQLOperand coordSys = null;
			coordSys = StringExpression();
			{
				if ("" != null)
					return coordSys;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("CoordinateSystem");
		}
	}

	final public GeometryFunction GeometryValueFunction() throws ParseException{
		trace_call("GeometryValueFunction");
		try{
			Token fct = null, end = null;
			ADQLOperand coordSys;
			ADQLOperand width, height;
			ADQLOperand[] coords, tmp;
			Vector<ADQLOperand> vCoords;
			ADQLOperand op = null;
			GeometryValue<GeometryFunction> gvf = null;
			GeometryFunction gf = null;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case BOX:{
						fct = jj_consume_token(BOX);
						jj_consume_token(LEFT_PAR);
						coordSys = CoordinateSystem();
						jj_consume_token(COMMA);
						coords = Coordinates();
						jj_consume_token(COMMA);
						width = NumericExpression();
						jj_consume_token(COMMA);
						height = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);
						break;
					}
					case CENTROID:{
						fct = jj_consume_token(CENTROID);
						jj_consume_token(LEFT_PAR);
						gvf = GeometryExpression();
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createCentroid(gvf);
						break;
					}
					case CIRCLE:{
						fct = jj_consume_token(CIRCLE);
						jj_consume_token(LEFT_PAR);
						coordSys = CoordinateSystem();
						jj_consume_token(COMMA);
						coords = Coordinates();
						jj_consume_token(COMMA);
						width = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);
						break;
					}
					case POINT:{
						gf = Point();
						break;
					}
					case POLYGON:{
						fct = jj_consume_token(POLYGON);
						jj_consume_token(LEFT_PAR);
						coordSys = CoordinateSystem();
						vCoords = new Vector<ADQLOperand>();
						jj_consume_token(COMMA);
						tmp = Coordinates();
						vCoords.add(tmp[0]);
						vCoords.add(tmp[1]);
						jj_consume_token(COMMA);
						tmp = Coordinates();
						vCoords.add(tmp[0]);
						vCoords.add(tmp[1]);
						jj_consume_token(COMMA);
						tmp = Coordinates();
						vCoords.add(tmp[0]);
						vCoords.add(tmp[1]);
						label_12: while(true){
							switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
								case COMMA:{
									;
									break;
								}
								default:
									jj_la1[87] = jj_gen;
									break label_12;
							}
							jj_consume_token(COMMA);
							tmp = Coordinates();
							vCoords.add(tmp[0]);
							vCoords.add(tmp[1]);
						}
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createPolygon(coordSys, vCoords);
						break;
					}
					case REGION:{
						fct = jj_consume_token(REGION);
						jj_consume_token(LEFT_PAR);
						op = StringExpression();
						end = jj_consume_token(RIGHT_PAR);
						gf = queryFactory.createRegion(op);
						break;
					}
					default:
						jj_la1[88] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			if (fct != null && end != null) // = !(gf instanceof Point)
				gf.setPosition(new TextPosition(fct, end));
			{
				if ("" != null)
					return gf;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("GeometryValueFunction");
		}
	}

	final public PointFunction Point() throws ParseException{
		trace_call("Point");
		try{
			Token start, end;
			ADQLOperand coordSys;
			ADQLOperand[] coords;
			start = jj_consume_token(POINT);
			jj_consume_token(LEFT_PAR);
			coordSys = CoordinateSystem();
			jj_consume_token(COMMA);
			coords = Coordinates();
			end = jj_consume_token(RIGHT_PAR);
			try{
				PointFunction pf = queryFactory.createPoint(coordSys, coords[0], coords[1]);
				pf.setPosition(new TextPosition(start, end));
				{
					if ("" != null)
						return pf;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("Point");
		}
	}

	final public GeometryFunction ExtractCoordSys() throws ParseException{
		trace_call("ExtractCoordSys");
		try{
			Token start, end;
			GeometryValue<GeometryFunction> gvf;
			start = jj_consume_token(COORDSYS);
			jj_consume_token(LEFT_PAR);
			gvf = GeometryExpression();
			end = jj_consume_token(RIGHT_PAR);
			try{
				GeometryFunction gf = queryFactory.createExtractCoordSys(gvf);
				gf.setPosition(new TextPosition(start, end));
				{
					if ("" != null)
						return gf;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("ExtractCoordSys");
		}
	}

	/* ***************** */
	/* NUMERIC FUNCTIONS */
	/* ***************** */
	final public ADQLFunction NumericFunction() throws ParseException{
		trace_call("NumericFunction");
		try{
			ADQLFunction fct;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case ABS:
				case CEILING:
				case DEGREES:
				case EXP:
				case FLOOR:
				case LOG:
				case LOG10:
				case MOD:
				case PI:
				case POWER:
				case RADIANS:
				case RAND:
				case ROUND:
				case SQRT:
				case TRUNCATE:{
					fct = MathFunction();
					break;
				}
				case ACOS:
				case ASIN:
				case ATAN:
				case ATAN2:
				case COS:
				case COT:
				case SIN:
				case TAN:{
					fct = TrigFunction();
					break;
				}
				case CONTAINS:
				case INTERSECTS:
				case AREA:
				case COORD1:
				case COORD2:
				case DISTANCE:{
					fct = GeometryFunction();
					break;
				}
				case REGULAR_IDENTIFIER:{
					fct = UserDefinedFunction();
					((UserDefinedFunction)fct).setExpectedType('N');
					break;
				}
				default:
					jj_la1[89] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			{
				if ("" != null)
					return fct;
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("NumericFunction");
		}
	}

	final public MathFunction MathFunction() throws ParseException{
		trace_call("MathFunction");
		try{
			Token fct = null, end;
			ADQLOperand param1 = null, param2 = null;
			NumericConstant integerValue = null;
			try{
				switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
					case ABS:{
						fct = jj_consume_token(ABS);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case CEILING:{
						fct = jj_consume_token(CEILING);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case DEGREES:{
						fct = jj_consume_token(DEGREES);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case EXP:{
						fct = jj_consume_token(EXP);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case FLOOR:{
						fct = jj_consume_token(FLOOR);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case LOG:{
						fct = jj_consume_token(LOG);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case LOG10:{
						fct = jj_consume_token(LOG10);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case MOD:{
						fct = jj_consume_token(MOD);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						jj_consume_token(COMMA);
						param2 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case PI:{
						fct = jj_consume_token(PI);
						jj_consume_token(LEFT_PAR);
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case POWER:{
						fct = jj_consume_token(POWER);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						jj_consume_token(COMMA);
						param2 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case RADIANS:{
						fct = jj_consume_token(RADIANS);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case RAND:{
						fct = jj_consume_token(RAND);
						jj_consume_token(LEFT_PAR);
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case LEFT_PAR:
							case PLUS:
							case MINUS:
							case AVG:
							case MAX:
							case MIN:
							case SUM:
							case COUNT:
							case CONTAINS:
							case INTERSECTS:
							case AREA:
							case COORD1:
							case COORD2:
							case DISTANCE:
							case ABS:
							case CEILING:
							case DEGREES:
							case EXP:
							case FLOOR:
							case LOG:
							case LOG10:
							case MOD:
							case PI:
							case POWER:
							case RADIANS:
							case RAND:
							case ROUND:
							case SQRT:
							case TRUNCATE:
							case ACOS:
							case ASIN:
							case ATAN:
							case ATAN2:
							case COS:
							case COT:
							case SIN:
							case TAN:
							case DELIMITED_IDENTIFIER:
							case REGULAR_IDENTIFIER:
							case SCIENTIFIC_NUMBER:
							case UNSIGNED_FLOAT:
							case UNSIGNED_INTEGER:{
								param1 = NumericExpression();
								break;
							}
							default:
								jj_la1[90] = jj_gen;;
						}
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case ROUND:{
						fct = jj_consume_token(ROUND);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case COMMA:{
								jj_consume_token(COMMA);
								param2 = SignedInteger();
								break;
							}
							default:
								jj_la1[91] = jj_gen;;
						}
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case SQRT:{
						fct = jj_consume_token(SQRT);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					case TRUNCATE:{
						fct = jj_consume_token(TRUNCATE);
						jj_consume_token(LEFT_PAR);
						param1 = NumericExpression();
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case COMMA:{
								jj_consume_token(COMMA);
								param2 = SignedInteger();
								break;
							}
							default:
								jj_la1[92] = jj_gen;;
						}
						end = jj_consume_token(RIGHT_PAR);
						break;
					}
					default:
						jj_la1[93] = jj_gen;
						jj_consume_token(-1);
						throw new ParseException();
				}
				MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
				mf.setPosition(new TextPosition(fct, end));
				{
					if ("" != null)
						return mf;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("MathFunction");
		}
	}

	final public MathFunction TrigFunction() throws ParseException{
		trace_call("TrigFunction");
		try{
			Token fct = null, end;
			ADQLOperand param1 = null, param2 = null;
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case ACOS:{
					fct = jj_consume_token(ACOS);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case ASIN:{
					fct = jj_consume_token(ASIN);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case ATAN:{
					fct = jj_consume_token(ATAN);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case ATAN2:{
					fct = jj_consume_token(ATAN2);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					jj_consume_token(COMMA);
					param2 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case COS:{
					fct = jj_consume_token(COS);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case COT:{
					fct = jj_consume_token(COT);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case SIN:{
					fct = jj_consume_token(SIN);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				case TAN:{
					fct = jj_consume_token(TAN);
					jj_consume_token(LEFT_PAR);
					param1 = NumericExpression();
					end = jj_consume_token(RIGHT_PAR);
					break;
				}
				default:
					jj_la1[94] = jj_gen;
					jj_consume_token(-1);
					throw new ParseException();
			}
			try{
				MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
				mf.setPosition(new TextPosition(fct, end));
				{
					if ("" != null)
						return mf;
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("TrigFunction");
		}
	}

	final public UserDefinedFunction UserDefinedFunction() throws ParseException{
		trace_call("UserDefinedFunction");
		try{
			Token fct, end;
			Vector<ADQLOperand> params = new Vector<ADQLOperand>();
			ADQLOperand op;
			fct = jj_consume_token(REGULAR_IDENTIFIER);
			jj_consume_token(LEFT_PAR);
			switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
				case LEFT_PAR:
				case PLUS:
				case MINUS:
				case AVG:
				case MAX:
				case MIN:
				case SUM:
				case COUNT:
				case BOX:
				case CENTROID:
				case CIRCLE:
				case POINT:
				case POLYGON:
				case REGION:
				case CONTAINS:
				case INTERSECTS:
				case AREA:
				case COORD1:
				case COORD2:
				case COORDSYS:
				case DISTANCE:
				case ABS:
				case CEILING:
				case DEGREES:
				case EXP:
				case FLOOR:
				case LOG:
				case LOG10:
				case MOD:
				case PI:
				case POWER:
				case RADIANS:
				case RAND:
				case ROUND:
				case SQRT:
				case TRUNCATE:
				case ACOS:
				case ASIN:
				case ATAN:
				case ATAN2:
				case COS:
				case COT:
				case SIN:
				case TAN:
				case STRING_LITERAL:
				case DELIMITED_IDENTIFIER:
				case REGULAR_IDENTIFIER:
				case SCIENTIFIC_NUMBER:
				case UNSIGNED_FLOAT:
				case UNSIGNED_INTEGER:{
					op = ValueExpression();
					params.add(op);
					label_13: while(true){
						switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){
							case COMMA:{
								;
								break;
							}
							default:
								jj_la1[95] = jj_gen;
								break label_13;
						}
						jj_consume_token(COMMA);
						op = ValueExpression();
						params.add(op);
					}
					break;
				}
				default:
					jj_la1[96] = jj_gen;;
			}
			end = jj_consume_token(RIGHT_PAR);
			//System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !");
			try{
				//  Build the parameters list:
				ADQLOperand[] parameters = new ADQLOperand[params.size()];
				for(int i = 0; i < params.size(); i++)
					parameters[i] = params.get(i);
				// Create the UDF function:
				UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters);
				udf.setPosition(new TextPosition(fct, end));
				{
					if ("" != null)
						return udf;
				}
			}catch(UnsupportedOperationException uoe){
				/* This catch clause is just for backward compatibility:
				* if the createUserDefinedFunction(...) is overridden and
				* the function can not be identified a such exception may be thrown). */
				{
					if (true)
						throw new ParseException(uoe.getMessage(), new TextPosition(fct, token));
				}
			}catch(Exception ex){
				{
					if (true)
						throw generateParseException(ex);
				}
			}
			throw new Error("Missing return statement in function");
		}finally{
			trace_return("UserDefinedFunction");
		}
	}

	private boolean jj_2_1(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_1();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(0, xla);
		}
	}

	private boolean jj_2_2(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_2();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(1, xla);
		}
	}

	private boolean jj_2_3(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_3();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(2, xla);
		}
	}

	private boolean jj_2_4(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_4();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(3, xla);
		}
	}

	private boolean jj_2_5(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_5();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(4, xla);
		}
	}

	private boolean jj_2_6(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_6();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(5, xla);
		}
	}

	private boolean jj_2_7(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_7();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(6, xla);
		}
	}

	private boolean jj_2_8(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_8();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(7, xla);
		}
	}

	private boolean jj_2_9(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_9();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(8, xla);
		}
	}

	private boolean jj_2_10(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_10();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(9, xla);
		}
	}

	private boolean jj_2_11(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_11();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(10, xla);
		}
	}

	private boolean jj_2_12(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_12();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(11, xla);
		}
	}

	private boolean jj_2_13(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_13();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(12, xla);
		}
	}

	private boolean jj_2_14(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_14();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(13, xla);
		}
	}

	private boolean jj_2_15(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_15();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(14, xla);
		}
	}

	private boolean jj_2_16(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_16();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(15, xla);
		}
	}

	private boolean jj_2_17(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_17();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(16, xla);
		}
	}

	private boolean jj_2_18(int xla){
		jj_la = xla;
		jj_lastpos = jj_scanpos = token;
		try{
			return !jj_3_18();
		}catch(LookaheadSuccess ls){
			return true;
		}finally{
			jj_save(17, xla);
		}
	}

	private boolean jj_3R_128(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(99)){
			jj_scanpos = xsp;
			if (jj_scan_token(100)){
				jj_scanpos = xsp;
				if (jj_scan_token(101))
					return true;
			}
		}
		return false;
	}

	private boolean jj_3R_129(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_135()){
			jj_scanpos = xsp;
			if (jj_3R_136())
				return true;
		}
		return false;
	}

	private boolean jj_3R_113(){
		if (jj_scan_token(LEFT))
			return true;
		return false;
	}

	private boolean jj_3R_73(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_113()){
			jj_scanpos = xsp;
			if (jj_3R_114()){
				jj_scanpos = xsp;
				if (jj_3R_115())
					return true;
			}
		}
		return false;
	}

	private boolean jj_3R_54(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(25)){
			jj_scanpos = xsp;
			if (jj_3R_73())
				return true;
		}
		return false;
	}

	private boolean jj_3R_44(){
		if (jj_scan_token(STRING_LITERAL))
			return true;
		return false;
	}

	private boolean jj_3R_23(){
		Token xsp;
		if (jj_3R_44())
			return true;
		while(true){
			xsp = jj_scanpos;
			if (jj_3R_44()){
				jj_scanpos = xsp;
				break;
			}
		}
		return false;
	}

	private boolean jj_3R_116(){
		if (jj_scan_token(LEFT))
			return true;
		return false;
	}

	private boolean jj_3R_74(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_116()){
			jj_scanpos = xsp;
			if (jj_3R_117()){
				jj_scanpos = xsp;
				if (jj_3R_118())
					return true;
			}
		}
		xsp = jj_scanpos;
		if (jj_scan_token(26))
			jj_scanpos = xsp;
		return false;
	}

	private boolean jj_3_18(){
		if (jj_3R_16())
			return true;
		return false;
	}

	private boolean jj_3R_55(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(25)){
			jj_scanpos = xsp;
			if (jj_3R_74())
				return true;
		}
		return false;
	}

	private boolean jj_3R_35(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_55())
			jj_scanpos = xsp;
		if (jj_scan_token(JOIN))
			return true;
		if (jj_3R_56())
			return true;
		return false;
	}

	private boolean jj_3R_34(){
		if (jj_scan_token(NATURAL))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_54())
			jj_scanpos = xsp;
		if (jj_scan_token(JOIN))
			return true;
		return false;
	}

	private boolean jj_3R_28(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(36))
			jj_scanpos = xsp;
		if (jj_scan_token(BETWEEN))
			return true;
		if (jj_3R_51())
			return true;
		return false;
	}

	private boolean jj_3_15(){
		if (jj_3R_28())
			return true;
		return false;
	}

	private boolean jj_3R_17(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_34()){
			jj_scanpos = xsp;
			if (jj_3R_35())
				return true;
		}
		return false;
	}

	private boolean jj_3_17(){
		if (jj_3R_29())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(36))
			jj_scanpos = xsp;
		if (jj_scan_token(LIKE))
			return true;
		return false;
	}

	private boolean jj_3R_76(){
		if (jj_scan_token(LEFT_PAR))
			return true;
		return false;
	}

	private boolean jj_3_3(){
		if (jj_3R_17())
			return true;
		return false;
	}

	private boolean jj_3_16(){
		if (jj_3R_22())
			return true;
		if (jj_scan_token(IS))
			return true;
		return false;
	}

	private boolean jj_3_2(){
		if (jj_3R_16())
			return true;
		return false;
	}

	private boolean jj_3R_75(){
		if (jj_3R_79())
			return true;
		return false;
	}

	private boolean jj_3R_134(){
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_51())
			return true;
		return false;
	}

	private boolean jj_3R_27(){
		if (jj_3R_51())
			return true;
		return false;
	}

	private boolean jj_3R_56(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_75()){
			jj_scanpos = xsp;
			if (jj_3_2()){
				jj_scanpos = xsp;
				if (jj_3R_76())
					return true;
			}
		}
		return false;
	}

	private boolean jj_3_14(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(42)){
			jj_scanpos = xsp;
			if (jj_3R_27())
				return true;
		}
		return false;
	}

	private boolean jj_3R_60(){
		if (jj_scan_token(DOT))
			return true;
		if (jj_3R_79())
			return true;
		return false;
	}

	private boolean jj_3R_120(){
		if (jj_3R_51())
			return true;
		Token xsp;
		while(true){
			xsp = jj_scanpos;
			if (jj_3R_134()){
				jj_scanpos = xsp;
				break;
			}
		}
		return false;
	}

	private boolean jj_3R_22(){
		if (jj_3R_43())
			return true;
		return false;
	}

	private boolean jj_3R_150(){
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_153())
			return true;
		return false;
	}

	private boolean jj_3R_149(){
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_153())
			return true;
		return false;
	}

	private boolean jj_3R_43(){
		if (jj_3R_14())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_60())
			jj_scanpos = xsp;
		return false;
	}

	private boolean jj_3R_127(){
		if (jj_scan_token(DOT))
			return true;
		if (jj_3R_14())
			return true;
		return false;
	}

	private boolean jj_3R_126(){
		if (jj_scan_token(DOT))
			return true;
		if (jj_3R_14())
			return true;
		return false;
	}

	private boolean jj_3R_79(){
		if (jj_3R_14())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_126())
			jj_scanpos = xsp;
		xsp = jj_scanpos;
		if (jj_3R_127())
			jj_scanpos = xsp;
		return false;
	}

	private boolean jj_3R_31(){
		if (jj_scan_token(DELIMITED_IDENTIFIER))
			return true;
		return false;
	}

	private boolean jj_3R_133(){
		if (jj_3R_21())
			return true;
		return false;
	}

	private boolean jj_3R_30(){
		if (jj_scan_token(REGULAR_IDENTIFIER))
			return true;
		return false;
	}

	private boolean jj_3R_26(){
		if (jj_scan_token(REGULAR_IDENTIFIER))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_120())
			jj_scanpos = xsp;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_141(){
		if (jj_3R_112())
			return true;
		return false;
	}

	private boolean jj_3R_14(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_30()){
			jj_scanpos = xsp;
			if (jj_3R_31())
				return true;
		}
		return false;
	}

	private boolean jj_3R_132(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_119(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_132()){
			jj_scanpos = xsp;
			if (jj_3R_133())
				return true;
		}
		return false;
	}

	private boolean jj_3R_106(){
		if (jj_scan_token(TAN))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_105(){
		if (jj_scan_token(SIN))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_104(){
		if (jj_scan_token(COT))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_58(){
		if (jj_3R_78())
			return true;
		return false;
	}

	private boolean jj_3_13(){
		if (jj_3R_26())
			return true;
		return false;
	}

	private boolean jj_3R_103(){
		if (jj_scan_token(COS))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_102(){
		if (jj_scan_token(ATAN2))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_57(){
		if (jj_3R_77())
			return true;
		return false;
	}

	private boolean jj_3R_101(){
		if (jj_scan_token(ATAN))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_36(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_57()){
			jj_scanpos = xsp;
			if (jj_3_13()){
				jj_scanpos = xsp;
				if (jj_3R_58())
					return true;
			}
		}
		return false;
	}

	private boolean jj_3R_100(){
		if (jj_scan_token(ASIN))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_99(){
		if (jj_scan_token(ACOS))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_64(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_99()){
			jj_scanpos = xsp;
			if (jj_3R_100()){
				jj_scanpos = xsp;
				if (jj_3R_101()){
					jj_scanpos = xsp;
					if (jj_3R_102()){
						jj_scanpos = xsp;
						if (jj_3R_103()){
							jj_scanpos = xsp;
							if (jj_3R_104()){
								jj_scanpos = xsp;
								if (jj_3R_105()){
									jj_scanpos = xsp;
									if (jj_3R_106())
										return true;
								}
							}
						}
					}
				}
			}
		}
		return false;
	}

	private boolean jj_3R_46(){
		if (jj_3R_62())
			return true;
		return false;
	}

	private boolean jj_3R_98(){
		if (jj_scan_token(TRUNCATE))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_150())
			jj_scanpos = xsp;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_97(){
		if (jj_scan_token(SQRT))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_96(){
		if (jj_scan_token(ROUND))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_149())
			jj_scanpos = xsp;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_95(){
		if (jj_scan_token(RAND))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_141())
			jj_scanpos = xsp;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_94(){
		if (jj_scan_token(RADIANS))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_93(){
		if (jj_scan_token(POWER))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_92(){
		if (jj_scan_token(PI))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_91(){
		if (jj_scan_token(MOD))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_90(){
		if (jj_scan_token(LOG10))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_89(){
		if (jj_scan_token(LOG))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_88(){
		if (jj_scan_token(FLOOR))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_87(){
		if (jj_scan_token(EXP))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_52(){
		if (jj_scan_token(CONCAT))
			return true;
		if (jj_3R_36())
			return true;
		return false;
	}

	private boolean jj_3R_86(){
		if (jj_scan_token(DEGREES))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_85(){
		if (jj_scan_token(CEILING))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_84(){
		if (jj_scan_token(ABS))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_29(){
		if (jj_3R_36())
			return true;
		Token xsp;
		while(true){
			xsp = jj_scanpos;
			if (jj_3R_52()){
				jj_scanpos = xsp;
				break;
			}
		}
		return false;
	}

	private boolean jj_3R_63(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_84()){
			jj_scanpos = xsp;
			if (jj_3R_85()){
				jj_scanpos = xsp;
				if (jj_3R_86()){
					jj_scanpos = xsp;
					if (jj_3R_87()){
						jj_scanpos = xsp;
						if (jj_3R_88()){
							jj_scanpos = xsp;
							if (jj_3R_89()){
								jj_scanpos = xsp;
								if (jj_3R_90()){
									jj_scanpos = xsp;
									if (jj_3R_91()){
										jj_scanpos = xsp;
										if (jj_3R_92()){
											jj_scanpos = xsp;
											if (jj_3R_93()){
												jj_scanpos = xsp;
												if (jj_3R_94()){
													jj_scanpos = xsp;
													if (jj_3R_95()){
														jj_scanpos = xsp;
														if (jj_3R_96()){
															jj_scanpos = xsp;
															if (jj_3R_97()){
																jj_scanpos = xsp;
																if (jj_3R_98())
																	return true;
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		return false;
	}

	private boolean jj_3R_61(){
		if (jj_scan_token(MINUS))
			return true;
		return false;
	}

	private boolean jj_3R_50(){
		if (jj_3R_26())
			return true;
		return false;
	}

	private boolean jj_3R_49(){
		if (jj_3R_65())
			return true;
		return false;
	}

	private boolean jj_3R_48(){
		if (jj_3R_64())
			return true;
		return false;
	}

	private boolean jj_3R_47(){
		if (jj_3R_63())
			return true;
		return false;
	}

	private boolean jj_3R_25(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_47()){
			jj_scanpos = xsp;
			if (jj_3R_48()){
				jj_scanpos = xsp;
				if (jj_3R_49()){
					jj_scanpos = xsp;
					if (jj_3R_50())
						return true;
				}
			}
		}
		return false;
	}

	private boolean jj_3R_32(){
		if (jj_3R_14())
			return true;
		if (jj_scan_token(DOT))
			return true;
		return false;
	}

	private boolean jj_3_12(){
		if (jj_3R_25())
			return true;
		return false;
	}

	private boolean jj_3R_45(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(9)){
			jj_scanpos = xsp;
			if (jj_3R_61())
				return true;
		}
		return false;
	}

	private boolean jj_3R_15(){
		if (jj_3R_14())
			return true;
		if (jj_scan_token(DOT))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_32())
			jj_scanpos = xsp;
		return false;
	}

	private boolean jj_3R_137(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(11)){
			jj_scanpos = xsp;
			if (jj_scan_token(12))
				return true;
		}
		if (jj_3R_130())
			return true;
		return false;
	}

	private boolean jj_3R_24(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_45())
			jj_scanpos = xsp;
		xsp = jj_scanpos;
		if (jj_3_12()){
			jj_scanpos = xsp;
			if (jj_3R_46())
				return true;
		}
		return false;
	}

	private boolean jj_3R_77(){
		if (jj_scan_token(COORDSYS))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_119())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_145(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_143(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_140(){
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		return false;
	}

	private boolean jj_3R_131(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(9)){
			jj_scanpos = xsp;
			if (jj_scan_token(10))
				return true;
		}
		if (jj_3R_112())
			return true;
		return false;
	}

	private boolean jj_3R_59(){
		if (jj_scan_token(POINT))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_138())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_130(){
		if (jj_3R_24())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_137())
			jj_scanpos = xsp;
		return false;
	}

	private boolean jj_3R_42(){
		if (jj_scan_token(REGION))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_29())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_19(){
		if (jj_3R_24())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(9)){
			jj_scanpos = xsp;
			if (jj_scan_token(10)){
				jj_scanpos = xsp;
				if (jj_scan_token(11)){
					jj_scanpos = xsp;
					if (jj_scan_token(12))
						return true;
				}
			}
		}
		return false;
	}

	private boolean jj_3_1(){
		if (jj_3R_14())
			return true;
		if (jj_scan_token(DOT))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_15())
			jj_scanpos = xsp;
		if (jj_scan_token(ASTERISK))
			return true;
		return false;
	}

	private boolean jj_3R_20(){
		if (jj_3R_36())
			return true;
		if (jj_scan_token(CONCAT))
			return true;
		return false;
	}

	private boolean jj_3R_41(){
		if (jj_scan_token(POLYGON))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_138())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		Token xsp;
		while(true){
			xsp = jj_scanpos;
			if (jj_3R_140()){
				jj_scanpos = xsp;
				break;
			}
		}
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_72(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_40(){
		if (jj_3R_59())
			return true;
		return false;
	}

	private boolean jj_3_10(){
		if (jj_3R_23())
			return true;
		return false;
	}

	private boolean jj_3R_112(){
		if (jj_3R_130())
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_131())
			jj_scanpos = xsp;
		return false;
	}

	private boolean jj_3_9(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3_7(){
		if (jj_scan_token(REGULAR_IDENTIFIER))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		return false;
	}

	private boolean jj_3_6(){
		if (jj_scan_token(LEFT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_39(){
		if (jj_scan_token(CIRCLE))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_138())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3_5(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(65)){
			jj_scanpos = xsp;
			if (jj_3R_20())
				return true;
		}
		return false;
	}

	private boolean jj_3_4(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_18()){
			jj_scanpos = xsp;
			if (jj_3R_19())
				return true;
		}
		return false;
	}

	private boolean jj_3R_18(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(9)){
			jj_scanpos = xsp;
			if (jj_scan_token(10))
				return true;
		}
		return false;
	}

	private boolean jj_3R_38(){
		if (jj_scan_token(CENTROID))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_119())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3_11(){
		if (jj_3R_24())
			return true;
		return false;
	}

	private boolean jj_3R_71(){
		if (jj_3R_36())
			return true;
		return false;
	}

	private boolean jj_3R_70(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3_8(){
		if (jj_3R_21())
			return true;
		return false;
	}

	private boolean jj_3R_69(){
		if (jj_3R_26())
			return true;
		return false;
	}

	private boolean jj_3R_68(){
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_51())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_37(){
		if (jj_scan_token(BOX))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_138())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_139())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_67(){
		if (jj_3R_29())
			return true;
		return false;
	}

	private boolean jj_3R_66(){
		if (jj_3R_112())
			return true;
		return false;
	}

	private boolean jj_3R_152(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_53(){
		if (jj_scan_token(SELECT))
			return true;
		return false;
	}

	private boolean jj_3R_125(){
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_51())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_144(){
		if (jj_3R_59())
			return true;
		return false;
	}

	private boolean jj_3R_21(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_37()){
			jj_scanpos = xsp;
			if (jj_3R_38()){
				jj_scanpos = xsp;
				if (jj_3R_39()){
					jj_scanpos = xsp;
					if (jj_3R_40()){
						jj_scanpos = xsp;
						if (jj_3R_41()){
							jj_scanpos = xsp;
							if (jj_3R_42())
								return true;
						}
					}
				}
			}
		}
		return false;
	}

	private boolean jj_3R_148(){
		if (jj_3R_51())
			return true;
		return false;
	}

	private boolean jj_3R_142(){
		if (jj_3R_59())
			return true;
		return false;
	}

	private boolean jj_3R_124(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_51(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_66()){
			jj_scanpos = xsp;
			if (jj_3R_67()){
				jj_scanpos = xsp;
				if (jj_3R_68()){
					jj_scanpos = xsp;
					if (jj_3R_69()){
						jj_scanpos = xsp;
						if (jj_3_8()){
							jj_scanpos = xsp;
							if (jj_3R_70()){
								jj_scanpos = xsp;
								if (jj_3R_71()){
									jj_scanpos = xsp;
									if (jj_3_11()){
										jj_scanpos = xsp;
										if (jj_3R_72())
											return true;
									}
								}
							}
						}
					}
				}
			}
		}
		return false;
	}

	private boolean jj_3R_147(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_123(){
		if (jj_3R_129())
			return true;
		return false;
	}

	private boolean jj_3R_151(){
		if (jj_3R_59())
			return true;
		return false;
	}

	private boolean jj_3R_16(){
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_33())
			return true;
		return false;
	}

	private boolean jj_3R_138(){
		if (jj_3R_29())
			return true;
		return false;
	}

	private boolean jj_3R_122(){
		if (jj_3R_128())
			return true;
		return false;
	}

	private boolean jj_3R_121(){
		if (jj_3R_23())
			return true;
		return false;
	}

	private boolean jj_3R_115(){
		if (jj_scan_token(FULL))
			return true;
		return false;
	}

	private boolean jj_3R_146(){
		if (jj_3R_59())
			return true;
		return false;
	}

	private boolean jj_3R_83(){
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_112())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_82(){
		if (jj_3R_129())
			return true;
		return false;
	}

	private boolean jj_3R_78(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_121()){
			jj_scanpos = xsp;
			if (jj_3R_122()){
				jj_scanpos = xsp;
				if (jj_3R_123()){
					jj_scanpos = xsp;
					if (jj_3R_124()){
						jj_scanpos = xsp;
						if (jj_3R_125())
							return true;
					}
				}
			}
		}
		return false;
	}

	private boolean jj_3R_81(){
		if (jj_3R_22())
			return true;
		return false;
	}

	private boolean jj_3R_80(){
		if (jj_3R_128())
			return true;
		return false;
	}

	private boolean jj_3R_111(){
		if (jj_scan_token(DISTANCE))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_146()){
			jj_scanpos = xsp;
			if (jj_3R_147())
				return true;
		}
		if (jj_scan_token(COMMA))
			return true;
		xsp = jj_scanpos;
		if (jj_3R_151()){
			jj_scanpos = xsp;
			if (jj_3R_152())
				return true;
		}
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_110(){
		if (jj_scan_token(COORD2))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_144()){
			jj_scanpos = xsp;
			if (jj_3R_145())
				return true;
		}
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_109(){
		if (jj_scan_token(COORD1))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_142()){
			jj_scanpos = xsp;
			if (jj_3R_143())
				return true;
		}
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_108(){
		if (jj_scan_token(AREA))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_119())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_118(){
		if (jj_scan_token(FULL))
			return true;
		return false;
	}

	private boolean jj_3R_62(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_80()){
			jj_scanpos = xsp;
			if (jj_3R_81()){
				jj_scanpos = xsp;
				if (jj_3R_82()){
					jj_scanpos = xsp;
					if (jj_3R_83())
						return true;
				}
			}
		}
		return false;
	}

	private boolean jj_3R_33(){
		if (jj_3R_53())
			return true;
		return false;
	}

	private boolean jj_3R_107(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(60)){
			jj_scanpos = xsp;
			if (jj_scan_token(61))
				return true;
		}
		if (jj_scan_token(LEFT_PAR))
			return true;
		if (jj_3R_119())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_119())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_114(){
		if (jj_scan_token(RIGHT))
			return true;
		return false;
	}

	private boolean jj_3R_154(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(9)){
			jj_scanpos = xsp;
			if (jj_scan_token(10))
				return true;
		}
		return false;
	}

	private boolean jj_3R_153(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_154())
			jj_scanpos = xsp;
		if (jj_scan_token(UNSIGNED_INTEGER))
			return true;
		return false;
	}

	private boolean jj_3R_65(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_3R_107()){
			jj_scanpos = xsp;
			if (jj_3R_108()){
				jj_scanpos = xsp;
				if (jj_3R_109()){
					jj_scanpos = xsp;
					if (jj_3R_110()){
						jj_scanpos = xsp;
						if (jj_3R_111())
							return true;
					}
				}
			}
		}
		return false;
	}

	private boolean jj_3R_139(){
		if (jj_3R_112())
			return true;
		if (jj_scan_token(COMMA))
			return true;
		if (jj_3R_112())
			return true;
		return false;
	}

	private boolean jj_3R_136(){
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(49)){
			jj_scanpos = xsp;
			if (jj_scan_token(50)){
				jj_scanpos = xsp;
				if (jj_scan_token(51)){
					jj_scanpos = xsp;
					if (jj_scan_token(52))
						return true;
				}
			}
		}
		if (jj_scan_token(LEFT_PAR))
			return true;
		xsp = jj_scanpos;
		if (jj_scan_token(20))
			jj_scanpos = xsp;
		if (jj_3R_51())
			return true;
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_135(){
		if (jj_scan_token(COUNT))
			return true;
		if (jj_scan_token(LEFT_PAR))
			return true;
		Token xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(20))
			jj_scanpos = xsp;
		xsp = jj_scanpos;
		if (jj_scan_token(11)){
			jj_scanpos = xsp;
			if (jj_3R_148())
				return true;
		}
		if (jj_scan_token(RIGHT_PAR))
			return true;
		return false;
	}

	private boolean jj_3R_117(){
		if (jj_scan_token(RIGHT))
			return true;
		return false;
	}

	/** Generated Token Manager. */
	public ADQLParserTokenManager token_source;
	SimpleCharStream jj_input_stream;
	/** Current token. */
	public Token token;
	/** Next token. */
	public Token jj_nt;
	private int jj_ntk;
	private Token jj_scanpos, jj_lastpos;
	private int jj_la;
	private int jj_gen;
	final private int[] jj_la1 = new int[97];
	static private int[] jj_la1_0;
	static private int[] jj_la1_1;
	static private int[] jj_la1_2;
	static private int[] jj_la1_3;
	static{
		jj_la1_init_0();
		jj_la1_init_1();
		jj_la1_init_2();
		jj_la1_init_3();
	}

	private static void jj_la1_init_0(){
		jj_la1_0 = new int[]{0x81,0x0,0x0,0x0,0x0,0x100000,0x200000,0x40,0x0,0x0,0x800000,0x800000,0x800,0x608,0x40,0x40,0x40,0x0,0x20,0x20,0x20,0x0,0x0,0x0,0x800000,0x800000,0x800000,0x0,0x8,0x7b000000,0x38000000,0x4000000,0x3a000000,0x3a000000,0x38000000,0x4000000,0x3a000000,0x3a000000,0x40,0x80000000,0x7b000000,0x0,0x0,0x0,0x600,0x600,0x8,0x8,0x0,0x600,0x600,0x1800,0x1800,0x600,0x600,0x8,0x100,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x7e000,0x0,0x0,0x608,0x7e000,0x0,0x0,0x40,0x8,0x100000,0xe08,0x0,0x100000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x608,0x40,0x40,0x0,0x0,0x40,0x608,};
	}

	private static void jj_la1_init_1(){
		jj_la1_1 = new int[]{0x0,0x2,0x1000,0x2000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffe0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000,0x18000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,0x3e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,0x0,0x0,0x3e0000,0xfc00000,0x10,0xc,0xc,0x10,0x0,0x10,0x10,0x0,0x210,0x400,0xfffe0000,0x0,0x10,0x10,0x0,0x0,0x0,0xfffe0000,0x1e0000,0x0,0x3e0000,0x30000000,0x2000000,0x2000000,0x2000000,0x2000000,0xf0000000,0x0,0xfc00000,0xf0000000,0xf03e0000,0x0,0x0,0x0,0x0,0x0,0xfffe0000,};
	}

	private static void jj_la1_init_2(){
		jj_la1_2 = new int[]{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x23ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x0,0x3fffffd,0x3fffffd,0x0,0x0,0x3fff8,0x3fc0000,0x0,0x23ffffff,};
	}

	private static void jj_la1_init_3(){
		jj_la1_3 = new int[]{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x3,0x0,0x3b,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x23,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x30,0x0,0x0,0x3b,0x3b,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x3b,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x0,0x0,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x2,0x3b,0x0,0x0,0x0,0x0,0x0,0x3b,};
	}

	final private JJCalls[] jj_2_rtns = new JJCalls[18];
	private boolean jj_rescan = false;
	private int jj_gc = 0;

	/** Constructor with InputStream. */
	public ADQLParser(java.io.InputStream stream){
		this(stream, (String)null);
	}

	/** Constructor with InputStream and supplied encoding */
	public ADQLParser(java.io.InputStream stream, String encoding){
		try{
			jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1);
		}catch(java.io.UnsupportedEncodingException e){
			throw new RuntimeException(e);
		}
		token_source = new ADQLParserTokenManager(jj_input_stream);
		token = new Token();
		jj_ntk = -1;
		jj_gen = 0;
		for(int i = 0; i < 97; i++)
			jj_la1[i] = -1;
		for(int i = 0; i < jj_2_rtns.length; i++)
			jj_2_rtns[i] = new JJCalls();
	}

	/** Reinitialise. */
	public void ReInit(java.io.InputStream stream){
		ReInit(stream, null);
	}

	/** Reinitialise. */
	public void ReInit(java.io.InputStream stream, String encoding){
		try{
			jj_input_stream.ReInit(stream, encoding, 1, 1);
		}catch(java.io.UnsupportedEncodingException e){
			throw new RuntimeException(e);
		}
		token_source.ReInit(jj_input_stream);
		token = new Token();
		jj_ntk = -1;
		jj_gen = 0;
		for(int i = 0; i < 97; i++)
			jj_la1[i] = -1;
		for(int i = 0; i < jj_2_rtns.length; i++)
			jj_2_rtns[i] = new JJCalls();
	}

	/** Constructor. */
	public ADQLParser(java.io.Reader stream){
		jj_input_stream = new SimpleCharStream(stream, 1, 1);
		token_source = new ADQLParserTokenManager(jj_input_stream);
		token = new Token();
		jj_ntk = -1;
		jj_gen = 0;
		for(int i = 0; i < 97; i++)
			jj_la1[i] = -1;
		for(int i = 0; i < jj_2_rtns.length; i++)
			jj_2_rtns[i] = new JJCalls();
	}

	/** Reinitialise. */
	public void ReInit(java.io.Reader stream){
		jj_input_stream.ReInit(stream, 1, 1);
		token_source.ReInit(jj_input_stream);
		token = new Token();
		jj_ntk = -1;
		jj_gen = 0;
		for(int i = 0; i < 97; i++)
			jj_la1[i] = -1;
		for(int i = 0; i < jj_2_rtns.length; i++)
			jj_2_rtns[i] = new JJCalls();
	}

	/** Constructor with generated Token Manager. */
	public ADQLParser(ADQLParserTokenManager tm){
		token_source = tm;
		token = new Token();
		jj_ntk = -1;
		jj_gen = 0;
		for(int i = 0; i < 97; i++)
			jj_la1[i] = -1;
		for(int i = 0; i < jj_2_rtns.length; i++)
			jj_2_rtns[i] = new JJCalls();
	}

	/** Reinitialise. */
	public void ReInit(ADQLParserTokenManager tm){
		token_source = tm;
		token = new Token();
		jj_ntk = -1;
		jj_gen = 0;
		for(int i = 0; i < 97; i++)
			jj_la1[i] = -1;
		for(int i = 0; i < jj_2_rtns.length; i++)
			jj_2_rtns[i] = new JJCalls();
	}

	private Token jj_consume_token(int kind) throws ParseException{
		Token oldToken;
		if ((oldToken = token).next != null)
			token = token.next;
		else
			token = token.next = token_source.getNextToken();
		jj_ntk = -1;
		if (token.kind == kind){
			jj_gen++;
			if (++jj_gc > 100){
				jj_gc = 0;
				for(int i = 0; i < jj_2_rtns.length; i++){
					JJCalls c = jj_2_rtns[i];
					while(c != null){
						if (c.gen < jj_gen)
							c.first = null;
						c = c.next;
					}
				}
			}
			trace_token(token, "");
			return token;
		}
		token = oldToken;
		jj_kind = kind;
		throw generateParseException();
	}

	@SuppressWarnings("serial")
	static private final class LookaheadSuccess extends java.lang.Error {}

	final private LookaheadSuccess jj_ls = new LookaheadSuccess();

	private boolean jj_scan_token(int kind){
		if (jj_scanpos == jj_lastpos){
			jj_la--;
			if (jj_scanpos.next == null){
				jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
			}else{
				jj_lastpos = jj_scanpos = jj_scanpos.next;
			}
		}else{
			jj_scanpos = jj_scanpos.next;
		}
		if (jj_rescan){
			int i = 0;
			Token tok = token;
			while(tok != null && tok != jj_scanpos){
				i++;
				tok = tok.next;
			}
			if (tok != null)
				jj_add_error_token(kind, i);
		}
		if (jj_scanpos.kind != kind)
			return true;
		if (jj_la == 0 && jj_scanpos == jj_lastpos)
			throw jj_ls;
		return false;
	}

	/** Get the next Token. */
	final public Token getNextToken(){
		if (token.next != null)
			token = token.next;
		else
			token = token.next = token_source.getNextToken();
		jj_ntk = -1;
		jj_gen++;
		trace_token(token, " (in getNextToken)");
		return token;
	}

	/** Get the specific Token. */
	final public Token getToken(int index){
		Token t = token;
		for(int i = 0; i < index; i++){
			if (t.next != null)
				t = t.next;
			else
				t = t.next = token_source.getNextToken();
		}
		return t;
	}

	private int jj_ntk_f(){
		if ((jj_nt = token.next) == null)
			return (jj_ntk = (token.next = token_source.getNextToken()).kind);
		else
			return (jj_ntk = jj_nt.kind);
	}

	private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
	private int[] jj_expentry;
	private int jj_kind = -1;
	private int[] jj_lasttokens = new int[100];
	private int jj_endpos;

	private void jj_add_error_token(int kind, int pos){
		if (pos >= 100)
			return;
		if (pos == jj_endpos + 1){
			jj_lasttokens[jj_endpos++] = kind;
		}else if (jj_endpos != 0){
			jj_expentry = new int[jj_endpos];
			for(int i = 0; i < jj_endpos; i++){
				jj_expentry[i] = jj_lasttokens[i];
			}
			jj_entries_loop: for(java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();){
				int[] oldentry = (int[])(it.next());
				if (oldentry.length == jj_expentry.length){
					for(int i = 0; i < jj_expentry.length; i++){
						if (oldentry[i] != jj_expentry[i]){
							continue jj_entries_loop;
						}
					}
					jj_expentries.add(jj_expentry);
					break jj_entries_loop;
				}
			}
			if (pos != 0)
				jj_lasttokens[(jj_endpos = pos) - 1] = kind;
		}
	}

	/** Generate ParseException. */
	public ParseException generateParseException(){
		jj_expentries.clear();
		boolean[] la1tokens = new boolean[103];
		if (jj_kind >= 0){
			la1tokens[jj_kind] = true;
			jj_kind = -1;
		}
		for(int i = 0; i < 97; i++){
			if (jj_la1[i] == jj_gen){
				for(int j = 0; j < 32; j++){
					if ((jj_la1_0[i] & (1 << j)) != 0){
						la1tokens[j] = true;
					}
					if ((jj_la1_1[i] & (1 << j)) != 0){
						la1tokens[32 + j] = true;
					}
					if ((jj_la1_2[i] & (1 << j)) != 0){
						la1tokens[64 + j] = true;
					}
					if ((jj_la1_3[i] & (1 << j)) != 0){
						la1tokens[96 + j] = true;
					}
				}
			}
		}
		for(int i = 0; i < 103; i++){
			if (la1tokens[i]){
				jj_expentry = new int[1];
				jj_expentry[0] = i;
				jj_expentries.add(jj_expentry);
			}
		}
		jj_endpos = 0;
		jj_rescan_token();
		jj_add_error_token(0, 0);
		int[][] exptokseq = new int[jj_expentries.size()][];
		for(int i = 0; i < jj_expentries.size(); i++){
			exptokseq[i] = jj_expentries.get(i);
		}
		return new ParseException(token, exptokseq, tokenImage);
	}

	private int trace_indent = 0;
	private boolean trace_enabled = true;

	/** Enable tracing. */
	final public void enable_tracing(){
		trace_enabled = true;
	}

	/** Disable tracing. */
	final public void disable_tracing(){
		trace_enabled = false;
	}

	private void trace_call(String s){
		if (trace_enabled){
			for(int i = 0; i < trace_indent; i++){
				System.out.print(" ");
			}
			System.out.println("Call:   " + s);
		}
		trace_indent = trace_indent + 2;
	}

	private void trace_return(String s){
		trace_indent = trace_indent - 2;
		if (trace_enabled){
			for(int i = 0; i < trace_indent; i++){
				System.out.print(" ");
			}
			System.out.println("Return: " + s);
		}
	}

	private void trace_token(Token t, String where){
		if (trace_enabled){
			for(int i = 0; i < trace_indent; i++){
				System.out.print(" ");
			}
			System.out.print("Consumed token: <" + tokenImage[t.kind]);
			if (t.kind != 0 && !tokenImage[t.kind].equals("\"" + t.image + "\"")){
				System.out.print(": \"" + t.image + "\"");
			}
			System.out.println(" at line " + t.beginLine + " column " + t.beginColumn + ">" + where);
		}
	}

	private void trace_scan(Token t1, int t2){
		if (trace_enabled){
			for(int i = 0; i < trace_indent; i++){
				System.out.print(" ");
			}
			System.out.print("Visited token: <" + tokenImage[t1.kind]);
			if (t1.kind != 0 && !tokenImage[t1.kind].equals("\"" + t1.image + "\"")){
				System.out.print(": \"" + t1.image + "\"");
			}
			System.out.println(" at line " + t1.beginLine + " column " + t1.beginColumn + ">; Expected token: <" + tokenImage[t2] + ">");
		}
	}

	private void jj_rescan_token(){
		jj_rescan = true;
		for(int i = 0; i < 18; i++){
			try{
				JJCalls p = jj_2_rtns[i];
				do{
					if (p.gen > jj_gen){
						jj_la = p.arg;
						jj_lastpos = jj_scanpos = p.first;
						switch(i){
							case 0:
								jj_3_1();
								break;
							case 1:
								jj_3_2();
								break;
							case 2:
								jj_3_3();
								break;
							case 3:
								jj_3_4();
								break;
							case 4:
								jj_3_5();
								break;
							case 5:
								jj_3_6();
								break;
							case 6:
								jj_3_7();
								break;
							case 7:
								jj_3_8();
								break;
							case 8:
								jj_3_9();
								break;
							case 9:
								jj_3_10();
								break;
							case 10:
								jj_3_11();
								break;
							case 11:
								jj_3_12();
								break;
							case 12:
								jj_3_13();
								break;
							case 13:
								jj_3_14();
								break;
							case 14:
								jj_3_15();
								break;
							case 15:
								jj_3_16();
								break;
							case 16:
								jj_3_17();
								break;
							case 17:
								jj_3_18();
								break;
						}
					}
					p = p.next;
				}while(p != null);
			}catch(LookaheadSuccess ls){}
		}
		jj_rescan = false;
	}

	private void jj_save(int index, int xla){
		JJCalls p = jj_2_rtns[index];
		while(p.gen > jj_gen){
			if (p.next == null){
				p = p.next = new JJCalls();
				break;
			}
			p = p.next;
		}
		p.gen = jj_gen + xla - jj_la;
		p.first = token;
		p.arg = xla;
	}

	static final class JJCalls {
		int gen;
		Token first;
		int arg;
		JJCalls next;
	}

}
