/* * 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-9-12) */ package com.alibaba.cobar.parser.recognizer.mysql.syntax; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.EOF; import static com.alibaba.cobar.parser.recognizer.mysql.MySQLToken.KW_RELEASE; import java.sql.SQLSyntaxErrorException; import java.util.HashMap; import java.util.Map; import com.alibaba.cobar.parser.ast.expression.primary.Identifier; import com.alibaba.cobar.parser.ast.stmt.mts.MTSReleaseStatement; import com.alibaba.cobar.parser.ast.stmt.mts.MTSRollbackStatement; import com.alibaba.cobar.parser.ast.stmt.mts.MTSSavepointStatement; import com.alibaba.cobar.parser.recognizer.mysql.lexer.MySQLLexer; /** * @author <a href="mailto:shuo.qius@alibaba-inc.com">QIU Shuo</a> */ public class MySQLMTSParser extends MySQLParser { private static enum SpecialIdentifier { CHAIN, NO, RELEASE, SAVEPOINT, WORK } private static final Map<String, SpecialIdentifier> specialIdentifiers = new HashMap<String, SpecialIdentifier>(); static { specialIdentifiers.put("SAVEPOINT", SpecialIdentifier.SAVEPOINT); specialIdentifiers.put("WORK", SpecialIdentifier.WORK); specialIdentifiers.put("CHAIN", SpecialIdentifier.CHAIN); specialIdentifiers.put("RELEASE", SpecialIdentifier.RELEASE); specialIdentifiers.put("NO", SpecialIdentifier.NO); } public MySQLMTSParser(MySQLLexer lexer) { super(lexer); } /** * first token <code>SAVEPOINT</code> is scanned but not yet consumed */ public MTSSavepointStatement savepoint() throws SQLSyntaxErrorException { // matchIdentifier("SAVEPOINT"); // for performance issue, change to // follow: lexer.nextToken(); Identifier id = identifier(); match(EOF); return new MTSSavepointStatement(id); } /** * first token <code>RELEASE</code> is scanned but not yet consumed */ public MTSReleaseStatement release() throws SQLSyntaxErrorException { match(KW_RELEASE); matchIdentifier("SAVEPOINT"); Identifier id = identifier(); match(EOF); return new MTSReleaseStatement(id); } /** * first token <code>ROLLBACK</code> is scanned but not yet consumed * * <pre> * ROLLBACK [WORK] TO [SAVEPOINT] identifier * ROLLBACK [WORK] [AND [NO] CHAIN | [NO] RELEASE] * </pre> */ public MTSRollbackStatement rollback() throws SQLSyntaxErrorException { // matchIdentifier("ROLLBACK"); // for performance issue, change to // follow: lexer.nextToken(); SpecialIdentifier siTemp = specialIdentifiers.get(lexer.stringValueUppercase()); if (siTemp == SpecialIdentifier.WORK) { lexer.nextToken(); } switch (lexer.token()) { case EOF: return new MTSRollbackStatement(MTSRollbackStatement.CompleteType.UN_DEF); case KW_TO: lexer.nextToken(); String str = lexer.stringValueUppercase(); if (specialIdentifiers.get(str) == SpecialIdentifier.SAVEPOINT) { lexer.nextToken(); } Identifier savepoint = identifier(); match(EOF); return new MTSRollbackStatement(savepoint); case KW_AND: lexer.nextToken(); siTemp = specialIdentifiers.get(lexer.stringValueUppercase()); if (siTemp == SpecialIdentifier.NO) { lexer.nextToken(); matchIdentifier("CHAIN"); match(EOF); return new MTSRollbackStatement(MTSRollbackStatement.CompleteType.NO_CHAIN); } matchIdentifier("CHAIN"); match(EOF); return new MTSRollbackStatement(MTSRollbackStatement.CompleteType.CHAIN); case KW_RELEASE: lexer.nextToken(); match(EOF); return new MTSRollbackStatement(MTSRollbackStatement.CompleteType.RELEASE); case IDENTIFIER: siTemp = specialIdentifiers.get(lexer.stringValueUppercase()); if (siTemp == SpecialIdentifier.NO) { lexer.nextToken(); match(KW_RELEASE); match(EOF); return new MTSRollbackStatement(MTSRollbackStatement.CompleteType.NO_RELEASE); } default: throw err("unrecognized complete type: " + lexer.token()); } } }