/* * Copyright 1999-2012 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * (created at 2011-5-19) */ package com.alibaba.cobar.parser.recognizer.mysql.syntax; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.IDENTIFIER; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_CHARACTER; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_COLLATE; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_DEFAULT; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_DESC; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_DESCRIBE; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_FOR; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_FROM; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_IN; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_LIKE; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_LIMIT; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_OPTION; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_READ; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_SET; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_SHOW; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_WHERE; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.OP_ASSIGN; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.OP_ASTERISK; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.OP_EQUALS; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.PUNC_COMMA; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.PUNC_LEFT_PAREN; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.PUNC_RIGHT_PAREN; import java.sql.SQLSyntaxErrorException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.alibaba.cobar.parser.ast.expression.Expression; import com.alibaba.cobar.parser.ast.expression.primary.Identifier; import com.alibaba.cobar.parser.ast.expression.primary.SysVarPrimary; import com.alibaba.cobar.parser.ast.expression.primary.UsrDefVarPrimary; import com.alibaba.cobar.parser.ast.expression.primary.VariableExpression; import com.alibaba.cobar.parser.ast.expression.primary.literal.LiteralString; import com.alibaba.cobar.parser.ast.fragment.Limit; import com.alibaba.cobar.parser.ast.fragment.VariableScope; import com.alibaba.cobar.parser.ast.stmt.SQLStatement; import com.alibaba.cobar.parser.ast.stmt.dal.DALSetCharacterSetStatement; import com.alibaba.cobar.parser.ast.stmt.dal.DALSetNamesStatement; import com.alibaba.cobar.parser.ast.stmt.dal.DALSetStatement; import com.alibaba.cobar.parser.ast.stmt.dal.DALShowStatement; import com.alibaba.cobar.parser.ast.stmt.dal.ShowAuthors; import com.alibaba.cobar.parser.ast.stmt.dal.ShowBinLogEvent; import com.alibaba.cobar.parser.ast.stmt.dal.ShowBinaryLog; import com.alibaba.cobar.parser.ast.stmt.dal.ShowCharaterSet; import com.alibaba.cobar.parser.ast.stmt.dal.ShowCollation; import com.alibaba.cobar.parser.ast.stmt.dal.ShowColumns; import com.alibaba.cobar.parser.ast.stmt.dal.ShowContributors; import com.alibaba.cobar.parser.ast.stmt.dal.ShowCreate; import com.alibaba.cobar.parser.ast.stmt.dal.ShowDatabases; import com.alibaba.cobar.parser.ast.stmt.dal.ShowEngine; import com.alibaba.cobar.parser.ast.stmt.dal.ShowEngines; import com.alibaba.cobar.parser.ast.stmt.dal.ShowErrors; import com.alibaba.cobar.parser.ast.stmt.dal.ShowEvents; import com.alibaba.cobar.parser.ast.stmt.dal.ShowFunctionCode; import com.alibaba.cobar.parser.ast.stmt.dal.ShowFunctionStatus; import com.alibaba.cobar.parser.ast.stmt.dal.ShowGrants; import com.alibaba.cobar.parser.ast.stmt.dal.ShowIndex; import com.alibaba.cobar.parser.ast.stmt.dal.ShowMasterStatus; import com.alibaba.cobar.parser.ast.stmt.dal.ShowOpenTables; import com.alibaba.cobar.parser.ast.stmt.dal.ShowPlugins; import com.alibaba.cobar.parser.ast.stmt.dal.ShowPrivileges; import com.alibaba.cobar.parser.ast.stmt.dal.ShowProcedureCode; import com.alibaba.cobar.parser.ast.stmt.dal.ShowProcedureStatus; import com.alibaba.cobar.parser.ast.stmt.dal.ShowProcesslist; import com.alibaba.cobar.parser.ast.stmt.dal.ShowProfile; import com.alibaba.cobar.parser.ast.stmt.dal.ShowProfiles; import com.alibaba.cobar.parser.ast.stmt.dal.ShowSlaveHosts; import com.alibaba.cobar.parser.ast.stmt.dal.ShowSlaveStatus; import com.alibaba.cobar.parser.ast.stmt.dal.ShowStatus; import com.alibaba.cobar.parser.ast.stmt.dal.ShowTableStatus; import com.alibaba.cobar.parser.ast.stmt.dal.ShowTables; import com.alibaba.cobar.parser.ast.stmt.dal.ShowTriggers; import com.alibaba.cobar.parser.ast.stmt.dal.ShowVariables; import com.alibaba.cobar.parser.ast.stmt.dal.ShowWarnings; import com.alibaba.cobar.parser.ast.stmt.ddl.DescTableStatement; import com.alibaba.cobar.parser.ast.stmt.mts.MTSSetTransactionStatement; import com.alibaba.cobar.parser.recognizer.mysql.lexer.MySQLLexer; import com.alibaba.cobar.parser.util.Pair; /** * @author <a href="mailto:shuo.qius@alibaba-inc.com">QIU Shuo</a> */ public class MySQLDALParser extends MySQLParser { protected MySQLExprParser exprParser; public MySQLDALParser(MySQLLexer lexer, MySQLExprParser exprParser) { super(lexer); this.exprParser = exprParser; } private static enum SpecialIdentifier { AUTHORS, BINLOG, BLOCK, CODE, COLLATION, COLUMNS, COMMITTED, CONTEXT, CONTRIBUTORS, COUNT, CPU, ENGINE, ENGINES, ERRORS, EVENT, EVENTS, FULL, FUNCTION, GLOBAL, GRANTS, HOSTS, INDEXES, INNODB, IPC, LOCAL, MASTER, MEMORY, MUTEX, NAMES, OPEN, PAGE, PERFORMANCE_SCHEMA, PLUGINS, PRIVILEGES, PROCESSLIST, PROFILE, PROFILES, REPEATABLE, SERIALIZABLE, SESSION, SLAVE, SOURCE, STATUS, STORAGE, SWAPS, TABLES, TRANSACTION, TRIGGERS, UNCOMMITTED, VARIABLES, VIEW, WARNINGS } private static final Map<String, SpecialIdentifier> specialIdentifiers = new HashMap<String, SpecialIdentifier>(); static { specialIdentifiers.put("AUTHORS", SpecialIdentifier.AUTHORS); specialIdentifiers.put("BINLOG", SpecialIdentifier.BINLOG); specialIdentifiers.put("COLLATION", SpecialIdentifier.COLLATION); specialIdentifiers.put("COLUMNS", SpecialIdentifier.COLUMNS); specialIdentifiers.put("CONTRIBUTORS", SpecialIdentifier.CONTRIBUTORS); specialIdentifiers.put("EVENT", SpecialIdentifier.EVENT); specialIdentifiers.put("FUNCTION", SpecialIdentifier.FUNCTION); specialIdentifiers.put("VIEW", SpecialIdentifier.VIEW); specialIdentifiers.put("ENGINE", SpecialIdentifier.ENGINE); specialIdentifiers.put("ENGINES", SpecialIdentifier.ENGINES); specialIdentifiers.put("ERRORS", SpecialIdentifier.ERRORS); specialIdentifiers.put("EVENTS", SpecialIdentifier.EVENTS); specialIdentifiers.put("FULL", SpecialIdentifier.FULL); specialIdentifiers.put("GLOBAL", SpecialIdentifier.GLOBAL); specialIdentifiers.put("GRANTS", SpecialIdentifier.GRANTS); specialIdentifiers.put("MASTER", SpecialIdentifier.MASTER); specialIdentifiers.put("OPEN", SpecialIdentifier.OPEN); specialIdentifiers.put("PLUGINS", SpecialIdentifier.PLUGINS); specialIdentifiers.put("CODE", SpecialIdentifier.CODE); specialIdentifiers.put("STATUS", SpecialIdentifier.STATUS); specialIdentifiers.put("PRIVILEGES", SpecialIdentifier.PRIVILEGES); specialIdentifiers.put("PROCESSLIST", SpecialIdentifier.PROCESSLIST); specialIdentifiers.put("PROFILE", SpecialIdentifier.PROFILE); specialIdentifiers.put("PROFILES", SpecialIdentifier.PROFILES); specialIdentifiers.put("SESSION", SpecialIdentifier.SESSION); specialIdentifiers.put("SLAVE", SpecialIdentifier.SLAVE); specialIdentifiers.put("STORAGE", SpecialIdentifier.STORAGE); specialIdentifiers.put("TABLES", SpecialIdentifier.TABLES); specialIdentifiers.put("TRIGGERS", SpecialIdentifier.TRIGGERS); specialIdentifiers.put("VARIABLES", SpecialIdentifier.VARIABLES); specialIdentifiers.put("WARNINGS", SpecialIdentifier.WARNINGS); specialIdentifiers.put("INNODB", SpecialIdentifier.INNODB); specialIdentifiers.put("PERFORMANCE_SCHEMA", SpecialIdentifier.PERFORMANCE_SCHEMA); specialIdentifiers.put("MUTEX", SpecialIdentifier.MUTEX); specialIdentifiers.put("COUNT", SpecialIdentifier.COUNT); specialIdentifiers.put("BLOCK", SpecialIdentifier.BLOCK); specialIdentifiers.put("CONTEXT", SpecialIdentifier.CONTEXT); specialIdentifiers.put("CPU", SpecialIdentifier.CPU); specialIdentifiers.put("MEMORY", SpecialIdentifier.MEMORY); specialIdentifiers.put("PAGE", SpecialIdentifier.PAGE); specialIdentifiers.put("SOURCE", SpecialIdentifier.SOURCE); specialIdentifiers.put("SWAPS", SpecialIdentifier.SWAPS); specialIdentifiers.put("IPC", SpecialIdentifier.IPC); specialIdentifiers.put("LOCAL", SpecialIdentifier.LOCAL); specialIdentifiers.put("HOSTS", SpecialIdentifier.HOSTS); specialIdentifiers.put("INDEXES", SpecialIdentifier.INDEXES); specialIdentifiers.put("TRANSACTION", SpecialIdentifier.TRANSACTION); specialIdentifiers.put("UNCOMMITTED", SpecialIdentifier.UNCOMMITTED); specialIdentifiers.put("COMMITTED", SpecialIdentifier.COMMITTED); specialIdentifiers.put("REPEATABLE", SpecialIdentifier.REPEATABLE); specialIdentifiers.put("SERIALIZABLE", SpecialIdentifier.SERIALIZABLE); specialIdentifiers.put("NAMES", SpecialIdentifier.NAMES); } public DescTableStatement desc() throws SQLSyntaxErrorException { match(KW_DESC, KW_DESCRIBE); Identifier table = identifier(); return new DescTableStatement(table); } public DALShowStatement show() throws SQLSyntaxErrorException { match(KW_SHOW); String tempStr; String tempStrUp; Expression tempExpr; Identifier tempId; SpecialIdentifier tempSi; Limit tempLimit; switch (lexer.token()) { case KW_BINARY: lexer.nextToken(); matchIdentifier("LOGS"); return new ShowBinaryLog(); case KW_CHARACTER: lexer.nextToken(); match(KW_SET); switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowCharaterSet(tempStr); case KW_WHERE: tempExpr = where(); return new ShowCharaterSet(tempExpr); default: return new ShowCharaterSet(); } case KW_CREATE: ShowCreate.Type showCreateType; switch1: switch (lexer.nextToken()) { case KW_DATABASE: showCreateType = ShowCreate.Type.DATABASE; break; case KW_PROCEDURE: showCreateType = ShowCreate.Type.PROCEDURE; break; case KW_TABLE: showCreateType = ShowCreate.Type.TABLE; break; case KW_TRIGGER: showCreateType = ShowCreate.Type.TRIGGER; break; case IDENTIFIER: tempSi = specialIdentifiers.get(lexer.stringValueUppercase()); if (tempSi != null) { switch (tempSi) { case EVENT: showCreateType = ShowCreate.Type.EVENT; break switch1; case FUNCTION: showCreateType = ShowCreate.Type.FUNCTION; break switch1; case VIEW: showCreateType = ShowCreate.Type.VIEW; break switch1; } } default: throw err("unexpect token for SHOW CREATE"); } lexer.nextToken(); tempId = identifier(); return new ShowCreate(showCreateType, tempId); case KW_SCHEMAS: case KW_DATABASES: lexer.nextToken(); switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowDatabases(tempStr); case KW_WHERE: tempExpr = where(); return new ShowDatabases(tempExpr); } return new ShowDatabases(); case KW_KEYS: return showIndex(ShowIndex.Type.KEYS); case KW_INDEX: return showIndex(ShowIndex.Type.INDEX); case KW_PROCEDURE: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case CODE: lexer.nextToken(); tempId = identifier(); return new ShowProcedureCode(tempId); case STATUS: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowProcedureStatus(tempStr); case KW_WHERE: tempExpr = where(); return new ShowProcedureStatus(tempExpr); default: return new ShowProcedureStatus(); } } } throw err("unexpect token for SHOW PROCEDURE"); case KW_TABLE: lexer.nextToken(); matchIdentifier("STATUS"); tempId = null; if (lexer.token() == KW_FROM || lexer.token() == KW_IN) { lexer.nextToken(); tempId = identifier(); } switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowTableStatus(tempId, tempStr); case KW_WHERE: tempExpr = where(); return new ShowTableStatus(tempId, tempExpr); } return new ShowTableStatus(tempId); case IDENTIFIER: tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi == null) { break; } switch (tempSi) { case INDEXES: return showIndex(ShowIndex.Type.INDEXES); case GRANTS: if (lexer.nextToken() == KW_FOR) { lexer.nextToken(); tempExpr = exprParser.expression(); return new ShowGrants(tempExpr); } return new ShowGrants(); case AUTHORS: lexer.nextToken(); return new ShowAuthors(); case BINLOG: lexer.nextToken(); matchIdentifier("EVENTS"); tempStr = null; tempExpr = null; tempLimit = null; if (lexer.token() == KW_IN) { lexer.nextToken(); tempStr = lexer.stringValue(); lexer.nextToken(); } if (lexer.token() == KW_FROM) { lexer.nextToken(); tempExpr = exprParser.expression(); } if (lexer.token() == KW_LIMIT) { tempLimit = limit(); } return new ShowBinLogEvent(tempStr, tempExpr, tempLimit); case COLLATION: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowCollation(tempStr); case KW_WHERE: tempExpr = where(); return new ShowCollation(tempExpr); } return new ShowCollation(); case COLUMNS: return showColumns(false); case CONTRIBUTORS: lexer.nextToken(); return new ShowContributors(); case ENGINE: switch (lexer.nextToken()) { case IDENTIFIER: tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case INNODB: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case STATUS: lexer.nextToken(); return new ShowEngine(ShowEngine.Type.INNODB_STATUS); case MUTEX: lexer.nextToken(); return new ShowEngine(ShowEngine.Type.INNODB_MUTEX); } } case PERFORMANCE_SCHEMA: lexer.nextToken(); matchIdentifier("STATUS"); return new ShowEngine(ShowEngine.Type.PERFORMANCE_SCHEMA_STATUS); } } default: throw err("unexpect token for SHOW ENGINE"); } case ENGINES: lexer.nextToken(); return new ShowEngines(); case ERRORS: lexer.nextToken(); tempLimit = limit(); return new ShowErrors(false, tempLimit); case COUNT: lexer.nextToken(); match(PUNC_LEFT_PAREN); match(OP_ASTERISK); match(PUNC_RIGHT_PAREN); switch (matchIdentifier("ERRORS", "WARNINGS")) { case 0: return new ShowErrors(true, null); case 1: return new ShowWarnings(true, null); } case EVENTS: tempId = null; switch (lexer.nextToken()) { case KW_IN: case KW_FROM: lexer.nextToken(); tempId = identifier(); } switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowEvents(tempId, tempStr); case KW_WHERE: tempExpr = where(); return new ShowEvents(tempId, tempExpr); default: return new ShowEvents(tempId); } case FULL: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case COLUMNS: return showColumns(true); case PROCESSLIST: lexer.nextToken(); return new ShowProcesslist(true); case TABLES: tempId = null; switch (lexer.nextToken()) { case KW_IN: case KW_FROM: lexer.nextToken(); tempId = identifier(); } switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowTables(true, tempId, tempStr); case KW_WHERE: tempExpr = where(); return new ShowTables(true, tempId, tempExpr); default: return new ShowTables(true, tempId); } } } throw err("unexpected token for SHOW FULL"); case FUNCTION: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case CODE: lexer.nextToken(); tempId = identifier(); return new ShowFunctionCode(tempId); case STATUS: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowFunctionStatus(tempStr); case KW_WHERE: tempExpr = where(); return new ShowFunctionStatus(tempExpr); default: return new ShowFunctionStatus(); } } } throw err("unexpected token for SHOW FUNCTION"); case GLOBAL: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case STATUS: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowStatus(VariableScope.GLOBAL, tempStr); case KW_WHERE: tempExpr = where(); return new ShowStatus(VariableScope.GLOBAL, tempExpr); default: return new ShowStatus(VariableScope.GLOBAL); } case VARIABLES: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowVariables(VariableScope.GLOBAL, tempStr); case KW_WHERE: tempExpr = where(); return new ShowVariables(VariableScope.GLOBAL, tempExpr); default: return new ShowVariables(VariableScope.GLOBAL); } } } throw err("unexpected token for SHOW GLOBAL"); case MASTER: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null && tempSi == SpecialIdentifier.STATUS) { lexer.nextToken(); return new ShowMasterStatus(); } matchIdentifier("LOGS"); return new ShowBinaryLog(); case OPEN: lexer.nextToken(); matchIdentifier("TABLES"); tempId = null; switch (lexer.token()) { case KW_IN: case KW_FROM: lexer.nextToken(); tempId = identifier(); } switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowOpenTables(tempId, tempStr); case KW_WHERE: tempExpr = where(); return new ShowOpenTables(tempId, tempExpr); default: return new ShowOpenTables(tempId); } case PLUGINS: lexer.nextToken(); return new ShowPlugins(); case PRIVILEGES: lexer.nextToken(); return new ShowPrivileges(); case PROCESSLIST: lexer.nextToken(); return new ShowProcesslist(false); case PROFILE: return showProfile(); case PROFILES: lexer.nextToken(); return new ShowProfiles(); case LOCAL: case SESSION: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case STATUS: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowStatus(VariableScope.SESSION, tempStr); case KW_WHERE: tempExpr = where(); return new ShowStatus(VariableScope.SESSION, tempExpr); default: return new ShowStatus(VariableScope.SESSION); } case VARIABLES: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowVariables(VariableScope.SESSION, tempStr); case KW_WHERE: tempExpr = where(); return new ShowVariables(VariableScope.SESSION, tempExpr); default: return new ShowVariables(VariableScope.SESSION); } } } throw err("unexpected token for SHOW SESSION"); case SLAVE: lexer.nextToken(); tempStrUp = lexer.stringValueUppercase(); tempSi = specialIdentifiers.get(tempStrUp); if (tempSi != null) { switch (tempSi) { case HOSTS: lexer.nextToken(); return new ShowSlaveHosts(); case STATUS: lexer.nextToken(); return new ShowSlaveStatus(); } } throw err("unexpected token for SHOW SLAVE"); case STATUS: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowStatus(VariableScope.SESSION, tempStr); case KW_WHERE: tempExpr = where(); return new ShowStatus(VariableScope.SESSION, tempExpr); default: return new ShowStatus(VariableScope.SESSION); } case STORAGE: lexer.nextToken(); matchIdentifier("ENGINES"); return new ShowEngines(); case TABLES: tempId = null; switch (lexer.nextToken()) { case KW_IN: case KW_FROM: lexer.nextToken(); tempId = identifier(); } switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowTables(false, tempId, tempStr); case KW_WHERE: tempExpr = where(); return new ShowTables(false, tempId, tempExpr); default: return new ShowTables(false, tempId); } case TRIGGERS: tempId = null; switch (lexer.nextToken()) { case KW_IN: case KW_FROM: lexer.nextToken(); tempId = identifier(); } switch (lexer.token()) { case KW_LIKE: tempStr = like(); return new ShowTriggers(tempId, tempStr); case KW_WHERE: tempExpr = where(); return new ShowTriggers(tempId, tempExpr); default: return new ShowTriggers(tempId); } case VARIABLES: switch (lexer.nextToken()) { case KW_LIKE: tempStr = like(); return new ShowVariables(VariableScope.SESSION, tempStr); case KW_WHERE: tempExpr = where(); return new ShowVariables(VariableScope.SESSION, tempExpr); default: return new ShowVariables(VariableScope.SESSION); } case WARNINGS: lexer.nextToken(); tempLimit = limit(); return new ShowWarnings(false, tempLimit); } break; } throw err("unexpect token for SHOW"); } private ShowIndex showIndex(ShowIndex.Type type) throws SQLSyntaxErrorException { lexer.nextToken(); match(KW_FROM, KW_IN); Identifier tempId = identifier(); if (lexer.token() == KW_FROM || lexer.token() == KW_IN) { lexer.nextToken(); Identifier tempId2 = identifier(); return new ShowIndex(type, tempId, tempId2); } return new ShowIndex(type, tempId); } private ShowProfile showProfile() throws SQLSyntaxErrorException { lexer.nextToken(); List<ShowProfile.Type> types = new LinkedList<ShowProfile.Type>(); ShowProfile.Type type = showPrifileType(); if (type == null) { types = Collections.emptyList(); } else if (lexer.token() == PUNC_COMMA) { types = new LinkedList<ShowProfile.Type>(); types.add(type); for (; lexer.token() == PUNC_COMMA;) { lexer.nextToken(); type = showPrifileType(); types.add(type); } } else { types = new ArrayList<ShowProfile.Type>(); types.add(type); } Expression forQuery = null; if (lexer.token() == KW_FOR) { lexer.nextToken(); matchIdentifier("QUERY"); forQuery = exprParser.expression(); } Limit limit = limit(); return new ShowProfile(types, forQuery, limit); } /** * @return null if not a type */ private ShowProfile.Type showPrifileType() throws SQLSyntaxErrorException { switch (lexer.token()) { case KW_ALL: lexer.nextToken(); return ShowProfile.Type.ALL; case IDENTIFIER: String strUp = lexer.stringValueUppercase(); SpecialIdentifier si = specialIdentifiers.get(strUp); if (si != null) { switch (si) { case BLOCK: lexer.nextToken(); matchIdentifier("IO"); return ShowProfile.Type.BLOCK_IO; case CONTEXT: lexer.nextToken(); matchIdentifier("SWITCHES"); return ShowProfile.Type.CONTEXT_SWITCHES; case CPU: lexer.nextToken(); return ShowProfile.Type.CPU; case IPC: lexer.nextToken(); return ShowProfile.Type.IPC; case MEMORY: lexer.nextToken(); return ShowProfile.Type.MEMORY; case PAGE: lexer.nextToken(); matchIdentifier("FAULTS"); return ShowProfile.Type.PAGE_FAULTS; case SOURCE: lexer.nextToken(); return ShowProfile.Type.SOURCE; case SWAPS: lexer.nextToken(); return ShowProfile.Type.SWAPS; } } default: return null; } } /** * First token is {@link SpecialIdentifier#COLUMNS} * * <pre> * SHOW [FULL] <code>COLUMNS {FROM | IN} tbl_name [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr] </code> * </pre> */ private ShowColumns showColumns(boolean full) throws SQLSyntaxErrorException { lexer.nextToken(); match(KW_FROM, KW_IN); Identifier table = identifier(); Identifier database = null; switch (lexer.token()) { case KW_FROM: case KW_IN: lexer.nextToken(); database = identifier(); } switch (lexer.token()) { case KW_LIKE: String like = like(); return new ShowColumns(full, table, database, like); case KW_WHERE: Expression where = where(); return new ShowColumns(full, table, database, where); } return new ShowColumns(full, table, database); } private String like() throws SQLSyntaxErrorException { match(KW_LIKE); String pattern = lexer.stringValue(); lexer.nextToken(); return pattern; } private Expression where() throws SQLSyntaxErrorException { match(KW_WHERE); Expression where = exprParser.expression(); return where; } private String getStringValue() throws SQLSyntaxErrorException { String name; switch (lexer.token()) { case IDENTIFIER: name = Identifier.unescapeName(lexer.stringValue()); lexer.nextToken(); return name; case LITERAL_CHARS: name = lexer.stringValue(); name = LiteralString.getUnescapedString(name.substring(1, name.length() - 1)); lexer.nextToken(); return name; default: throw err("unexpected token: " + lexer.token()); } } /** * @return {@link DALSetStatement} or {@link MTSSetTransactionStatement} */ @SuppressWarnings("unchecked") public SQLStatement set() throws SQLSyntaxErrorException { match(KW_SET); if (lexer.token() == KW_OPTION) { lexer.nextToken(); } if (lexer.token() == IDENTIFIER && SpecialIdentifier.NAMES == specialIdentifiers.get(lexer.stringValueUppercase())) { if (lexer.nextToken() == KW_DEFAULT) { lexer.nextToken(); return new DALSetNamesStatement(); } String charsetName = getStringValue(); String collationName = null; if (lexer.token() == KW_COLLATE) { lexer.nextToken(); collationName = getStringValue(); } return new DALSetNamesStatement(charsetName, collationName); } else if (lexer.token() == KW_CHARACTER) { lexer.nextToken(); match(KW_SET); if (lexer.token() == KW_DEFAULT) { lexer.nextToken(); return new DALSetCharacterSetStatement(); } String charsetName = getStringValue(); return new DALSetCharacterSetStatement(charsetName); } List<Pair<VariableExpression, Expression>> assignmentList; Object obj = varAssign(); if (obj instanceof MTSSetTransactionStatement) { return (MTSSetTransactionStatement) obj; } Pair<VariableExpression, Expression> pair = (Pair<VariableExpression, Expression>) obj; if (lexer.token() != PUNC_COMMA) { assignmentList = new ArrayList<Pair<VariableExpression, Expression>>(1); assignmentList.add(pair); return new DALSetStatement(assignmentList); } assignmentList = new LinkedList<Pair<VariableExpression, Expression>>(); assignmentList.add(pair); for (; lexer.token() == PUNC_COMMA;) { lexer.nextToken(); pair = (Pair<VariableExpression, Expression>) varAssign(); assignmentList.add(pair); } return new DALSetStatement(assignmentList); } /** * first token is <code>TRANSACTION</code> */ private MTSSetTransactionStatement setMTSSetTransactionStatement(VariableScope scope) throws SQLSyntaxErrorException { lexer.nextToken(); matchIdentifier("ISOLATION"); matchIdentifier("LEVEL"); SpecialIdentifier si; switch (lexer.token()) { case KW_READ: lexer.nextToken(); si = specialIdentifiers.get(lexer.stringValueUppercase()); if (si != null) { switch (si) { case COMMITTED: lexer.nextToken(); return new MTSSetTransactionStatement( scope, MTSSetTransactionStatement.IsolationLevel.READ_COMMITTED); case UNCOMMITTED: lexer.nextToken(); return new MTSSetTransactionStatement( scope, MTSSetTransactionStatement.IsolationLevel.READ_UNCOMMITTED); } } throw err("unknown isolation read level: " + lexer.stringValue()); case IDENTIFIER: si = specialIdentifiers.get(lexer.stringValueUppercase()); if (si != null) { switch (si) { case REPEATABLE: lexer.nextToken(); match(KW_READ); return new MTSSetTransactionStatement( scope, MTSSetTransactionStatement.IsolationLevel.REPEATABLE_READ); case SERIALIZABLE: lexer.nextToken(); return new MTSSetTransactionStatement(scope, MTSSetTransactionStatement.IsolationLevel.SERIALIZABLE); } } } throw err("unknown isolation level: " + lexer.stringValue()); } private Object varAssign() throws SQLSyntaxErrorException { VariableExpression var; Expression expr; VariableScope scope = VariableScope.SESSION; switch (lexer.token()) { case IDENTIFIER: boolean explictScope = false; SpecialIdentifier si = specialIdentifiers.get(lexer.stringValueUppercase()); if (si != null) { switch (si) { case TRANSACTION: return setMTSSetTransactionStatement(null); case GLOBAL: scope = VariableScope.GLOBAL; case SESSION: case LOCAL: explictScope = true; lexer.nextToken(); default: break; } } if (explictScope && specialIdentifiers.get(lexer.stringValueUppercase()) == SpecialIdentifier.TRANSACTION) { return setMTSSetTransactionStatement(scope); } var = new SysVarPrimary(scope, lexer.stringValue(), lexer.stringValueUppercase()); match(IDENTIFIER); break; case SYS_VAR: var = systemVariale(); break; case USR_VAR: var = new UsrDefVarPrimary(lexer.stringValue()); lexer.nextToken(); break; default: throw err("unexpected token for SET statement"); } match(OP_EQUALS, OP_ASSIGN); expr = exprParser.expression(); return new Pair<VariableExpression, Expression>(var, expr); } }