Newer
Older
if (debug) te.printStackTrace(System.err);
System.exit(4);
}
}catch(IOException ioe){
System.err.println("\n((X)) Error while reading the file \""+file+"\": "+ioe.getMessage()+" ((X))");
if (debug) ioe.printStackTrace(System.err);
System.exit(2);
}
}
PARSER_END(ADQLParser)
/* ########### */
/* # GRAMMAR # */
/* ########### */
/* ******************** */
/* Characters to ignore */
/* ******************** */
SKIP : { < " " | "\t" | "\n" | "\r" | "\r\n" > }
/* ************************************************************************** */
/* Reserved SQL words */
/* */
/* NOTE: */
/* This list is the one provided by the ADQL-2.0 standard after removal of */
/* all ADQL used words (e.g. SELECT, AS, LIKE, AVG, ABS, COS, POINT). */
/* (see ParseException.initialise(Token, int[][], String[]) for more */
/* details) */
/* ************************************************************************** */
TOKEN : {
< SQL_RESERVED_WORD: ("ABSOLUTE"|"ACTION"|"ADD"|"ALLOCATE"|"ALTER"|"ANY"|"ARE"|"ASSERTION"|"AT"|"AUTHORIZATION"|"BEGIN"|"BIT"|"BIT_LENGTH"|"BOTH"|"CASCADE"|"CASCADED"|"CASE"|"CAST"|"CATALOG"|"CHAR"|"CHARACTER"|"CHAR_LENGTH"|"CHARACTER_LENGTH"|"CHECK"|"CLOSE"|"COALESCE"|"COLLATE"|"COLLATION"|"COLUMN"|"COMMIT"|"CONNECT"|"CONNECTION"|"CONSTRAINT"|"CONSTRAINTS"|"CONTINUE"|"CONVERT"|"CORRESPONDING"|"CREATE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_USER"|"CURSOR"|"DATE"|"DAY"|"DEALLOCATE"|"DECIMAL"|"DECLARE"|"DEFAULT"|"DEFERRABLE"|"DEFERRED"|"DELETE"|"DESCRIBE"|"DESCRIPTOR"|"DIAGNOSTICS"|"DISCONNECT"|"DOMAIN"|"DOUBLE"|"DROP"|"ELSE"|"END"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXCEPTION"|"EXEC"|"EXECUTE"|"EXTERNAL"|"EXTRACT"|"FALSE"|"FETCH"|"FIRST"|"FLOAT"|"FOR"|"FOREIGN"|"FOUND"|"GET"|"GLOBAL"|"GO"|"GOTO"|"GRANT"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"INDICATOR"|"INITIALLY"|"INPUT"|"INSENSITIVE"|"INSERT"|"INT"|"INTEGER"|"INTERSECT"|"INTERVAL"|"INTO"|"ISOLATION"|"KEY"|"LANGUAGE"|"LAST"|"LEADING"|"LEVEL"|"LOCAL"|"LOWER"|"MATCH"|"MINUTE"|"MODULE"|"MONTH"|"NAMES"|"NATIONAL"|"NCHAR"|"NEXT"|"NO"|"NULLIF"|"NUMERIC"|"OCTET_LENGTH"|"OF"|"ONLY"|"OPEN"|"OPTION"|"OUTPUT"|"OVERLAPS"|"PAD"|"PARTIAL"|"POSITION"|"PRECISION"|"PREPARE"|"PRESERVE"|"PRIMARY"|"PRIOR"|"PRIVILEGES"|"PROCEDURE"|"PUBLIC"|"READ"|"REAL"|"REFERENCES"|"RELATIVE"|"RESTRICT"|"REVOKE"|"ROLLBACK"|"ROWS"|"SCHEMA"|"SCROLL"|"SECOND"|"SECTION"|"SESSION"|"SESSION_USER"|"SET"|"SIZE"|"SMALLINT"|"SOME"|"SPACE"|"SQL"|"SQLCODE"|"SQLERROR"|"SQLSTATE"|"SUBSTRING"|"SYSTEM_USER"|"TABLE"|"TEMPORARY"|"THEN"|"TIME"|"TIMESTAMP"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSACTION"|"TRANSLATE"|"TRANSLATION"|"TRIM"|"TRUE"|"UNION"|"UNIQUE"|"UNKNOWN"|"UPDATE"|"UPPER"|"USAGE"|"USER"|"VALUE"|"VALUES"|"VARCHAR"|"VARYING"|"VIEW"|"WHEN"|"WHENEVER"|"WITH"|"WORK"|"WRITE"|"YEAR"|"ZONE") >
}
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
/* *********** */
/* Punctuation */
/* *********** */
TOKEN : {
< LEFT_PAR: "(" >
| < RIGHT_PAR: ")" >
| < DOT: "." >
| < COMMA: "," >
| < EOQ: ";">
| < CONCAT: "||" >
}
/* ******************** */
/* Arithmetic operators */
/* ******************** */
TOKEN : {
< PLUS: "+" >
| < MINUS: "-" >
| < ASTERISK: "*" >
| < DIVIDE: "/" >
}
/* ******************** */
/* Comparison operators */
/* ******************** */
TOKEN : {
< EQUAL: "=" >
| < NOT_EQUAL: "<>" | "!=" >
| < LESS_THAN: "<" >
| < LESS_EQUAL_THAN: "<=" >
| < GREATER_THAN: ">" >
| < GREATER_EQUAL_THAN: ">=" >
}
/* *************** */
/* SELECT's tokens */
/* *************** */
TOKEN : {
< SELECT: "SELECT" >
| < QUANTIFIER: "DISTINCT" | "ALL" >
| < TOP: "TOP" >
}
/* ************* */
/* FROM's tokens */
/* ************* */
TOKEN : {
< FROM: "FROM" >
| < AS: "AS" >
| < NATURAL: "NATURAL" >
| < INNER: "INNER" >
| < OUTER: "OUTER" >
| < RIGHT: "RIGHT" >
| < LEFT: "LEFT" >
| < FULL: "FULL" >
| < JOIN: "JOIN" >
| < ON: "ON" >
| < USING: "USING" >
}
/* ************** */
/* WHERE's tokens */
/* ************** */
TOKEN : {
< WHERE: "WHERE" >
| < AND: "AND" >
| < OR: "OR" >
| < NOT: "NOT" >
| < IS: "IS" >
| < NULL: "NULL" >
| < BETWEEN: "BETWEEN" >
| < LIKE: "LIKE" >
| < IN: "IN" >
| < EXISTS: "EXISTS" >
}
/* ********************* */
/* Other clauses' tokens */
/* ********************* */
TOKEN : {
< BY: "BY" >
| < GROUP: "GROUP" >
| < HAVING: "HAVING" >
| < ORDER: "ORDER" >
| < ASC: "ASC" >
| < DESC: "DESC" >
}
/* ************* */
/* SQL functions */
/* ************* */
TOKEN : {
< AVG: "AVG" >
| < MAX: "MAX" >
| < MIN: "MIN" >
| < SUM: "SUM" >
| < COUNT: "COUNT" >
}
/* ************** */
/* ADQL functions */
/* ************** */
TOKEN : {
< BOX: "BOX" >
| < CENTROID: "CENTROID" >
| < CIRCLE: "CIRCLE" >
| < POINT: "POINT" >
| < POLYGON: "POLYGON" >
| < REGION: "REGION" >
| < CONTAINS: "CONTAINS" >
| < INTERSECTS: "INTERSECTS" >
| < AREA: "AREA" >
| < COORD1: "COORD1" >
| < COORD2: "COORD2" >
| < COORDSYS: "COORDSYS" >
| < DISTANCE: "DISTANCE" >
}
/* ********************** */
/* Mathematical functions */
/* ********************** */
TOKEN : {
< ABS: "ABS" >
| < CEILING: "CEILING" >
| < DEGREES: "DEGREES" >
| < EXP: "EXP" >
| < FLOOR: "FLOOR" >
| < LOG: "LOG" >
| < LOG10: "LOG10" >
| < MOD: "MOD" >
| < PI: "PI" >
| < POWER: "POWER" >
| < RADIANS: "RADIANS" >
| < RAND: "RAND" >
| < ROUND: "ROUND" >
| < SQRT: "SQRT" >
| < TRUNCATE: "TRUNCATE" >
}
/* ************************* */
/* Trigonometrical functions */
/* ************************* */
TOKEN : {
< ACOS: "ACOS" >
| < ASIN: "ASIN" >
| < ATAN: "ATAN" >
| < ATAN2: "ATAN2" >
| < COS: "COS" >
| < COT: "COT" >
| < SIN: "SIN" >
| < TAN: "TAN" >
}
/* ******* */
/* Comment */
/* ******* */
SKIP : { < <MINUS><MINUS> (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > }
/* ****** */
/* String */
/* ****** */
<DEFAULT> MORE : { "'" : WithinString }
<WithinString> MORE : { < ~["'"] | ("''") > }
<WithinString> TOKEN : { < STRING_LITERAL: "'" >: DEFAULT }
/* *************** */
/* Primary numbers */
/* *************** */
TOKEN : {
< SCIENTIFIC_NUMBER: (<UNSIGNED_FLOAT>|<UNSIGNED_INTEGER>) "E" (<PLUS>|<MINUS>)? <UNSIGNED_INTEGER> >
| < UNSIGNED_FLOAT: (<UNSIGNED_INTEGER> <DOT> (<UNSIGNED_INTEGER>)?) | (<DOT> <UNSIGNED_INTEGER>) >
| < UNSIGNED_INTEGER: (<DIGIT>)+ >
| < #DIGIT: ["0"-"9"] >
Grégory Mantelet
committed
}
/* ************************************************* */
/* Identifier (column, tables, ...) */
/* ************************************************* */
<DEFAULT> MORE : { "\"" : WithinDelimitedId }
<WithinDelimitedId> MORE : { < ~["\""] | ("\"\"") > }
<WithinDelimitedId> TOKEN : { < DELIMITED_IDENTIFIER: "\"" >: DEFAULT }
TOKEN : {
< REGULAR_IDENTIFIER_CANDIDATE: ((<Letter>)+ (<DIGIT> | <Letter>)* | (<DIGIT>)+ <Letter> (<DIGIT> | <Letter>)*) >
| < #Letter: ["a"-"z","A"-"Z","_","?","$","@","^","#","`","~","[","]","{","}"] >
}
/* ########## */
/* # 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.
*/
ADQLQuery Query(): {ADQLQuery q = null;}{
q=QueryExpression() (<EOF> | <EOQ>)
gmantele
committed
{
// check the query:
if (queryChecker != null)
queryChecker.check(q);
return q;
}
ADQLQuery QueryExpression(): {TextPosition endPos = null;} {
{
try{
// create the query:
query = queryFactory.createQuery();
stackQuery.push(query);
}catch(Exception ex){
throw generateParseException(ex);
}
}
Select()
From() {endPos = query.getFrom().getPosition();}
[Where() {endPos = query.getWhere().getPosition();}]
[GroupBy() {endPos = query.getGroupBy().getPosition();}]
[Having() {endPos = query.getHaving().getPosition();}]
[OrderBy() {endPos = query.getOrderBy().getPosition();}]
// 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();
return previousQuery;
}
}
ADQLQuery SubQueryExpression(): {ADQLQuery q = null; Token start, end;} {
start=<LEFT_PAR> q=QueryExpression() end=<RIGHT_PAR>
{
q.setPosition(new TextPosition(start, end));
return q;
}
void Select(): {ClauseSelect select = query.getSelect(); SelectItem item=null; Token start,t = null;} {
start=<SELECT>
[t=<QUANTIFIER> {select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT"));}]
[<TOP> t=<UNSIGNED_INTEGER>
{
try{
select.setLimit(Integer.parseInt(t.image));
}catch(NumberFormatException nfe){
throw new ParseException("[l."+t.beginLine+";c."+t.beginColumn+"] The TOP limit (\""+t.image+"\") isn't a regular unsigned integer !");
}
}
]
item=SelectItem() {select.add(item);}
(<COMMA> item=SelectItem() {select.add(item);})*
{
TextPosition lastItemPos = query.getSelect().get(query.getSelect().size()-1).getPosition();
select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn));
}
SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null; SelectItem item; Token starToken;} {
( starToken=<ASTERISK>
{
item = new SelectAllColumns(query);
item.setPosition(new TextPosition(starToken));
return item;
}
)
|LOOKAHEAD(7)
(
id=Identifier() <DOT> { identifiers.append(id); }
(
id=Identifier() <DOT> { identifiers.append(id); }
(
id=Identifier() <DOT> { identifiers.append(id); }
)?
)?
starToken=<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)));
return item;
}catch(Exception ex) {
throw generateParseException(ex);
}
}
)
|
(op=ValueExpression()[[<AS>] label=Identifier()])
)
{
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()));
return item;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
void From():{FromContent content = null, content2 = null;}{
try{
<FROM> content=TableRef()
(<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){
throw generateParseException(ex);
}
}
void Where(): {ClauseConstraints where = query.getWhere(); ADQLConstraint condition; Token start;} {
start=<WHERE> ConditionsList(where)
{
TextPosition endPosition = where.getPosition();
where.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
}
void GroupBy(): {ClauseADQL<ADQLColumn> groupBy = query.getGroupBy(); ADQLColumn colRef = null; Token start;} {
start=<GROUP> <BY> colRef=Column() { groupBy.add(colRef); }
( <COMMA> colRef=Column() { groupBy.add(colRef); } )*
{ groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn)); }
void Having(): {ClauseConstraints having = query.getHaving(); Token start;} {
start=<HAVING> ConditionsList(having)
{
TextPosition endPosition = having.getPosition();
having.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
}
void OrderBy(): {ClauseADQL<ADQLOrder> orderBy = query.getOrderBy(); ADQLOrder order = null; Token start;} {
start=<ORDER> <BY> order=OrderItem() {orderBy.add(order);}
( <COMMA> order=OrderItem() {orderBy.add(order);} )*
{ orderBy.setPosition(new TextPosition(start, token)); }
/* *************************** */
/* COLUMN AND TABLE REFERENCES */
/* *************************** */
IdentifierItem Identifier(): {Token t;} {
(
Grégory Mantelet
committed
t=<REGULAR_IDENTIFIER_CANDIDATE>
{
testRegularIdentifier(t);
return new IdentifierItem(t, false);
}
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
|
t=<DELIMITED_IDENTIFIER>
{ return new IdentifierItem(t, true); }
)
}
/**
* 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.
*/
IdentifierItems TableName(): {IdentifierItems identifiers=new IdentifierItems(true); IdentifierItem id=null;} {
(
id=Identifier() {identifiers.append(id);} // catalog
(LOOKAHEAD(1) <DOT> id=Identifier() {identifiers.append(id);})? // schema
(LOOKAHEAD(1) <DOT> id=Identifier() {identifiers.append(id);})? // table
)
{ return identifiers; }
}
/**
* 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.
*/
IdentifierItems ColumnName(): {IdentifierItem id; IdentifierItems table=null, identifiers=new IdentifierItems(false);} {
( id=Identifier() (LOOKAHEAD(1) <DOT> table=TableName())? )
{
identifiers.append(id);
if (table != null){
for(int i=0; i<table.size(); i++)
identifiers.append(table.get(i));
}
return identifiers;
}
}
ADQLColumn Column(): {IdentifierItems identifiers;} {
identifiers = ColumnName()
{
try{
return queryFactory.createColumn(identifiers);
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
gmantele
committed
ADQLOrder OrderItem(): {IdentifierItem identifier = null; Token ind = null, desc = null;}{
(identifier=Identifier() | ind=<UNSIGNED_INTEGER>) (<ASC> | desc=<DESC>)?
{
try{
ADQLOrder order = null;
gmantele
committed
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));
}
return order;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
FromContent SimpleTableRef(): {IdentifierItem alias = null; IdentifierItems identifiers = null; ADQLQuery subQuery = null; FromContent content = null; Token start,end;} {
try{
(
identifiers=TableName() [[<AS>] alias=Identifier()]
{
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));
return content;
}
|LOOKAHEAD(2)
subQuery=SubQueryExpression() [<AS>] 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));
return content;
}
start=<LEFT_PAR> content=JoinedTable() end=<RIGHT_PAR>
{
content.setPosition(new TextPosition(start, end));
return content;
}
)
}catch(Exception ex){
throw generateParseException(ex);
}
}
FromContent TableRef(): { FromContent content; } {
content=SimpleTableRef()
( LOOKAHEAD(2) content=JoinSpecification(content) )*
{ return content; }
}
FromContent JoinedTable(): { FromContent content; } {
content=SimpleTableRef()
( content=JoinSpecification(content) )+
{ return content; }
}
ADQLJoin JoinSpecification(FromContent leftTable): { 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;} {
<NATURAL> {natural=true;} [<INNER> | ((<LEFT> {type = JoinType.OUTER_LEFT;}|<RIGHT> {type = JoinType.OUTER_RIGHT;}|<FULL> {type = JoinType.OUTER_FULL;}) [<OUTER>])] <JOIN> rightTable=SimpleTableRef()
{
join = queryFactory.createJoin(type, leftTable, rightTable);
join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition()));
return join;
}
[<INNER> | ((<LEFT> {type = JoinType.OUTER_LEFT;}|<RIGHT> {type = JoinType.OUTER_RIGHT;}|<FULL> {type = JoinType.OUTER_FULL;}) [<OUTER>])] <JOIN> rightTable=SimpleTableRef()
(
<ON> ConditionsList(condition)
{
join = queryFactory.createJoin(type, leftTable, rightTable, condition);
join.setPosition(new TextPosition(leftTable.getPosition(), condition.getPosition()));
return join;
}
|
<USING> <LEFT_PAR> id=Identifier()
{ lstColumns.add( queryFactory.createColumn(id) ); }
(
<COMMA> id=Identifier()
{ lstColumns.add( queryFactory.createColumn(id) ); }
)* lastPar=<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)));
return join;
}
)
)
}catch(Exception ex){
throw generateParseException(ex);
}
}
/* ****** */
/* STRING */
/* ****** */
StringConstant String(): {Token t, start=null; String str=""; StringConstant cst;} {
(t=<STRING_LITERAL>
{
str += t.image.substring(1, t.image.length()-1).replaceAll("''", "'");
if (start == null)
start = t;
}
)+
{
try{
cst = queryFactory.createStringConstant(str);
cst.setPosition(new TextPosition(start, t));
return cst;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
/* ************* */
/* NUMERIC TYPES */
/* ************* */
NumericConstant UnsignedNumeric(): {Token t; NumericConstant cst;} {
(t=<SCIENTIFIC_NUMBER>
| t=<UNSIGNED_FLOAT>
| t=<UNSIGNED_INTEGER>)
cst = queryFactory.createNumericConstant(t.image);
cst.setPosition(new TextPosition(t));
return cst;
}catch(Exception ex){
throw generateParseException(ex);
}
}
NumericConstant UnsignedFloat(): {Token t; NumericConstant cst;} {
(t=<UNSIGNED_INTEGER>
| t=<UNSIGNED_FLOAT>)
{
try{
cst = queryFactory.createNumericConstant(t.image);
cst.setPosition(new TextPosition(t));
return cst;
}catch(Exception ex){
throw generateParseException(ex);
}
}
NumericConstant SignedInteger(): {Token sign=null, number; NumericConstant cst;} {
((sign=<PLUS>|sign=<MINUS>)? number=<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));
}
return cst;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
/* *********** */
/* EXPRESSIONS */
/* *********** */
ADQLOperand NumericValueExpressionPrimary(): {ADQLColumn column; ADQLOperand op; Token left, right;} {
op=UnsignedNumeric() {return op;}
| column=Column() {column.setExpectedType('N'); return column;}
// set_function_specification
| op=SqlFunction() {return op;}
// LEFT_PAR value_expression RIGHT_PAR
| (left=<LEFT_PAR> op=NumericExpression() right=<RIGHT_PAR>) { WrappedOperand wop = queryFactory.createWrappedOperand(op); wop.setPosition(new TextPosition(left, right)); return wop; })
}catch(Exception ex){
throw generateParseException(ex);
}
}
ADQLOperand StringValueExpressionPrimary(): {StringConstant expr; ADQLColumn column; ADQLOperand op; Token left, right;} {
try{
(// string
// unsigned numeric
| op=UnsignedNumeric() {return op;}
// set_function_specification
| op=SqlFunction() {return op;}
// column_reference
| column=Column() {column.setExpectedType('*'); return column;}
// LEFT_PAR value_expression RIGHT_PAR
| (left=<LEFT_PAR> (op=ValueExpression()) right=<RIGHT_PAR>) { WrappedOperand wop = queryFactory.createWrappedOperand(op); wop.setPosition(new TextPosition(left, right)); return wop; })
}catch(Exception ex){
throw generateParseException(ex);
}
ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; Token left, right; } {
try{
(LOOKAHEAD((<PLUS>|<MINUS>) | (Factor() (<PLUS>|<MINUS>|<ASTERISK>|<DIVIDE>))) valueExpr=NumericExpression()
| LOOKAHEAD(<COORDSYS> | (StringFactor() <CONCAT>)) valueExpr=StringExpression()
| LOOKAHEAD(<LEFT_PAR>) left=<LEFT_PAR> valueExpr=ValueExpression() right=<RIGHT_PAR> { valueExpr = queryFactory.createWrappedOperand(valueExpr); ((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right)); }
Grégory Mantelet
committed
| LOOKAHEAD(<REGULAR_IDENTIFIER_CANDIDATE> <LEFT_PAR>) valueExpr=UserDefinedFunction()
| LOOKAHEAD(2) valueExpr=GeometryValueFunction()
| LOOKAHEAD(Column()) valueExpr=Column()
| LOOKAHEAD(String()) valueExpr=StringFactor()
| LOOKAHEAD(3) valueExpr=Factor()
/* At this position in this switch, all possibilities (including
* Column()) have already been tested and failed.
*
* So, this final choice actually aims to throw an error set with the
* current token and with an error message implying that a column name
* was expected (which is generally the case in an ADQL query).
*
* Note: This choice will generally be reached if an unexpected ADQL/SQL
* word is ending the query. */
| valueExpr=Column() )
{return valueExpr;}
}catch(Exception ex){
throw generateParseException(ex);
}
ADQLOperand NumericExpression(): {Token sign=null; ADQLOperand leftOp, rightOp=null;} {
(leftOp=NumericTerm() ((sign=<PLUS> | sign=<MINUS>) rightOp=NumericExpression())?)
{
if (sign == null)
return leftOp;
else{
try{
Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
return operation;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
}
ADQLOperand NumericTerm(): {Token sign=null; ADQLOperand leftOp, rightOp=null;} {
(leftOp=Factor() ((sign=<ASTERISK> | sign=<DIVIDE>) rightOp=NumericTerm())?)
{
if (sign == null)
return leftOp;
else{
try{
Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
return operation;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
}
ADQLOperand Factor(): {boolean negative = false; Token minusSign = null; ADQLOperand op;} {
(<PLUS> | (minusSign=<MINUS> {negative = true;}))?
(LOOKAHEAD(2) op=NumericFunction() | op=NumericValueExpressionPrimary())
)
{
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){
throw generateParseException(ex);
}
}
return op;
}
}
ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null;} {
leftOp=StringFactor()
(
<CONCAT>
rightOp=StringFactor()
{
if (!(leftOp instanceof Concatenation)){
try{
ADQLOperand temp = leftOp;
leftOp = queryFactory.createConcatenation();
((Concatenation)leftOp).add(temp);
}catch(Exception ex){
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()));
}
return leftOp;
}
ADQLOperand StringFactor(): {ADQLOperand op;} {
(op=ExtractCoordSys()
| LOOKAHEAD(2) op=UserDefinedFunction() { ((UserDefinedFunction)op).setExpectedType('S'); }
| op=StringValueExpressionPrimary())
{return op;}
}
GeometryValue<GeometryFunction> GeometryExpression(): {ADQLColumn col = null; GeometryFunction gf = null;} {
(col=Column() | gf=GeometryValueFunction())
{
if (col != null){
col.setExpectedType('G');
return new GeometryValue<GeometryFunction>(col);
}else
return new GeometryValue<GeometryFunction>(gf);
}
}
/* ********************************** */
/* BOOLEAN EXPRESSIONS (WHERE clause) */
/* ********************************** */
ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint constraint = null; Token op = null; boolean notOp = false;} {
try{
[op=<NOT> {notOp = true;}]
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));
}
if (clause instanceof ADQLConstraint)
clause.add(constraint);
else
clause.add(constraint);
}
(
(op=<AND> | op=<OR>)
[<NOT> {notOp = true;}]
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));
}
if (clause instanceof ADQLConstraint)
clause.add(op.image, constraint);
else
clause.add(op.image, constraint);
}
)*
}catch(Exception ex){
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));
}
return clause;
}
ADQLConstraint Constraint(): {ADQLConstraint constraint = null; Token start, end;} {
(LOOKAHEAD(<EXISTS> | ValueExpression()) constraint=Predicate()
start=<LEFT_PAR>
{
try{
constraint = queryFactory.createGroupOfConstraints();
}catch(Exception ex){
throw generateParseException(ex);
}
}
ConditionsList((ConstraintsGroup)constraint)
end=<RIGHT_PAR>
{ ((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end)); }
))
{return constraint;}
}
ADQLConstraint Predicate(): {ADQLQuery q=null; ADQLColumn column=null; ADQLOperand strExpr1=null, strExpr2=null; ADQLOperand op; Token start, notToken = null, end; ADQLConstraint constraint = null;} {
try{
// exists_predicate
(
(start=<EXISTS> q=SubQueryExpression()
{
Exists e = queryFactory.createExists(q);
e.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));
return e;
}
)
// null_predicate
| LOOKAHEAD(Column() <IS>)(column=Column() <IS> [notToken=<NOT>] end=<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)));
return in;
}
)
// like_predicate
| LOOKAHEAD(StringExpression() [<NOT>] <LIKE>) (strExpr1=StringExpression() [notToken=<NOT>] <LIKE> strExpr2=StringExpression()
{
Comparison comp = queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.LIKE:ComparisonOperator.NOTLIKE, strExpr2);
comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition()));
return comp;
}
)
| (op=ValueExpression()
(// comparison_predicate
(constraint=ComparisonEnd(op))
// between predicate
| LOOKAHEAD(2) constraint=BetweenEnd(op)
// in_predicate
| constraint=InEnd(op)
)
)
)
}catch(Exception ex){
throw generateParseException(ex);
}
{return constraint;}
}
Comparison ComparisonEnd(ADQLOperand leftOp): {Token comp; ADQLOperand rightOp;} {
((comp=<EQUAL> | comp=<NOT_EQUAL> | comp=<LESS_THAN> | comp=<LESS_EQUAL_THAN> | comp=<GREATER_THAN> | comp=<GREATER_EQUAL_THAN>) rightOp=ValueExpression())
{
try{
Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
return comparison;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
Between BetweenEnd(ADQLOperand leftOp): {Token start,notToken=null; ADQLOperand min, max;} {
[notToken=<NOT>] start=<BETWEEN> min=ValueExpression() <AND> max=ValueExpression()
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));
return bet;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
In InEnd(ADQLOperand leftOp): {Token not=null, start; ADQLQuery q = null; ADQLOperand item; Vector<ADQLOperand> items = new Vector<ADQLOperand>();} {
[not=<NOT>] start=<IN>
(LOOKAHEAD(2) q=SubQueryExpression()
| (<LEFT_PAR> item=ValueExpression() {items.add(item);} (<COMMA> item=ValueExpression() {items.add(item);})* <RIGHT_PAR>))
{
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));
return in;
}catch(Exception ex){
throw generateParseException(ex);
}
}
}
/* ************* */
/* SQL FUNCTIONS */
/* ************* */
SQLFunction SqlFunction(): {Token fct, all=null, distinct=null, end; ADQLOperand op=null; SQLFunction funct = null;}{
(fct=<COUNT> <LEFT_PAR> [distinct=<QUANTIFIER>] (all=<ASTERISK> | op=ValueExpression()) end=<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));
})
((fct=<AVG> | fct=<MAX> | fct=<MIN> | fct=<SUM>) <LEFT_PAR> [distinct=<QUANTIFIER>] op=ValueExpression() end=<RIGHT_PAR>
{
funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
funct.setPosition(new TextPosition(fct, end));
})
)
}catch(Exception ex){
throw generateParseException(ex);
}
{ return funct; }
}
/* ************** */
/* ADQL FUNCTIONS */
/* ************** */
ADQLOperand[] Coordinates(): {ADQLOperand[] ops = new ADQLOperand[2];} {
ops[0]=NumericExpression() <COMMA> ops[1]=NumericExpression()
{return ops;}
}
GeometryFunction GeometryFunction(): {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{
// predicate_geometry_function
(
((fct=<CONTAINS> | fct=<INTERSECTS>) <LEFT_PAR> gvf1=GeometryExpression() <COMMA> gvf2=GeometryExpression() end=<RIGHT_PAR>