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