blob: f7b9a76382f71ebdcccb4d088fec701a6c042394 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2005 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
options{
STATIC=false;
MULTI=true;
NODE_DEFAULT_VOID=true;
NODE_SCOPE_HOOK=true;
VISITOR=true;
}
PARSER_BEGIN(DerbySQLParser)
package org.eclipse.datatools.sqltools.db.derby.parser;
import java.util.ArrayList;
import java.io.StringReader;
import org.eclipse.datatools.sqltools.db.derby.Activator;
import org.eclipse.datatools.sqltools.sql.parser.SQLParser;
import org.eclipse.datatools.sqltools.sql.parser.ast.Node;
import org.eclipse.datatools.sqltools.sql.parser.ast.SimpleNode;
import org.eclipse.datatools.sqltools.sql.parser.ParseException;
import org.eclipse.datatools.sqltools.sql.parser.SQLParserConstants;
import org.eclipse.datatools.sqltools.sql.parser.JavaCharStream;
import org.eclipse.datatools.sqltools.sql.parser.Token;
import org.eclipse.datatools.sqltools.sql.parser.TokenMgrError;
import org.eclipse.datatools.sqltools.sql.parser.ParsingResult;
import org.eclipse.datatools.sqltools.sql.parser.util.ParserUtil;
import org.eclipse.datatools.sqltools.db.derby.internal.Messages;
import org.eclipse.datatools.sqltools.sql.parser.ParserParameters;
/**
* Derby SQL parser.
* @author Hui Cao
*
*/
public class DerbySQLParser extends SQLParser implements SQLParserConstants
{
private static DerbySQLParser _instance = new DerbySQLParser(new StringReader(""));
private boolean _debug = false;
private ParsingResult result = null;
private ArrayList exceptions = new ArrayList();
private ArrayList knownExceptions = new ArrayList();
private static final int[] STMT_START = new int[]{ALTER, BEGIN, BREAK, CHECKPOINT, CLOSE, COMMIT, CONNECT,
CONTINUE, CREATE, DEALLOCATE, DECLARE, DELETE, DISK, DROP, DUMP, EXECUTE, EXEC,
FETCH, GOTO, GRANT, IF, INSERT, KILL, LOAD, LOCK, ONLINE, OPEN, PREPARE, //MOUNT,
PRINT, QUIESCE, RAISERROR, READTEXT, RECONFIGURE, REMOVE, REORG, RETURN, REVOKE,
ROLLBACK, SAVE, SELECT, SET, SETUSER, SHUTDOWN, TRUNCATE, UPDATE, USE,//UNMOUNT,
WAITFOR, WHILE, WRITETEXT
};
public static final String[] STMT_START_STRING = new String[]{"ALTER","BEGIN","BREAK","CHECKPOINT","CLOSE","COMMIT","CONNECT",
"CONTINUE","CREATE","DEALLOCATE","DECLARE","DELETE","DISK","DROP","DUMP","EXECUTE","EXEC",
"FETCH","GOTO","GRANT","IF","INSERT","KILL","LOAD","LOCK","ONLINE","OPEN","PREPARE",
"PRINT","QUIESCE","RAISERROR","READTEXT","RECONFIGURE","REMOVE","REORG","RETURN","REVOKE",
"ROLLBACK","SAVE","SELECT","SET","SETUSER","SHUTDOWN","TRUNCATE","UPDATE","USE",
"WAITFOR","WHILE","WRITETEXT"
};
private static final int[] DEFINED_STMT_START = new int[]{ALTER, BEGIN, CREATE, DECLARE, DELETE, EXECUTE, EXEC, FETCH, IF, INSERT, PRINT, RETURN, SELECT, UPDATE, USE };
private static final int[] TERMINATORS = new int[]{GO, SEMICOLON};
private static final String[] TERMINATORS_STRING = new String[]{"GO", ";"};
private static int[] STMT_START_TERMINATORS = new int[STMT_START.length + TERMINATORS.length];
static
{
System.arraycopy(STMT_START, 0, STMT_START_TERMINATORS, 0, STMT_START.length);
System.arraycopy(TERMINATORS, 0, STMT_START_TERMINATORS, STMT_START.length, TERMINATORS.length);
}
//FIXME do we need this field?
private boolean isContentAssist = true;
/*
* Singleton
*/
public static DerbySQLParser getInstance(){
return _instance;
}
public DerbySQLParser()
{
}
//Implements JavaCC methods
void jjtreeOpenNodeScope(Node n)
{
((SimpleNode)n).setFirstToken ( getToken(1));
}
void jjtreeCloseNodeScope(Node n)
{
((SimpleNode)n).setLastToken( getToken(0));
}
//Implements SQLParser abstract methods
/**
* Returns the statement terminator array. Different vendors will have their
* own terminators defined, so we just leave this method as abstract here.
*
* @return statement terminator array
*/
public String[] getStatementTerminators()
{
return TERMINATORS_STRING;
}
/**
* Returns the token strings that can be used to begin a SQL statement.
*
* @return statement start token array
*/
public String[] getStatementStartTokens()
{
return STMT_START_STRING;
}
/**
* Concrete parsers must imlement this method to do the real parsing.
* @param text sql text to be parsed.
* @return <code>ParsingResult</code> containing root AST node and <code>ParseException</code>s.
*/
protected synchronized ParsingResult doParse(String text)
{
java.io.StringReader sr = new java.io.StringReader( text );
java.io.Reader r = new java.io.BufferedReader( sr );
//ReInit will be generated by JavaCC
ReInit(r);
initParsing();
return startIgnoreException();
}
//Other methods
private ParsingResult startIgnoreException()
{
Node node = new ASTStart(JJTSTART);
try
{
node = startRootIgnoreException();
}catch (ParseException e) {
exceptions.add(e);
}
catch (TokenMgrError t)
{
ParseException e = new ParseException(t.getMessage());
if (token == null){
//when the error token occurs at the beginning
e.currentToken = new Token();
}else{
e.currentToken = token;
}
if (t.getToken() != null){
e.currentToken.next = t.getToken();
}else{
Token errtoken = new Token();
errtoken.beginLine = token.endLine;
errtoken.beginColumn = token.endColumn + 1;
errtoken.endLine = token.endLine;
errtoken.endColumn = token.endColumn + 1;
e.currentToken.next = errtoken;
}
exceptions.add(e);
}
catch (Throwable t)
{
Activator.getDefault().log(t);
}
Boolean consumeException = (Boolean)getParameters().getProperty(ParserParameters.PARAM_CONSUME_EXCEPTION);
result.setRootNode(node);
if ( consumeException == null || consumeException.booleanValue())
{
result.setExceptions(knownExceptions);
}
else
{
result.setExceptions(exceptions);
}
return result;
}
private void initParsing(){
result = new DerbyParsingResult();
exceptions = new ArrayList();
knownExceptions = new ArrayList();
}
private boolean isSupportedStatementStartToken(int kind)
{
for (int i=0; i<DEFINED_STMT_START.length; i++)
{
if (kind == DEFINED_STMT_START[i])
{
return true;
}
}
return false;
}
private boolean isStatementStartToken(int kind)
{
for (int i=0; i<STMT_START.length; i++)
{
if (kind == STMT_START[i])
{
return true;
}
}
return false;
}
private boolean isStatementToken(int kind)
{
if (kind == 0 || isStatementStartToken(kind))
{
return false;
}
for (int i=0; i<TERMINATORS.length; i++)
{
if (kind == TERMINATORS[i])
{
return false;
}
}
return true;
}
private boolean check(String unReservedKeyword)
{
Token currentToken = getToken(1);
int currentTokenKind = currentToken.kind;
String currentTokenImage = currentToken.image;
if (currentTokenKind == ID && currentTokenImage.equalsIgnoreCase(unReservedKeyword))
{
return true;
}
if (currentTokenKind == INVALID_TOKEN)
{
result.addExpectedUnreservedKeywords(unReservedKeyword);
}
return false;
}
private boolean check(int type, String multiKeyword)
{
return check(type, new String[]{multiKeyword});
}
/**
*multiKeywords will show as content assist proposal
*/
private boolean check(int type, String[] multiKeywords)
{
Token currentToken = getToken(1);
int currentTokenKind = currentToken.kind;
String currentTokenImage = currentToken.image;
if (currentTokenKind == type)
{
return true;
}
if (currentTokenKind == INVALID_TOKEN)
{
for (int i=0; i< multiKeywords.length; i++)
{
result.addExpectedUnreservedKeywords(multiKeywords[i]);
}
}
return false;
}
final private void logDebug(String message)
{
if (_debug)
{
Activator.getDefault().log(message);
}
}
}
PARSER_END(DerbySQLParser)
SKIP:
{
" "
| "\n"
| "\r"
| "\t"
| "\f"
}
/* COMMENTS */
MORE :
{
"--" : IN_SINGLE_LINE_COMMENT
}
<IN_SINGLE_LINE_COMMENT>
SPECIAL_TOKEN :
{
<SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT
}
<IN_SINGLE_LINE_COMMENT>
MORE :
{
< ~[] >
}
/*
SPECIAL_TOKEN :
{
< SINGLE_LINE_COMMENT: "--"(~["\n","\r"])* ("\n"|"\r"|"\r\n")? >
}
*/
TOKEN_MGR_DECLS : {
int commentNestingDepth = 0 ;
}
MORE : { "/*" { commentNestingDepth = 1 ; } : IN_MULTI_LINE_COMMENT }
< IN_MULTI_LINE_COMMENT > MORE : { "/*" { commentNestingDepth += 1 ; } }
< IN_MULTI_LINE_COMMENT > SPECIAL_TOKEN : { "*/" {
commentNestingDepth -= 1;
SwitchTo( commentNestingDepth==0 ? DEFAULT : IN_MULTI_LINE_COMMENT ); } }
< IN_MULTI_LINE_COMMENT > MORE : { <COMMENT_CONTENT: ~[]> {} }
TOKEN:
{
< INVALID_TOKEN: "!%^&" > //Using token will always causes exception
| < ADD: "add" >
| < ALTER: "alter" >
| < AND: "and" >
| < ANY: "any" >
| < AS: "as" >
| < ASC: "asc" >
| < AT: "at" >
| < AUTHORIZATION: "authorization" >
| < AVG: "avg" >
| < BEGIN: "begin" >
| < BETWEEN: "between" >
| < BREAK: "break" >
| < BROWSE: "browse" >
| < BULK: "bulk" >
| < BY: "by" >
| < CASCADE: "cascade" >
| < CASE: "case" >
| < CHECK: "check" >
| < CHECKPOINT: "checkpoint" >
| < CLOSE: "close" >
| < CLUSTERED: "clustered" >
| < COALESCE: "coalesce" >
| < COMMIT: "commit" >
| < COMPUTE: "compute" >
| < CONFIRM: "confirm" >
| < CONNECT: "connect" >
| < CONSTRAINT: "constraint" >
| < CONTINUE: "continue" >
| < CONTROLROW: "controlrow" >
| < CONVERT: "convert" >
| < COUNT: "count" >
| < CREATE: "create" >
| < CURRENT: "current" >
| < CURSOR: "cursor" >
| < DATABASE: "database" >
| < DBCC: "dbcc" >
| < DEALLOCATE: "deallocate" >
| < DECLARE: "declare" >
| < DEFAULT_VAL: "default" >
| < DELETE: "delete" >
| < DESC: "desc" >
| < DETERMINISTIC: "deterministic" >
| < DISK: "disk" >
| < DISTINCT: "distinct" >
| < DOUBLE: "double" >
| < DROP: "drop" >
| < DUMMY: "dummy" >
| < DUMP: "dump" >
| < ELSE: "else" >
| < END: "end" >
| < ENDTRAN: "endtran" >
| < ESCAPE: "escape" >
| < EXCEPT: "except" >
| < EXCLUSIVE: "exclusive" >
| < EXEC: "exec" >
| < EXECUTE: "execute" >
| < EXISTS: "exists" >
| < EXIT: "exit" >
| < EXTERNAL: "external" >
| < EVENT: "event" >
| < FETCH: "fetch" >
| < FILLFACTOR: "fillfactor" >
| < FOR: "for" >
| < FOREIGN: "foreign" >
| < FROM: "from" >
| < FUNC: "func" >
| < FUNCTION: "function" >
| < GO: "go" > //terminator
| < GOTO: "goto" >
| < GRANT: "grant" >
| < GROUP: "group" >
| < HAVING: "having" >
| < HOLDLOCK: "holdlock" >
| < IDENTITY: "identity" >
| < IF: "if" >
| < IN: "in" >
| < INDEX: "index" >
| < INOUT: "inout" >
| < INSERT: "insert" >
| < INSTALL: "install" >
| < INTERSECT: "intersect" >
| < INTO: "into" >
| < IS: "is" >
| < ISOLATION: "isolation" >
| < JAR: "jar" >
| < JOIN: "join" >
| < KEY: "key" >
| < KILL: "kill" >
| < LEVEL: "level" >
| < LIKE: "like" >
| < LOAD: "load" >
| < LOCK: "lock" >
| < MAX: "max" >
| < MIN: "min" >
| < MODIFY: "modify" >
| < NATIONAL: "national" >
| < NOHOLDLOCK: "noholdlock" >
| < NONCLUSTERED: "nonclustered" >
| < NO: "no" >
| < NOT: "not" >
| < NULL: "null" >
| < NULLIF: "nullif" >
| < OF: "of" >
| < OFF: "off" >
| < OFFSETS: "offsets" >
| < ON: "on" >
| < ONCE: "once" >
| < ONLINE: "online" >
| < ONLY: "only" >
| < OPEN: "open" >
| < OPTION: "option" >
| < OR: "or" >
| < ORDER: "order" >
| < OUT: "out" >
| < OUTPUT: "output" >
| < OVER: "over" >
| < PARTITION: "partition" >
| < PERM: "perm" >
| < PERMANENT: "permanent" >
| < PLAN: "plan" >
| < PREPARE: "prepare" >
| < PRIMARY: "primary" >
| < PRINT: "print" >
| < PRIVILEGES: "privileges" >
| < PROC: "proc" >
| < PROCEDURE: "procedure" >
| < PROCESSEXIT: "processexit" >
| < PROXY_TABLE: "proxy_table" >
| < PUBLIC: "public" >
| < QUIESCE: "quiesce" >
| < RAISERROR: "raiserror" >
| < READ: "read" >
| < READPAST: "readpast" >
| < READTEXT: "readtext" >
| < RECONFIGURE: "reconfigure" >
| < REFERENCES: "references" >
| < REMOVE: "remove" >
| < REORG: "reorg" >
| < REPLACE: "replace" >
| < REPLICATION: "replication" >
| < RETURN: "return" >
| < RETURNS: "returns" >
| < REVOKE: "revoke" >
| < ROLE: "role" >
| < ROLLBACK: "rollback" >
| < ROWCOUNT: "rowcount" >
| < ROWS: "rows" >
| < RULE: "rule" >
| < SAVE: "save" >
| < SCHEMA: "schema" >
| < SELECT: "select" >
| < SET: "set" >
| < SETUSER: "setuser" >
| < SHARED: "shared" >
| < SHUTDOWN: "shutdown" >
| < SOME: "some" >
| < STATISTICS: "statistics" >
| < STRINGSIZE: "stringsize" >
| < STRIPE: "stripe" >
| < SUM: "sum" >
| < TABLE: "table" >
| < TEMP: "temp" >
| < TEMPORARY: "temporary" >
| < TEXTSIZE: "textsize" >
| < TO: "to" >
| < TRAN: "tran" >
| < TRANSACTION: "transaction" >
| < TRUNCATE: "truncate" >
| < UNION: "union" >
| < UNIQUE: "unique" >
| < UNPARTITION: "unpartition" >
| < UPDATE: "update" >
| < USE: "use" >
| < USER: "user" >
| < USING: "using" >
| < VALUES: "values" >
| < VARYING: "varying" >
| < VIEW: "view" >
| < WAITFOR: "waitfor" >
| < WHEN: "when" >
| < WHERE: "where" >
| < WHILE: "while" >
| < WITH: "with" >
| < WORK: "work" >
| < WRITETEXT: "writetext" >
}
<DESCRIPTION_START_STATE> TOKEN:
{
< OPENDESCRIPTION: "\r\n" > : DESCRIPTION_STATE
}
<DESCRIPTION_STATE> TOKEN: /* Line */
{
< CLOSEDESCRIPTION: "~" > : DEFAULT
| < DESCRIPTION: (~["~"])* "~" > : DEFAULT
}
TOKEN: /* Literals */
{
< INTEGER_LITERAL: (["0"-"9"])+ >
| < FLOATING_POINT_LITERAL:
(["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)?
| "." (["0"-"9"])+ (<EXPONENT>)?
| (["0"-"9"])+ (<EXPONENT>)?
>
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
| < SINGLE_STRING_LITERAL: "'" (~["'"])* ( "''" (~["'"])* )* "'" >
| < DOUBLE_STRING_LITERAL: "\"" (~["\""])* ( "\"\"" (~["\""])* )* "\"" >
| < BINARY_LITERAL: "0" ("x" | "X" ) ( <HEXDIGIT> )+ >
| < #HEXDIGIT: ["A"-"F", "a"-"f", "0"-"9"] >
| < MONEY_LITERAL: ("$" | "\u00a5" | "\u00a3" )? <FLOATING_POINT_LITERAL> >
}
Token string_literal() : {Token t;}
{
( t = <SINGLE_STRING_LITERAL> | t = <DOUBLE_STRING_LITERAL> )
{return t;}
}
TOKEN: /* Identifiers */
{
< ID: ( <LETTER> | "_" )+ ( <SYMBOL> | <DIGIT> | <LETTER> | "#" | "@" )* >
| < SQUARE_BRACKET_ID: ("[" <ID> "]")>
| < #VAR_NAME_BODY: ( <SYMBOL> | <DIGIT> | <LETTER> | "#" )+ ( <SYMBOL> | <DIGIT> | <LETTER> | "#" | "@" )* >
| < VAR_NAME: "@"<VAR_NAME_BODY> >
| < LABEL: <ID>":" >
| < GLOBAL_VAR_NAME: "@@"<VAR_NAME_BODY> >
| < TEMP_TABLE_NAME: "#" ( <SYMBOL> | <DIGIT> | <LETTER> | "#" | "@" )+ >
/*FIXME: Unicode code point ranges from 0000 to 10ffff, but JavaCC seems only recognize four digits following "u". Not sure what the consequence will be for now.*/
| < #LETTER: ["A"-"Z", "a"-"z", "\u0080"-"\uffff"] >
| < #DIGIT: ["0"-"9"] >
| < #SYMBOL: ["$" , "\u00a5" , "\u00a3" , "_" ] >
}
TOKEN: /* Separators and operators */
{
< CONCAT: "||" >
| < COMMA: "," >
| < SEMICOLON: ";" >
| < DOT: "." >
| < ROWTYPE: "%rowtype" >
| < TILDE: "~" >
| < LESS: "<" >
| < LESSEQUAL: "<=" >
| < GREATER: ">" >
| < GREATEREQUAL: ">=" >
| < EQUAL: "=" >
| < NOTEQUAL: "!=" >
| < JOINPLUS: "(+)" >
| < OPENPAREN: "(" >
| < CLOSEPAREN: ")" >
| < ASTERISK: "*" >
| < SLASH: "/" >
| < PLUS: "+" >
| < MINUS: "-" >
| < QUESTIONMARK: "?" >
| < LEQJOIN: "*="> //FIXME:
| < REQJOIN: "=*">
| < JAVA_REF: ">>">
}
/*******************************************************************
* Unreserved Keywords
*******************************************************************/
Token UK_ABSOLUTE() : {Token t;}
{
(LOOKAHEAD({check("absolute")}) t = <ID> )
{return t;}
}
Token UK_AFTER() : {Token t;}
{
(LOOKAHEAD({check("after")}) t = <ID> )
{return t;}
}
Token UK_ALL() : {Token t;}
{
(LOOKAHEAD({check("all")}) t = <ID> )
{return t;}
}
Token UK_BINARY() : {Token t;}
{
(LOOKAHEAD({check("binary")}) t = <ID> )
{return t;}
}
Token UK_BEFORE() : {Token t;}
{
(LOOKAHEAD({check("before")}) t = <ID> )
{return t;}
}
Token UK_BIT() : {Token t;}
{
(LOOKAHEAD({check("bit")}) t = <ID> )
{return t;}
}
Token UK_BOOLEAN() : {Token t;}
{
(LOOKAHEAD({check("boolean")}) t = <ID> )
{return t;}
}
Token UK_CHAR() : {Token t;}
{
(LOOKAHEAD({check("char")}) t = <ID> )
{return t;}
}
Token UK_CHAR_S() : {Token t;}
{
(LOOKAHEAD({check("character")}) t = <ID> )
{return t;}
}
Token UK_DATE() : {Token t;}
{
(LOOKAHEAD({check("date")}) t = <ID> )
{return t;}
}
Token UK_DATETIME() : {Token t;}
{
(LOOKAHEAD({check("datetime")}) t = <ID> )
{return t;}
}
Token UK_DB2SQL() : {Token t;}
{
(LOOKAHEAD({check("db2sql")}) t = <ID> )
{return t;}
}
Token UK_DECIMAL() : {Token t;}
{
(LOOKAHEAD({check("decimal")}) t = <ID> )
{return t;}
}
Token UK_DECIMAL_S() : {Token t;}
{
(LOOKAHEAD({check("dec")}) t = <ID> )
{return t;}
}
TOKEN:{ < UK_DOUBLE_PRECISION: "double" ("\t"|" "|"\r"|"\n")+ "precision"> }
Token UK_DOUBLE_PRECISION() : {Token t;}
{
(LOOKAHEAD({check( UK_DOUBLE_PRECISION, "double precision")}) t = <UK_DOUBLE_PRECISION> )
{return t;}
}
Token UK_EACH() : {Token t;}
{
(LOOKAHEAD({check("each")}) t = <ID> )
{return t;}
}
Token UK_FALSE() : {Token t;}
{
(LOOKAHEAD({check("false")}) t = <ID> )
{return t;}
}
Token UK_FIRST() : {Token t;}
{
(LOOKAHEAD({check("first")}) t = <ID> )
{return t;}
}
Token UK_FLOAT() : {Token t;}
{
(LOOKAHEAD({check("float")}) t = <ID> )
{return t;}
}
Token UK_FULL() : {Token t;}
{
(LOOKAHEAD({check("full")}) t = <ID> )
{return t;}
}
Token UK_IMAGE() : {Token t;}
{
(LOOKAHEAD({check("image")}) t = <ID> )
{return t;}
}
Token UK_INNER() : {Token t;}
{
(LOOKAHEAD({check( "inner")}) t = <ID> )
{return t;}
}
Token UK_INSENSITIVE() : {Token t;}
{
(LOOKAHEAD({check("insensitive")}) t = <ID> )
{return t;}
}
Token UK_INT() : {Token t;}
{
(LOOKAHEAD({check("int")}) t = <ID> )
{return t;}
}
Token UK_INT_S() : {Token t;}
{
(LOOKAHEAD({check("integer")}) t = <ID> )
{return t;}
}
Token UK_LAST() : {Token t;}
{
(LOOKAHEAD({check("last")}) t = <ID> )
{return t;}
}
Token UK_LEFT() : {Token t;}
{
(LOOKAHEAD({check("left")}) t = <ID> )
{return t;}
}
Token UK_MODE() : {Token t;}
{
(LOOKAHEAD({check("mode")}) t = <ID> )
{return t;}
}
Token UK_MONEY() : {Token t;}
{
(LOOKAHEAD({check("money")}) t = <ID> )
{return t;}
}
Token UK_NAME() : {Token t;}
{
(LOOKAHEAD({check("name")}) t = <ID> )
{return t;}
}
Token UK_NCHAR() : {Token t;}
{
(LOOKAHEAD({check("nchar")}) t = <ID> )
{return t;}
}
TOKEN:{ < UK_NCHAR_S: "national" ("\t"|" "|"\r"|"\n")+ "char"> }
Token UK_NCHAR_S() : {Token t;}
{
(LOOKAHEAD({check( UK_NCHAR_S, "national char")}) t = <UK_NCHAR_S> )
{return t;}
}
TOKEN:{ < UK_NCHAR_S1: "national" ("\t"|" "|"\r"|"\n")+ "character"> }
Token UK_NCHAR_S1() : {Token t;}
{
(LOOKAHEAD({check( UK_NCHAR_S1, "national character")}) t = <UK_NCHAR_S1> )
{return t;}
}
Token UK_NEXT() : {Token t;}
{
(LOOKAHEAD({check("next")}) t = <ID> )
{return t;}
}
Token UK_NEW() : {Token t;}
{
(LOOKAHEAD({check("new")}) t = <ID> )
{return t;}
}
Token UK_NEW_TABLE() : {Token t;}
{
(LOOKAHEAD({check("new_table")}) t = <ID> )
{return t;}
}
Token UK_NONE() : {Token t;}
{
(LOOKAHEAD({check("none")}) t = <ID> )
{return t;}
}
TOKEN:{ < UK_NO_SCROLL: "no" ("\t"|" "|"\r"|"\n")+ "scroll"> }
Token UK_NO_SCROLL() : {Token t;}
{
(LOOKAHEAD({check( UK_NO_SCROLL, "no scroll")}) t = <UK_NO_SCROLL> )
{return t;}
}
Token UK_NUMERIC() : {Token t;}
{
(LOOKAHEAD({check("numeric")}) t = <ID> )
{return t;}
}
Token UK_NVARCHAR() : {Token t;}
{
(LOOKAHEAD({check("nvarchar")}) t = <ID> )
{return t;}
}
TOKEN:{ < UK_NVARCHAR_S: "national" ("\t"|" "|"\r"|"\n")+ "char" ("\t"|" "|"\r"|"\n")+ "varying"> }
Token UK_NVARCHAR_S() : {Token t;}
{
(LOOKAHEAD({check( UK_NVARCHAR_S, "national char varying")}) t = <UK_NVARCHAR_S> )
{return t;}
}
TOKEN:{ < UK_NVARCHAR_S1: "national" ("\t"|" "|"\r"|"\n")+ "character" ("\t"|" "|"\r"|"\n")+ "varying"> }
Token UK_NVARCHAR_S1() : {Token t;}
{
(LOOKAHEAD({check( UK_NVARCHAR_S1, "national character varying")}) t = <UK_NVARCHAR_S1> )
{return t;}
}
TOKEN:{ < UK_NVARCHAR_S2: "nchar" ("\t"|" "|"\r"|"\n")+ "varying"> }
Token UK_NVARCHAR_S2() : {Token t;}
{
(LOOKAHEAD({check( UK_NVARCHAR_S2, "nchar varying")}) t = <UK_NVARCHAR_S2> )
{return t;}
}
Token UK_OF() : {Token t;}
{
(LOOKAHEAD({check("of")}) t = <ID> )
{return t;}
}
Token UK_OLD() : {Token t;}
{
(LOOKAHEAD({check("old")}) t = <ID> )
{return t;}
}
Token UK_OLD_TABLE() : {Token t;}
{
(LOOKAHEAD({check("old_table")}) t = <ID> )
{return t;}
}
Token UK_OUTER() : {Token t;}
{
(LOOKAHEAD({check("outer")}) t = <ID> )
{return t;}
}
Token UK_PRIOR() : {Token t;}
{
(LOOKAHEAD({check("prior")}) t = <ID> )
{return t;}
}
Token UK_REAL() : {Token t;}
{
(LOOKAHEAD({check("real")}) t = <ID> )
{return t;}
}
Token UK_REFERENCING() : {Token t;}
{
(LOOKAHEAD({check("referencing")}) t = <ID> )
{return t;}
}
Token UK_RELATIVE() : {Token t;}
{
(LOOKAHEAD({check("relative")}) t = <ID> )
{return t;}
}
Token UK_RIGHT() : {Token t;}
{
(LOOKAHEAD({check("right")}) t = <ID> )
{return t;}
}
Token UK_ROW() : {Token t;}
{
(LOOKAHEAD({check("row")}) t = <ID> )
{return t;}
}
Token UK_SCROLL() : {Token t;}
{
(LOOKAHEAD({check("scroll")}) t = <ID> )
{return t;}
}
TOKEN:{ < UK_SEMI_SENSITIVE: "semi" ("\t"|" "|"\r"|"\n")+ "sensitive"> }
Token UK_SEMI_SENSITIVE() : {Token t;}
{
(LOOKAHEAD({check( UK_SEMI_SENSITIVE, "semi sensitive")}) t = <UK_SEMI_SENSITIVE> )
{return t;}
}
Token UK_SMALLDATETIME() : {Token t;}
{
(LOOKAHEAD({check("smalldatetime")}) t = <ID> )
{return t;}
}
Token UK_SMALLINT() : {Token t;}
{
(LOOKAHEAD({check("smallint")}) t = <ID> )
{return t;}
}
Token UK_SMALLMONEY() : {Token t;}
{
(LOOKAHEAD({check("smallmoney")}) t = <ID> )
{return t;}
}
Token UK_STATEMENT() : {Token t;}
{
(LOOKAHEAD({check("statement")}) t = <ID> )
{return t;}
}
Token UK_TEXT() : {Token t;}
{
(LOOKAHEAD({check("text")}) t = <ID> )
{return t;}
}
Token UK_THEN() : {Token t;}
{
(LOOKAHEAD({check("then")}) t = <ID> )
{return t;}
}
Token UK_TIME() : {Token t;}
{
(LOOKAHEAD({check("time")}) t = <ID> )
{return t;}
}
Token UK_TIMESTAMP() : {Token t;}
{
(LOOKAHEAD({check("timestamp")}) t = <ID> )
{return t;}
}
Token UK_TINYINT() : {Token t;}
{
(LOOKAHEAD({check("tinyint")}) t = <ID> )
{return t;}
}
Token UK_TRIGGER() : {Token t;}
{
(LOOKAHEAD({check("trigger")}) t = <ID> )
{return t;}
}
Token UK_TRUE() : {Token t;}
{
(LOOKAHEAD({check("true")}) t = <ID> )
{return t;}
}
Token UK_UNICHAR() : {Token t;}
{
(LOOKAHEAD({check("unichar")}) t = <ID> )
{return t;}
}
Token UK_UNIVARCHAR() : {Token t;}
{
(LOOKAHEAD({check("univarchar")}) t = <ID> )
{return t;}
}
Token UK_VARBINARY() : {Token t;}
{
(LOOKAHEAD({check("varbinary")}) t = <ID> )
{return t;}
}
Token UK_VARCHAR() : {Token t;}
{
(LOOKAHEAD({check("varchar")}) t = <ID> )
{return t;}
}
TOKEN:{ < UK_VARCHAR_S: "char" ("\t"|" "|"\r"|"\n")+ "varying"> }
Token UK_VARCHAR_S() : {Token t;}
{
(LOOKAHEAD({check( UK_VARCHAR_S, "char varying")}) t = <UK_VARCHAR_S> )
{return t;}
}
TOKEN:{ < UK_VARCHAR_S1: "character" ("\t"|" "|"\r"|"\n")+ "varying"> }
Token UK_VARCHAR_S1() : {Token t;}
{
(LOOKAHEAD({check( UK_VARCHAR_S1, "character varying")}) t = <UK_VARCHAR_S1> )
{return t;}
}
/**
* Ignore exception during parsing so that the rest part can be parsed
*/
Node startRootIgnoreException() #Start: {}
{
(
[ delimiter()]
(
try{
statement()
}catch (ParseException e) {
//TODO can we create an UnknownStatement?
exceptions.add(e);
error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS);
} catch (Throwable t) {
//TODO: handle this throwable separately in SQLEditor:setOutlineContent.
ParseException e = new ParseException(ParserUtil.getErrorMessage(getToken(0)));
e.currentToken = getToken(0);
exceptions.add(e);
error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS);
}
)* <EOF>
)
{ return jjtThis; }
}
ASTSQLDelimiter delimiter() #SQLDelimiter:{}
{
(LOOKAHEAD(2) ( <GO> | <SEMICOLON> ))+
{
return jjtThis;
}
}
void statement() : {setScope("SQL Statement", SCOPE_DEFAULT);/*the default scope*/result.clearCurrentTableNames(isContentAssist);}
{
try{
(
( use()
| LOOKAHEAD(2) create_trigger()
| LOOKAHEAD( <CREATE> ) create_stmts()
| LOOKAHEAD( <ALTER> ) alter_stmts()
| LOOKAHEAD( <DROP> ) drop_stmts()
| LOOKAHEAD( <INSERT> ) insert_stmts()
| LOOKAHEAD( <UPDATE> ) update_stmts()
| LOOKAHEAD( <SELECT> ) select()
| LOOKAHEAD( <DELETE> ) delete_stmts()
| LOOKAHEAD( <FETCH> ) fetch()
| LOOKAHEAD( <BEGIN> ) begin_stmts()
| LOOKAHEAD(1) return_stmt()
| LOOKAHEAD(1) if_stmt()
| LOOKAHEAD(1) print()
| LOOKAHEAD(1) unknown_sql_stmt()
) #SQLStatement
| LOOKAHEAD(1) declare()
)
[LOOKAHEAD(<GO> | <SEMICOLON>) delimiter()]
}catch(ParseException e){
exceptions.add(e);
error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS);
//to generate an ASTSQLDelimiter node so that the statement can be separated
if (getToken(1).kind == GO || getToken(1).kind == SEMICOLON )
{
delimiter();
}
} catch (Throwable t) {
//TODO: handle this throwable separately in SQLEditor:setOutlineContent.
ParseException e = new ParseException(ParserUtil.getErrorMessage(getToken(0)));
e.currentToken = getToken(0);
exceptions.add(e);
error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS);
if (getToken(1).kind == GO || getToken(1).kind == SEMICOLON )
{
delimiter();
}
}
{
}
}
void unknown_sql_stmt() : {}
{
LOOKAHEAD({ !isSupportedStatementStartToken(getToken(1).kind) })
(
<BREAK> | <CHECKPOINT> | <CLOSE> | <COMMIT> | <CONNECT> |
<CONTINUE> | <DEALLOCATE> | <DECLARE> | <DISK> | <DUMP> | <EXECUTE> | <EXEC> |
<GOTO> | <GRANT> | <KILL> | <LOAD> | <LOCK> | <ONLINE> | <OPEN> | <PREPARE> |
<QUIESCE> | <RAISERROR> | <READTEXT> | <RECONFIGURE> | <REMOVE> | <REORG> | <RETURN> | <REVOKE> |
<ROLLBACK> | <SAVE> | <SET> | <SETUSER> | <SHUTDOWN> | <TRUNCATE> |
<WAITFOR> | <WHILE> | <WRITETEXT>| <ID>
)
{
error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS);
}
}
void any_stmt_token():{}
{
{
error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS);
}
}
void use() : {setScope("SQL Statement", SCOPE_CATALOGS);}
{
<USE> id()
}
void create_stmts() : {}
{
<CREATE>
(<DATABASE>
|<TABLE>
|<PROCEDURE> | <PROC>
|UK_TRIGGER()
|<FUNCTION>
|<EVENT>
|<SCHEMA>
|unique() dummy() clustered() <INDEX>
|<VIEW>
|<DEFAULT_VAL>
|<ROLE>
|<ID>
)
any_stmt_token()
}
void unique() : {}
{
[ <UNIQUE> ]
}
void dummy() : {}
{
[ <DUMMY> ]
}
void clustered() : {}
{
[ <NONCLUSTERED>
| <CLUSTERED> ]
}
void alter_stmts() : {}
{
<ALTER>
(<DATABASE>
|<TABLE>
|<PROCEDURE> | <PROC>
|UK_TRIGGER()
|<FUNCTION>
|<EVENT>
|<ROLE>
|<ID>
)
any_stmt_token()
}
void drop_stmts() : {}
{
<DROP>
(<DATABASE>
|<TABLE>
|<PROCEDURE> | <PROC>
|UK_TRIGGER()
|<FUNCTION>
|<EVENT>
|<SCHEMA>
|<INDEX>
|<VIEW>
|<DEFAULT_VAL>
|<ROLE>
|<ID>
)
any_stmt_token()
}
void begin_stmts() : {}
{
LOOKAHEAD(<BEGIN> tran()) begin_tran()
| compound_statement()
}
void delete_stmts() : {}
{
delete()
}
void insert_stmts() : {}
{
insert()
}
void update_stmts() : {}
{
update()
}
ASTSQLDataType datatype() #SQLDataType: {}
{
(
base_datatype()
)
{return jjtThis;}
}
ASTSQLDataType base_datatype() #SQLDataType: {Token t= null; int length=0, scale=-1; String name=null; }
{
try{
(
t = UK_DOUBLE_PRECISION()
| t = UK_BINARY() [ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_BIT()
| ( t = UK_CHAR() | t = UK_CHAR_S() ) [ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_DATETIME()
| t = UK_DATE()
| ( t = UK_DECIMAL() | t = UK_DECIMAL_S() ) [ LOOKAHEAD(2) "(" length = number() [ "," scale = number() ] ")" ]
| t = UK_FLOAT() [ LOOKAHEAD(2) "(" length = number() ")" ]
| ( t = UK_INT() | t = UK_INT_S() )
| t = UK_MONEY()
| ( t = UK_NCHAR() | t = UK_NCHAR_S() | t = UK_NCHAR_S1() ) [ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_NUMERIC() [ LOOKAHEAD(2) "(" length = number() [ "," scale = number() ] ")"
{
if ((length < scale))
{
ParseException e = new ParseException(Messages.SQLParser_datatype_judgeLengthAndScale);
e.currentToken = t.next;
exceptions.add(e);
}
}
]
| ( t = UK_NVARCHAR() | t = UK_NVARCHAR_S() | t = UK_NVARCHAR_S1() | t = UK_NVARCHAR_S2() ) [ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_REAL()
| t = UK_SMALLDATETIME()
| t = UK_SMALLINT()
| t = UK_SMALLMONEY()
| t = UK_TIMESTAMP()
| t = UK_TIME()
| t = UK_TINYINT()
| t = UK_UNICHAR()[ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_UNIVARCHAR()[ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_VARBINARY() [ LOOKAHEAD(2) "(" length = number() ")" ]
| t = UK_VARCHAR() [ LOOKAHEAD(2) "(" length = number() ")" ]
| name = java_name() [ LOOKAHEAD(2) "(" length = number() ")" ] //TODO: retrieve user defined datatype from ASE system table
)
{
if (t != null )
{
((ASTSQLDataType)jjtThis).setName(t.image);
}else{
((ASTSQLDataType)jjtThis).setName(name);
}
((ASTSQLDataType)jjtThis).setLength(length);
((ASTSQLDataType)jjtThis).setScale(scale);
return jjtThis;
}
}catch(ParseException e){
exceptions.add(e);
return jjtThis;
}
}
String java_name() : {Token t = null; String wholename = null; String part = null;}
{
t = id_or_string() {wholename = t.image;} [LOOKAHEAD(2) "." part = java_name() {wholename += "." + part;} ]
{return wholename;}
}
void length_spec() : {}
{
[ LOOKAHEAD(2) "(" number() [ "," number() ] ")" ]
}
void insert() : {setScope("insert", SCOPE_TABLES);}
{
<INSERT> into_over() table_object() {setScope("insert", SCOPE_COLUMNS);}
optional_insert_col_list() insert_source()
}
void into_over() : {}
{
[ <INTO>
| <OVER> ]
}
void optional_insert_col_list() : {}
{
[ LOOKAHEAD(2) "(" insert_column_list() ")" ]
}
void insert_column_list() : {}
{
insert_column()
( "," insert_column() )*
}
void insert_column() : {}
{
LOOKAHEAD([id_or_string()] ".") prefix_list() ( id_or_string() )
| id_or_string()
}
void insert_source() : {}
{
<VALUES> "(" insert_values() ")"
| select()
}
void insert_values() : {}
{
[ insert_value_list()]
}
void insert_value_list() : {}
{
insert_value()
( "," insert_value() )*
}
void insert_value() : {}
{
expression()
| <DEFAULT_VAL>
}
void update() : {}
{
<UPDATE>
{setScope("update", SCOPE_TABLES);} table_object() {}
<SET>
{setScope("update", SCOPE_COLUMNS);} set_clause_list()
{setScope("update", SCOPE_TABLES);} from_where_clause()
{}
}
void set_clause_list() : {}
{
set_clause()
( "," set_clause() )*
}
void set_clause() : {}
{
(
LOOKAHEAD(3) primary()
| variable_assignment()
)
"=" expression()
}
void select() : {}
{
query_expression() order_by_clause() compute_clause() isolation_clause()
}
void query_expression() : {}
{
query_term() ( <UNION> all_option() query_term() )*
}
void query_term() : {}
{
query_primary()
}
void all_option() : {}
{
[ UK_ALL() ]
}
void query_primary() : {}
{
simple_table()
| "(" query_expression() ")"
}
void simple_table() : {}
{
query_specification()
}
void query_specification() : {}
{
<SELECT> all_distinct()
{setScope("query_specification", SCOPE_COLUMNS);} select_list()
{setScope("query_specification", SCOPE_TABLES);} [ into() ]
optional_from_clause()
[ where_clause() ]
group_by_clause() having_clause()
}
void into(): {}
{
<INTO> into_object()
}
void into_object() : {}
{
table_object()
//TODO location_option() column_delimiter() on_segment() partition_option()
}
void cursor_update_list() : {}
{
[ <OF> cursor_column_list()]
}
void cursor_column_list() : {}
{
curs_upd_column()
( "," curs_upd_column() )*
}
void curs_upd_column() : {}
{
[ LOOKAHEAD([id_or_string()] ".") prefix_list() ] idplus()
}
void isolation_clause() : {}
{
[ <AT> <ISOLATION> isolation_lvl()]
}
void isolation_lvl() : {}
{
<INTEGER_LITERAL>
| <READ> <ID>
| <ID> [ <READ> ]
}
void all_distinct() : {}
{
[ UK_ALL()
| <DISTINCT> ]
}
void delete() : {setScope("delete", SCOPE_TABLES);}
{
<DELETE> result_table()
from_where_clause()
}
void result_table() : {}
{
[ <FROM> ] table_object() {}
}
void subquery() : {}
{
"(" subquery_content() ")"
}
void subquery_content() #SQLStatement: {}
{
<SELECT> subq_select()
{}
}
void subq_select() : {}
{
[ subq_all_distinct() subquery_select_expression()
optional_from_clause()
[ where_clause() ]
group_by_clause() having_clause() subq_fake_union() subq_fake_order_by_clause() subq_fake_compute_clause() subq_fake_isolation_clause() ]
}
void subq_all_distinct() : {}
{
[ UK_ALL()
| <DISTINCT> ]
}
void subq_fake_union() : {}
{
[ <UNION> subq_fake_select() ]
}
void subq_fake_select() : {}
{
[ LOOKAHEAD(2) subq_fake_primary() <UNION> ] subq_fake_primary()
}
void subq_fake_primary() : {}
{
<SELECT> subq_fake_all_distinct() subq_fake_select_expression()
optional_from_clause()
[ where_clause() ]
group_by_clause() having_clause()
}
void subq_fake_all_distinct() : {}
{
[ UK_ALL()
| <DISTINCT> ]
}
void subq_fake_select_expression() : {}
{
LOOKAHEAD(2) subq_expression_list()
| [ prefix_list() ] "*"
}
void subq_fake_order_by_clause() : {}
{
[ <ORDER> <BY> subq_fake_order_by_list() ]
}
void subq_fake_order_by_list() : {}
{
subq_fake_order_by_item()
( "," subq_fake_order_by_item() )*
}
void subq_fake_order_by_item() : {}
{
expression() [ order_by_option() ]
}
void subq_fake_compute_clause() : {}
{
[ subq_fake_compute_statement_list()]
}
void subq_fake_compute_statement_list() : {}
{
subq_fake_compute_statement()
( subq_fake_compute_statement() )*
}
void subq_fake_compute_statement() : {}
{
<COMPUTE> subq_fake_optional_compute_by_list() subq_fake_compute_list() subq_fake_optional_compute_by_list()
}
void subq_fake_compute_list() : {}
{
subq_fake_compute_function()
( "," subq_fake_compute_function() )*
}
void subq_fake_compute_function() : {}
{
<COUNT> "(" expression() ")"
| <AVG> "(" expression() ")"
| <MAX> "(" expression() ")"
| <MIN> "(" expression() ")"
| <SUM> "(" expression() ")"
}
void subq_fake_optional_compute_by_list() : {}
{
[ <BY> subq_fake_compute_by_list()]
}
void subq_fake_compute_by_list() : {}
{
subq_fake_compute_by_item()
( "," subq_fake_compute_by_item() )*
}
void subq_fake_compute_by_item() : {}
{
expression()
}
void subq_fake_cursor_update_list() : {}
{
[ <OF> subq_fake_cursor_column_list()]
}
void subq_fake_cursor_column_list() : {}
{
subq_fake_curs_upd_column()
( "," subq_fake_curs_upd_column() )*
}
void subq_fake_curs_upd_column() : {}
{
[ LOOKAHEAD([id_or_string()] ".") prefix_list() ] idplus()
}
void subq_fake_isolation_clause() : {}
{
[ <AT> <ISOLATION> isolation_lvl() ]
}
void compound_statement() : {}
{
<BEGIN> nullprogram() <END>
}
void nullprogram() : {}
{
[ program() ]
}
void program() : {}
{
( statement() )+
}
void declare() : {}
{
{int oldScope = setScope(SCOPE_DEFINE_VARIABLES);}
(LOOKAHEAD(2) declare_prefix() declaration_list()
| ( declare_prefix() declare_cursor() ) #SQLStatement )
{setScope(oldScope);}
}
void declare_cursor() : {Token t = null;}
{
t = idplus() {/*addStatementIdentifier(t.image);*/} cur_sensitivity() cur_scrollability() <CURSOR> <FOR> select()
}
void cur_sensitivity() : {}
{
[ UK_INSENSITIVE()
| UK_SEMI_SENSITIVE() ]
}
void cur_scrollability() : {}
{
[ UK_NO_SCROLL()
| UK_SCROLL() ]
}
void declare_prefix() #DeclareKeyword : {}
{
<DECLARE>
}
void fetch() : {}
{
fetch_orientation() fetch_val_spec() fetch_from_spec() object() fetch_into_clause()
}
void fetch_orientation() : {}
{
//Though weird, FIRST can be used as object name, so LOOKAHEAD(2)
<FETCH> [LOOKAHEAD(UK_NEXT() | UK_PRIOR() | UK_FIRST() | UK_LAST() | UK_ABSOLUTE() | UK_RELATIVE(), {getToken(2).kind != INTO && getToken(2).kind != FROM} ) ( UK_NEXT() | UK_PRIOR() | UK_FIRST() | UK_LAST() | UK_ABSOLUTE() | UK_RELATIVE() ) ]
}
void fetch_val_spec() : {Token t=null;}
{
[ t = <VAR_NAME>
| number()]
}
void fetch_into_clause() : {}
{
[ <INTO> fetch_into_list()]
}
void fetch_into_list() : {}
{
variable_assignment()
( "," variable_assignment() )*
}
void fetch_from_spec() : {}
{
[ <FROM> ]
}
void return_stmt() : {}
{
<RETURN> optional_expression()
}
void optional_expression() : {}
{
[ LOOKAHEAD(2) expression()]
}
void if_stmt() : {}
{
(if_prefix() statement() [ LOOKAHEAD(1) <ELSE> statement() ])
}
void if_prefix() : {}
{
<IF> boolean_expression()
}
void begin_tran() : {}
{
<BEGIN> tran() optional_xact_name()
}
void commit_tran() : {}
{
<COMMIT> tran_or_work() optional_xact_name()
}
void tran_or_work() : {}
{
[ <TRANSACTION>
| <TRAN>
| <WORK> ]
}
void tran() : {}
{
<TRANSACTION>
| <TRAN>
}
void rollback_tran() : {}
{
<ROLLBACK> tran_or_work() optional_xact_name()
}
void optional_xact_name() : {}
{
[ LOOKAHEAD(2) xact_name()]
}
void xact_name() : {}
{
<INTEGER_LITERAL> ":" <ID> "." <ID>
| id()
}
void checkpoint() : {}
{
<CHECKPOINT> optional_name_list_or_all()
}
void optional_name_list_or_all() : {}
{
UK_ALL()
| optional_name_list()
}
void optional_name_list() : {}
{
[LOOKAHEAD(2) name_list()]
}
void name_list() : {}
{
name_item()
( "," name_item() )*
}
void name_item() : {}
{
idplus()
| variable()
}
void print() : {}
{
<PRINT> pr_arglist()
}
void pr_arglist() : {}
{
printstring() arglist()
}
void arglist() : {}
{
( "," literal() )*
}
void printstring() : {}
{
string_literal()
| variable()
| null_stmt()
}
Token id_or_string() : {Token t;}
{
( t = idplus()
| t = string_literal()
)
{return t;}
}
//Special case: "NEW" can be used as id
Token idplus() : {Token t;}
{
( t = <ID>
| t = <TEMP_TABLE_NAME> //TEMP_TABLE_NAME can also be used as column name
| t = <SQUARE_BRACKET_ID>
)
{return t;}
}
void select_list() : {}
{
select_expression()
( "," select_expression() )*
}
void select_expression() : {}
{
LOOKAHEAD(<VAR_NAME> "=") ( select_or_set_variable_assignment())
| LOOKAHEAD(idplus() "=") idplus() "=" ( expression() | <IDENTITY> "(" <INTEGER_LITERAL> ")" )
| LOOKAHEAD(string_literal() "=") string_literal() "=" ( expression())
| "*"
| LOOKAHEAD(prefix_list() "*") prefix_list() "*"
| LOOKAHEAD(expression()) ( expression()) [LOOKAHEAD(2) (LOOKAHEAD(2)( optional_as() ( idplus() | string_literal() ) ) | "=" expression()) ]
//we have put java_memberref support in expression()
//| java_memberref() "=" expression()
}
void select_or_set_variable_assignment() : {}
{
variable_assignment() "=" expression()
}
void optional_as() : {}
{
[ <AS> ]
}
void subquery_select_expression() : {}
{
LOOKAHEAD(3) subq_expression_list()
| [ prefix_list() ] "*"
}
void declaration_list() : {}
{
declaration()
( comma() declaration() )*
}
void comma() #DeclareComma : {}
{
","
}
void declaration() #SQLParam: {Token name=null; String defaultValue=null; Node type=null; int direction = 0;}
{
try{
name = <VAR_NAME>
type = base_datatype()
defaultValue = optional_param_default()
direction = param_options()
}catch(ParseException e){
exceptions.add(e);
error_skiptobefore(new int[]{}, new int[]{COMMA, CLOSEPAREN, WITH, AS});
}
{
((ASTSQLParam)jjtThis).setName(name.image);
((ASTSQLParam)jjtThis).setType(type.toString());
((ASTSQLParam)jjtThis).setTypeObject((ASTSQLDataType)type);
if (defaultValue != null){
((ASTSQLParam)jjtThis).setDefaultValue(defaultValue);
}
((ASTSQLParam)jjtThis).setDirection(direction);
}
}
String optional_param_default() : {String t = null;}
{
[ "=" t = literal()]
{return t;}
}
int param_options() : {int direction = 0;}
{
[ <IN>
| out_option() {direction = 1;}]
{return direction;}
}
void out_option() : {}
{
<OUT>
| <OUTPUT>
}
void holdlock() : {}
{
[ <HOLDLOCK>
| <NOHOLDLOCK> ]
}
void shared() : {}
{
[ <SHARED> ]
}
void readpast() : {}
{
[ <READPAST> ]
}
void forceoptions() : {}
{
[ LOOKAHEAD(2) "(" [ LOOKAHEAD(2) <INTEGER_LITERAL> [ LOOKAHEAD(2) forceoption_terms() ] | <PARTITION> <ID> | forceoption_terms() ] ")" ]
}
void forceoption_terms() : {}
{
( forceoption_term() )+
}
void forceoption_term() : {}
{
forceindex()
| forcestrategy()
}
void forceindex() : {}
{
<INDEX> ( <INTEGER_LITERAL>
| idplus() )
}
void forcestrategy() : {}
{
<ID> [ number() ]
| "(" <ID> ( <ID> ")" | number() number() ")" )
}
void inner_join() : {}
{
[UK_INNER()] <JOIN>
}
void oj_operator() : {}
{
UK_LEFT() [UK_OUTER()] <JOIN>
| UK_RIGHT() [UK_OUTER()] <JOIN>
| inner_join()
}
void oj_expr() : {}
{
"(" oj_clause() ")"
}
void oj_clause() : {}
{
from_item() oj_operator() from_item() <ON> boolean_expression()
}
void from_where_clause() : {}
{
[ LOOKAHEAD(2) <WHERE> <CURRENT> <OF> object()
| from_clause() [ where_clause() ]
| where_clause() ]
}
void where_current_clause() : {}
{
[ LOOKAHEAD(2) <WHERE> <CURRENT> <OF> object()
| where_clause() ]
}
void from_clause() : {}
{
<FROM>
from_list()
}
void optional_from_clause() : {}
{
[ from_clause() ]
}
void from_list() : {}
{
from_table()
( "," from_table() {} )*
}
void from_table() : {}
{
{setScope("from_clause", SCOPE_TABLES);}
from_item()
{setScope("from_clause", SCOPE_DEFAULT);}
}
void from_item() : {String retval = null;}
{
(
LOOKAHEAD(from_unit())
retval = from_unit()
(
LOOKAHEAD(2) oj_operator() retval = from_unit()
<ON>
{setScope("from_item", SCOPE_COLUMNS);}
boolean_expression()
)*
|LOOKAHEAD(3) "(" retval = from_unit() ( LOOKAHEAD(2) oj_operator() retval = from_unit() <ON> boolean_expression() )+ ")"
)
}
String from_unit() : {String retval = null; Token aliasNameToken = null;}
{
( retval = table_object()
( [LOOKAHEAD({(getToken(1).kind == AS || getToken(1).kind == ID) && !(getToken(1).image.equalsIgnoreCase("inner") || getToken(1).image.equalsIgnoreCase("left") || getToken(1).image.equalsIgnoreCase("right"))})
optional_as() aliasNameToken = idplus() ] forceoptions() holdlock() readpast() shared() )
| "(" select() ")" optional_as() derived_table_name() optional_derived_col_name_list() holdlock() readpast() shared()
)
{
String aliasName = null;
if (aliasNameToken != null)
aliasName = aliasNameToken.image;
result.addCurrentTables(retval, aliasName, isContentAssist);
}
{return retval;}
}
void derived_table_name() : {}
{
[LOOKAHEAD({!(getToken(1).image.equalsIgnoreCase("inner") || getToken(1).image.equalsIgnoreCase("left") || getToken(1).image.equalsIgnoreCase("right"))}) idplus()]
}
void optional_derived_col_name_list() : {}
{
[ LOOKAHEAD(2) "(" derived_column_list() ")" ]
}
void derived_column_list() : {}
{
derived_col_name()
( "," derived_col_name() )*
}
void derived_col_name() : {}
{
idplus()
}
void where_clause() : {setScope("from_clause", SCOPE_COLUMNS);}
{
<WHERE> boolean_expression()
{setScope("where_clause", SCOPE_DEFAULT);}
}
void boolean_expression() : {}
{
boolean_term() ( <OR> boolean_term() )*
}
void boolean_term() : {}
{
boolean_factor() ( <AND> boolean_factor() )*
}
void boolean_factor() : {}
{
boolean_primary()
| <NOT> boolean_primary()
}
void boolean_primary() : {}
{
boolean_function()
| LOOKAHEAD ("(" boolean_expression() ")" ) "(" boolean_expression() ")"
| predicate()
}
void group_by_clause() : {}
{
[ <GROUP> <BY> by_all() group_by_list() ]
}
void by_all() : {}
{
[ UK_ALL() ]
}
void group_by_list() : {}
{
group_by_item()
( "," group_by_item() )*
}
void group_by_item() : {}
{
{setScope("group_clause", SCOPE_COLUMNS);}
expression()
{setScope("group_clause", SCOPE_DEFAULT);}
}
void having_clause() : {}
{
[ <HAVING> {setScope("having_clause", SCOPE_COLUMNS);} boolean_expression() {setScope("having_clause", SCOPE_DEFAULT);}]
}
void order_by_clause() : {}
{
[ <ORDER> <BY> order_by_list() ]
}
void order_by_list() : {}
{
order_by_item()
( "," order_by_item() )*
}
void order_by_item() : {setScope("order_by_clause", SCOPE_COLUMNS);}
{
expression() [ order_by_option() ]{setScope("order_by_clause", SCOPE_DEFAULT);}
}
void order_by_option() : {}
{
<ASC>
| <DESC>
}
void compute_clause() : {}
{
[ compute_statement_list()]
}
void compute_statement_list() : {}
{
compute_statement()
( compute_statement() )*
}
void compute_statement() : {}
{
<COMPUTE> compute_list()
{setScope("compute_statement", SCOPE_DEFAULT);}
optional_compute_by_list()
}
void compute_list() : {}
{
compute_function()
( "," compute_function() )*
}
void compute_function() : {}
{
<COUNT> "("
{setScope("compute_function", SCOPE_COLUMNS);}
expression()
")"
| <AVG> "("
{setScope("compute_function", SCOPE_COLUMNS);}
expression()
")"
| <MAX> "("
{setScope("compute_function", SCOPE_COLUMNS);}
expression()
")"
| <MIN> "("
{setScope("compute_function", SCOPE_COLUMNS);}
expression()
")"
| <SUM> "("
{setScope("compute_function", SCOPE_COLUMNS);}
expression()
")"
}
void optional_compute_by_list() : {}
{
[ <BY> compute_by_list()]
}
void compute_by_list() : {}
{
compute_by_item()
( "," compute_by_item() )*
}
void compute_by_item() : {}
{
{setScope("compute_by_item", SCOPE_COLUMNS);}
expression()
}
void predicate() : {}
{
LOOKAHEAD(<EXISTS>) exists_predicate() //starts with exists
| LOOKAHEAD( ("(")+ <SELECT> | expression() ) (expression()
(
LOOKAHEAD( comp_op() <ANY> ) any_predicate()
| LOOKAHEAD( comp_op() UK_ALL() ) all_predicate()
| LOOKAHEAD( comp_op() | join_op() ) comparison_predicate()
| LOOKAHEAD( [ <NOT> ] <BETWEEN> ) between_predicate()
| LOOKAHEAD( <IS> [ <NOT> ] ) null_predicate()
| LOOKAHEAD([ <NOT> ] <IN> ) in_predicate()
| LOOKAHEAD([ <NOT> ] <LIKE> ) like_predicate()
)
)
| LOOKAHEAD( row_constructor()) row_constructor() row_comparison_predicate()
}
void predicate_op() : {}
{
<EXISTS>
| LOOKAHEAD( expression() (comp_op() | join_op() | [ <NOT> ] ( <BETWEEN> | <IN> | <LIKE> ) | <IS> )) expression() (comp_op() | join_op() | [ <NOT> ] ( <BETWEEN> | <IN> | <LIKE> ) | <IS> )
| row_constructor() ( comp_op() | join_op() )
}
void comparison_predicate() : {}
{
( comp_op() | join_op() ) expression()
}
void row_comparison_predicate() : {}
{
comp_op() row_constructor()
}
void comp_op() : {}
{
"="
| "!" [ ">" | "=" | "<" ]
| "!>" | "!=" | "!<"
| ">" [ "=" ]
| ">="
| "<" [ ">" | "=" ]
| "<>" | "<="
}
void join_op() : {}
{
<LEQJOIN>
| <REQJOIN>
}
void between_predicate() : {}
{
[ <NOT> ] <BETWEEN> expression() <AND> expression()
}
void null_predicate() : {}
{
<IS> [ <NOT> ] null_stmt()
}
void in_predicate() : {}
{
[ <NOT> ] <IN> "(" ( in_value_list() | <SELECT> subq_select() ) ")"
}
void in_value_list() : {}
{
expression()
( "," expression() )*
}
void any_predicate() : {}
{
comp_op() <ANY> subquery()
}
void all_predicate() : {}
{
comp_op() UK_ALL() subquery()
}
void exists_predicate() : {}
{
<EXISTS> subquery()
}
void like_predicate() : {}
{
[ <NOT> ] <LIKE> pattern_clause()
}
void pattern_clause() : {}
{
expression() escape_clause()
}
void escape_clause() : {}
{
[ <ESCAPE> expression()]
}
void row_constructor() : {}
{
"(" row_constructor_list() ")"
}
void row_constructor_list() : {}
{
row_constructor_elem()
( "," row_constructor_elem() )*
}
void row_constructor_elem() : {}
{
expression()
}
ASTExpression expression() #Expression: {}
{
term() (LOOKAHEAD(3) ( LOOKAHEAD(3) "|" "|"
| LOOKAHEAD(2) "+"
| LOOKAHEAD(2) "-"
| LOOKAHEAD(2) "&"
| LOOKAHEAD(2) "|"
| LOOKAHEAD(2) "^" ) term()
)*
{
return jjtThis;
}
}
void term() : {}
{
factor() ( "*" factor()
| "/" factor()
| "%" factor()
)*
}
void factor() : {}
{
[ "~" ] subfactor()
}
void subfactor() : {}
{
[ "+" | "-" ] primary()
}
void primary_1() : {}
{
LOOKAHEAD(constant()) constant()
| LOOKAHEAD("(" <SELECT>) subquery()
| LOOKAHEAD(function()) function()
| LOOKAHEAD(column()) column()
| case_expression()
| "(" expression() ")"
}
//supports javaname>>javaref
void primary() : {}
{
primary_1() ( LOOKAHEAD(2) ( <DOT> | <JAVA_REF> ) id_or_string() [ LOOKAHEAD(2) "(" expression_list() ")" ] )*
}
void case_expression() : {}
{
case_abbreviation()
| case_specification()
}
void case_abbreviation() : {}
{
nullif_format()
| coalesce_format()
}
void case_specification() : {}
{
<CASE> simple_or_searched_case()
}
void simple_or_searched_case() : {}
{
simple_case()
| searched_case()
}
void simple_case() : {}
{
expression() simple_when_clause_list() optional_else_clause() <END>
}
void searched_case() : {}
{
searched_when_clause_list() optional_else_clause() <END>
}
void simple_when_clause_list() : {}
{
simple_when_clause()
( simple_when_clause() )*
}
void simple_when_clause() : {}
{
<WHEN> expression() UK_THEN() result()
}
void searched_when_clause_list() : {}
{
searched_when_clause()
( searched_when_clause() )*
}
void searched_when_clause() : {}
{
<WHEN> boolean_expression() UK_THEN() result()
}
void optional_else_clause() : {}
{
[ <ELSE> result()]
}
void result() : {}
{
expression()
}
void coalesce_format() : {}
{
<COALESCE> "(" coalesce_list() ")"
}
void coalesce_list() : {}
{
coalesce_element()
( "," coalesce_element() )*
}
void coalesce_element() : {}
{
expression()
}
void nullif_format() : {}
{
<NULLIF> "(" expression() "," expression() ")"
}
//database object such as: table, procedure, view, cursor...
String object() : {String retval = ""; Token t;}
{
[ LOOKAHEAD([id_or_string()] ".") retval = prefix_list() ] t = id_or_string()
{return retval + t.image;}
}
String table_object() : {String retval = "";}
{
retval = qualified_name()
{result.addCurrentTables(retval, null, isContentAssist);}
{return retval;}
}
String qualified_name() : {String retval = ""; Token t=null;}
{
[ LOOKAHEAD([id_or_string()] ".") retval = prefix_list() ] ( t = id_or_string() )
{return retval + t.image;}
}
void procedure() : {}
{
proc_name()
}
String proc_name() : {String s = null; Token t = null;}
{
( s = object()
| t = variable()
)
{
if ( t != null )
{
s = t.image;
}
return s;
}
}
void column() : {}
{
LOOKAHEAD(prefix_list()) prefix_list() ( id_or_string() )
| idplus()
}
String prefix_list() : {String retval = "", pre = ""; }
{
( LOOKAHEAD([id_or_string() ] ".") pre = prefix() {retval += pre;} )+
{return retval;}
}
String prefix() : {Token t = null;}
{
( "."
| (t = id_or_string() ) "."
)
{return t == null?".":t.image + ".";}
}
Token id() : {Token t = null;}
{
(t = idplus()
| t = variable()
)
{return t;}
}
void string() : {}
{
string_literal()
| variable()
}
void id_string() : {}
{
idplus()
| <DOUBLE_STRING_LITERAL>
| variable()
}
void integer() : {}
{
<INTEGER_LITERAL>
| variable()
}
int number() : {int retval = 0;}
{
( "-" <INTEGER_LITERAL> {try {retval = Integer.parseInt("-" + getToken(0).image);}catch(Exception e){}}
| [ "+" ] <INTEGER_LITERAL> {try {retval = Integer.parseInt(getToken(0).image);}catch(Exception e){}}
)
{return retval;}
}
void constant() : {}
{
signed_const()
| unsigned_const()
}
Token signed_const() : {Token t;}
{
( t = <INTEGER_LITERAL>
| t = <FLOATING_POINT_LITERAL>
| t = <MONEY_LITERAL>
)
{return t;}
}
Token unsigned_const() : {Token t;}
{
( t = <BINARY_LITERAL>
| t = string_literal()
| t = null_stmt()
| t = variable()
)
{return t;}
}
String literal() : {Token t; boolean negative = false;}
{
( [ "+" | "-" { negative = true;} ] t = signed_const()
| t = unsigned_const()
| t = idplus()
| t = <PRIMARY>
| t = <FOREIGN>
)
{return negative?"-"+t.image:t.image;}
}
void binary() : {}
{
UK_BINARY()
| variable()
}
Token null_stmt() : {Token t;}
{
t = <NULL>
{return t;}
}
//variable reference
Token variable() : {Token t;}
{
( t = <VAR_NAME>
| t = dyn_question_mark()
| t = <GLOBAL_VAR_NAME>
)
{return t;}
}
Token variable_assignment() : {Token t;}
{
( t = <VAR_NAME>
)
{return t;}
}
Token dyn_question_mark() : {Token t;}
{
t = <QUESTIONMARK>
{return t;}
}
//include field reference and method reference
void java_memberref() : {}
{
primary_1() ( LOOKAHEAD(3) ( <DOT> | <JAVA_REF> ) id_or_string() [ "(" expression_list() ")" ] )*
}
void function() : {}
{
java_constructor()
| LOOKAHEAD(2) builtin_function()
| LOOKAHEAD(2) agg_function()
}
void builtin_function() : {}
{
<CONVERT> "(" datatype() [<NULL>] "," expression() optional_comma_argument() ")"
| <USER>
| [LOOKAHEAD(2) prefix_list()] id_or_string() "(" expression_list() optional_using_clause() ")"
}
void java_constructor() : {}
{
UK_NEW() java_name() "(" expression_list() ")"
}
void subq_expression_list() : {}
{
subq_expression()
( "," subq_expression() )*
}
void subq_expression() : {}
{
LOOKAHEAD(2) idplus() "=" [ expression() | <IDENTITY> "(" <INTEGER_LITERAL> ")" ]
| LOOKAHEAD(2) expression() [ optional_as() ( idplus() | string_literal() ) ]
| LOOKAHEAD(2) string_literal() "=" expression()
}
void expression_list() : {}
{
[LOOKAHEAD(2) expression()
( LOOKAHEAD(2) "," expression() )* ]
}
void optional_using_clause() : {}
{
[ "," [ <USING> <ID>]
| <AS> datatype()
]
}
void optional_comma_argument() : {}
{
[ "," expression()]
}
void agg_function() : {}
{
agg_function_specification()
}
void agg_function_specification() : {}
{
<COUNT> "(" ( "*" | ( <DISTINCT> | all() ) expression() ) ")"
| <AVG> "(" ( ( <DISTINCT> | all() ) expression() ) ")"
| <MAX> "(" ( ( <DISTINCT> | all() ) expression() ) ")"
| <MIN> "(" ( ( <DISTINCT> | all() ) expression() ) ")"
| <SUM> "(" ( ( <DISTINCT> | all() ) expression() ) ")"
}
void all() : {}
{
[ UK_ALL() ]
}
void boolean_function() : {}
{
<UPDATE> "(" idplus() ")"
}
void create_trigger():{}{
try{ <CREATE> UK_TRIGGER() qualified_name() trigtime() simpletrigevent() [UK_OF() collist() ]<ON> qualified_name() [referencing() ]<FOR> UK_EACH() (UK_ROW() | UK_STATEMENT() )UK_MODE() UK_DB2SQL() statement()
}catch(ParseException e){
knownExceptions.add(e);
//error recovery
error_skiptobefore(new int []{END}, STMT_START_TERMINATORS);
}
}
void trigtime() :{}{ UK_AFTER() | (<NO> <CASCADE> UK_BEFORE() ) } void simpletrigevent() :{}{ <INSERT> | <DELETE> | <UPDATE> } void collist() :{}{ qualified_name() (LOOKAHEAD(2) "," qualified_name() )* } void referencing() :{}{ UK_REFERENCING() reflist() } void reflist() :{}{ (reftype() <AS> qualified_name() )+ } void reftype() :{}{ UK_OLD() | UK_NEW() | UK_OLD_TABLE() | UK_NEW_TABLE() }
JAVACODE
/**
* Skips the subsequent tokens when parsing error occurrs.
* The process will continue until the current consumed token matches <code>tokinds</code>
* or the next token to be consumed matches <code>beforekinds</code>.
*/
void error_skiptobefore(int[] tokinds, int[] beforekinds) {
boolean match = false;
Token t1 = getToken(0);
// The following loop consumes tokens all the way up to a token of
// "kind". We use a do-while loop rather than a while because the
// current token is the one immediately before the erroneous token
// (in our case the token immediately before what should have been
// "if"/"while".
do {
match = token.kind == 0 || getToken(1).kind == 0 ; // 0 means the <EOF>
if (match) {break;}
for (int i=0; i< tokinds.length; i++){
match = match || token.kind == tokinds[i];
if (match) {break;}
}
if (match) {break;}
for (int i=0; i< beforekinds.length; i++){
match = match || getToken(1).kind == beforekinds[i];
if (match) {break;}
}
if (!match){
logDebug("current token:" + token.image);
getNextToken() ;
}
} while (!match);
Token t2 = getToken(0);
if (t1 == t2 ){
//force get next token
logDebug("current token:" + token.image);
getNextToken() ;
}
}