| /******************************************************************************* |
| * 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() ; |
| } |
| } |
| |