diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index cd16e69125..d481bc9ae3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -1,491 +1,489 @@ -/* - * Copyright 1999-2011 Alibaba Group Holding Ltd. - * - * 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. - */ -package com.alibaba.druid.sql.dialect.mysql.parser; - -import static com.alibaba.druid.sql.parser.CharTypes.isFirstIdentifierChar; -import static com.alibaba.druid.sql.parser.CharTypes.isIdentifierChar; -import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI; -import static com.alibaba.druid.sql.parser.Token.LITERAL_CHARS; - -import java.util.HashMap; -import java.util.Map; - -import com.alibaba.druid.sql.parser.Keywords; -import com.alibaba.druid.sql.parser.Lexer; -import com.alibaba.druid.sql.parser.NotAllowCommentException; -import com.alibaba.druid.sql.parser.ParserException; -import com.alibaba.druid.sql.parser.Token; - -public class MySqlLexer extends Lexer { - - public final static Keywords DEFAULT_MYSQL_KEYWORDS; - - static { - Map map = new HashMap(); - - map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords()); - - map.put("DUAL", Token.DUAL); - map.put("FALSE", Token.FALSE); - map.put("IDENTIFIED", Token.IDENTIFIED); - map.put("IF", Token.IF); - map.put("KILL", Token.KILL); - - map.put("LIMIT", Token.LIMIT); - map.put("TRUE", Token.TRUE); - map.put("BINARY", Token.BINARY); - map.put("SHOW", Token.SHOW); - map.put("CACHE", Token.CACHE); - map.put("ANALYZE", Token.ANALYZE); - map.put("OPTIMIZE", Token.OPTIMIZE); - - DEFAULT_MYSQL_KEYWORDS = new Keywords(map); - } - - public MySqlLexer(char[] input, int inputLength, boolean skipComment){ - super(input, inputLength, skipComment); - super.keywods = DEFAULT_MYSQL_KEYWORDS; - } - - public MySqlLexer(String input){ - super(input); - super.keywods = DEFAULT_MYSQL_KEYWORDS; - } - - public void scanSharp() { - if (ch != '#') { - throw new ParserException("illegal stat"); - } - - if (charAt(pos + 1) == '{') { - scanVariable(); - return; - } - - Token lastToken = this.token; - - scanChar(); - mark = pos; - bufPos = 0; - for (;;) { - if (ch == '\r') { - if (charAt(pos + 1) == '\n') { - bufPos += 2; - scanChar(); - break; - } - bufPos++; - break; - } else if (ch == EOI) { - break; - } - - if (ch == '\n') { - scanChar(); - bufPos++; - break; - } - - scanChar(); - bufPos++; - } - - stringVal = subString(mark, bufPos); - token = Token.LINE_COMMENT; - - if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { - return; - } - - if (!isAllowComment()) { - throw new NotAllowCommentException(); - } - } - - public void scanVariable() { - if (ch != '@' && ch != ':' && ch != '#' && ch != '$') { - throw new ParserException("illegal variable"); - } - - mark = pos; - bufPos = 1; - - if (charAt(pos + 1) == '@') { - ch = charAt(++pos); - bufPos++; - } - - if (charAt(pos + 1) == '`') { - ++pos; - ++bufPos; - char ch; - for (;;) { - ch = charAt(++pos); - - if (ch == '`') { - bufPos++; - ch = charAt(++pos); - break; - } else if (ch == EOI) { - throw new ParserException("illegal identifier"); - } - - bufPos++; - continue; - } - - this.ch = charAt(pos); - - stringVal = subString(mark, bufPos); - token = Token.VARIANT; - } else if (charAt(pos + 1) == '{') { - ++pos; - ++bufPos; - char ch; - for (;;) { - ch = charAt(++pos); - - if (ch == '}') { - bufPos++; - ch = charAt(++pos); - break; - } else if (ch == EOI) { - throw new ParserException("illegal identifier"); - } - - bufPos++; - continue; - } - - this.ch = charAt(pos); - - stringVal = subString(mark, bufPos); - token = Token.VARIANT; - } else { - for (;;) { - ch = charAt(++pos); - - if (!isIdentifierChar(ch)) { - break; - } - - bufPos++; - continue; - } - } - - this.ch = charAt(pos); - - stringVal = subString(mark, bufPos); - token = Token.VARIANT; - } - - public void scanIdentifier() { - final char first = ch; - - if (ch == '`') { - - mark = pos; - bufPos = 1; - char ch; - for (;;) { - ch = charAt(++pos); - - if (ch == '`') { - bufPos++; - ch = charAt(++pos); - break; - } else if (ch == EOI) { - throw new ParserException("illegal identifier"); - } - - bufPos++; - continue; - } - - this.ch = charAt(pos); - - stringVal = subString(mark, bufPos); - Token tok = keywods.getKeyword(stringVal); - if (tok != null) { - token = tok; - } else { - token = Token.IDENTIFIER; - } - } else { - - final boolean firstFlag = isFirstIdentifierChar(first); - if (!firstFlag) { - throw new ParserException("illegal identifier"); - } - - mark = pos; - bufPos = 1; - char ch; - for (;;) { - ch = charAt(++pos); - - if (!isIdentifierChar(ch)) { - break; - } - - bufPos++; - continue; - } - - this.ch = charAt(pos); - - stringVal = addSymbol(); - Token tok = keywods.getKeyword(stringVal); - if (tok != null) { - token = tok; - } else { - token = Token.IDENTIFIER; - } - } - } - - protected final void scanString() { - { - boolean hasSpecial = false; - int startIndex = pos + 1; - int endIndex = -1; // text.indexOf('\'', startIndex); - for (int i = startIndex; i < text.length(); ++i) { - final char ch = text.charAt(i); - if (ch == '\\') { - hasSpecial = true; - continue; - } - if (ch == '\'') { - endIndex = i; - break; - } - } - - if (endIndex == -1) { - throw new ParserException("unclosed str"); - } - - String stringVal = subString(startIndex, endIndex - startIndex); - // hasSpecial = stringVal.indexOf('\\') != -1; - - if (!hasSpecial) { - this.stringVal = stringVal; - int pos = endIndex + 1; - char ch = charAt(pos); - if (ch != '\'') { - this.pos = pos; - this.ch = ch; - token = LITERAL_CHARS; - return; - } - } - } - - mark = pos; - boolean hasSpecial = false; - for (;;) { - if (isEOF()) { - lexError("unclosed.str.lit"); - return; - } - - ch = charAt(++pos); - - if (ch == '\\') { - scanChar(); - if (!hasSpecial) { - initBuff(bufPos); - arraycopy(mark + 1, buf, 0, bufPos); - hasSpecial = true; - } - - switch (ch) { - case '\0': - putChar('\0'); - break; - case '\'': - putChar('\''); - break; - case '"': - putChar('"'); - break; - case 'b': - putChar('\b'); - break; - case 'n': - putChar('\n'); - break; - case 'r': - putChar('\r'); - break; - case 't': - putChar('\t'); - break; - case '\\': - putChar('\\'); - break; - case 'Z': - putChar((char) 0x1A); // ctrl + Z - break; - default: - putChar(ch); - break; - } - scanChar(); - } - - if (ch == '\'') { - scanChar(); - if (ch != '\'') { - token = LITERAL_CHARS; - break; - } else { - initBuff(bufPos); - arraycopy(mark + 1, buf, 0, bufPos); - hasSpecial = true; - putChar('\''); - continue; - } - } - - if (!hasSpecial) { - bufPos++; - continue; - } - - if (bufPos == buf.length) { - putChar(ch); - } else { - buf[bufPos++] = ch; - } - } - - if (!hasSpecial) { - stringVal = ""; - stringVal = subString(mark + 1, bufPos); - } else { - stringVal = new String(buf, 0, bufPos); - } - } - - public void scanComment() { - Token lastToken = this.token; - - if (ch != '/' && ch != '-') { - throw new IllegalStateException(); - } - - mark = pos; - bufPos = 0; - scanChar(); - - // /*+ */ - if (ch == '*') { - scanChar(); - bufPos++; - - while (ch == ' ') { - scanChar(); - bufPos++; - } - - boolean isHint = false; - int startHintSp = bufPos + 1; - if (ch == '!') { - isHint = true; - scanChar(); - bufPos++; - } - - for (;;) { - if (ch == EOI) { - this.token = Token.ERROR; - return; - } - if (ch == '*' && charAt(pos + 1) == '/') { - bufPos += 3; - scanChar(); - scanChar(); - break; - } - - scanChar(); - bufPos++; - } - - if (isHint) { - stringVal = subString(mark + startHintSp, (bufPos - startHintSp) - 2); - token = Token.HINT; - } else { - stringVal = subString(mark, bufPos); - token = Token.MULTI_LINE_COMMENT; - } - - if (token != Token.HINT) { - if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { - return; - } - - if (!isAllowComment()) { - throw new NotAllowCommentException(); - } - } - - return; - } - if (ch == '/' || ch == '-') { - scanChar(); - bufPos++; - - for (;;) { - if (ch == '\r') { - if (charAt(pos + 1) == '\n') { - bufPos += 2; - scanChar(); - break; - } - bufPos++; - break; - } else if (ch == EOI) { - break; - } - - if (ch == '\n') { - scanChar(); - bufPos++; - break; - } - - scanChar(); - bufPos++; - } - - stringVal = subString(mark, bufPos + 1); - token = Token.LINE_COMMENT; - - if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { - return; - } - - if (!isAllowComment()) { - throw new NotAllowCommentException(); - } - - return; - } - } -} +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * 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. + */ +package com.alibaba.druid.sql.dialect.mysql.parser; + +import static com.alibaba.druid.sql.parser.CharTypes.isFirstIdentifierChar; +import static com.alibaba.druid.sql.parser.CharTypes.isIdentifierChar; +import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI; +import static com.alibaba.druid.sql.parser.Token.LITERAL_CHARS; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.druid.sql.parser.Keywords; +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.NotAllowCommentException; +import com.alibaba.druid.sql.parser.ParserException; +import com.alibaba.druid.sql.parser.Token; + +public class MySqlLexer extends Lexer { + + public final static Keywords DEFAULT_MYSQL_KEYWORDS; + + static { + Map map = new HashMap(); + + map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords()); + + map.put("DUAL", Token.DUAL); + map.put("FALSE", Token.FALSE); + map.put("IDENTIFIED", Token.IDENTIFIED); + map.put("IF", Token.IF); + map.put("KILL", Token.KILL); + + map.put("LIMIT", Token.LIMIT); + map.put("TRUE", Token.TRUE); + map.put("BINARY", Token.BINARY); + map.put("SHOW", Token.SHOW); + map.put("CACHE", Token.CACHE); + map.put("ANALYZE", Token.ANALYZE); + map.put("OPTIMIZE", Token.OPTIMIZE); + + DEFAULT_MYSQL_KEYWORDS = new Keywords(map); + } + + public MySqlLexer(char[] input, int inputLength, boolean skipComment){ + super(input, inputLength, skipComment); + super.keywods = DEFAULT_MYSQL_KEYWORDS; + } + + public MySqlLexer(String input){ + super(input); + super.keywods = DEFAULT_MYSQL_KEYWORDS; + } + + public void scanSharp() { + if (ch != '#') { + throw new ParserException("illegal stat"); + } + + if (charAt(pos + 1) == '{') { + scanVariable(); + return; + } + + Token lastToken = this.token; + + scanChar(); + mark = pos; + bufPos = 0; + for (;;) { + if (ch == '\r') { + if (charAt(pos + 1) == '\n') { + bufPos += 2; + scanChar(); + break; + } + bufPos++; + break; + } else if (ch == EOI) { + break; + } + + if (ch == '\n') { + scanChar(); + bufPos++; + break; + } + + scanChar(); + bufPos++; + } + + stringVal = subString(mark, bufPos); + token = Token.LINE_COMMENT; + + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { + return; + } + + if (!isAllowComment()) { + throw new NotAllowCommentException(); + } + } + + public void scanVariable() { + if (ch != '@' && ch != ':' && ch != '#' && ch != '$') { + throw new ParserException("illegal variable"); + } + + mark = pos; + bufPos = 1; + + if (charAt(pos + 1) == '@') { + ch = charAt(++pos); + bufPos++; + } + + if (charAt(pos + 1) == '`') { + ++pos; + ++bufPos; + char ch; + for (;;) { + ch = charAt(++pos); + + if (ch == '`') { + bufPos++; + ch = charAt(++pos); + break; + } else if (ch == EOI) { + throw new ParserException("illegal identifier"); + } + + bufPos++; + continue; + } + + this.ch = charAt(pos); + + stringVal = subString(mark, bufPos); + token = Token.VARIANT; + } else if (charAt(pos + 1) == '{') { + ++pos; + ++bufPos; + char ch; + for (;;) { + ch = charAt(++pos); + + if (ch == '}') { + bufPos++; + ch = charAt(++pos); + break; + } else if (ch == EOI) { + throw new ParserException("illegal identifier"); + } + + bufPos++; + continue; + } + + this.ch = charAt(pos); + + stringVal = subString(mark, bufPos); + token = Token.VARIANT; + } else { + for (;;) { + ch = charAt(++pos); + + if (!isIdentifierChar(ch)) { + break; + } + + bufPos++; + continue; + } + } + + this.ch = charAt(pos); + + stringVal = subString(mark, bufPos); + token = Token.VARIANT; + } + + public void scanIdentifier() { + final char first = ch; + + if (ch == '`') { + + mark = pos; + bufPos = 1; + char ch; + for (;;) { + ch = charAt(++pos); + + if (ch == '`') { + bufPos++; + ch = charAt(++pos); + break; + } else if (ch == EOI) { + throw new ParserException("illegal identifier"); + } + + bufPos++; + continue; + } + + this.ch = charAt(pos); + + stringVal = subString(mark, bufPos); + Token tok = keywods.getKeyword(stringVal); + if (tok != null) { + token = tok; + } else { + token = Token.IDENTIFIER; + } + } else { + + final boolean firstFlag = isFirstIdentifierChar(first); + if (!firstFlag) { + throw new ParserException("illegal identifier"); + } + + mark = pos; + bufPos = 1; + char ch; + for (;;) { + ch = charAt(++pos); + + if (!isIdentifierChar(ch)) { + break; + } + + bufPos++; + continue; + } + + this.ch = charAt(pos); + + stringVal = addSymbol(); + Token tok = keywods.getKeyword(stringVal); + if (tok != null) { + token = tok; + } else { + token = Token.IDENTIFIER; + } + } + } + + protected final void scanString() { + { + boolean hasSpecial = false; + int startIndex = pos + 1; + int endIndex = -1; // text.indexOf('\'', startIndex); + for (int i = startIndex; i < text.length(); ++i) { + final char ch = text.charAt(i); + if (ch == '\\') { + hasSpecial = true; + continue; + } + if (ch == '\'') { + endIndex = i; + break; + } + } + + if (endIndex == -1) { + throw new ParserException("unclosed str"); + } + + String stringVal = subString(startIndex, endIndex - startIndex); + // hasSpecial = stringVal.indexOf('\\') != -1; + + if (!hasSpecial) { + this.stringVal = stringVal; + int pos = endIndex + 1; + char ch = charAt(pos); + if (ch != '\'') { + this.pos = pos; + this.ch = ch; + token = LITERAL_CHARS; + return; + } + } + } + + mark = pos; + boolean hasSpecial = false; + for (;;) { + if (isEOF()) { + lexError("unclosed.str.lit"); + return; + } + + ch = charAt(++pos); + + if (ch == '\\') { + scanChar(); + if (!hasSpecial) { + initBuff(bufPos); + arraycopy(mark + 1, buf, 0, bufPos); + hasSpecial = true; + } + + switch (ch) { + case '\0': + putChar('\0'); + break; + case '\'': + putChar('\''); + break; + case '"': + putChar('"'); + break; + case 'b': + putChar('\b'); + break; + case 'n': + putChar('\n'); + break; + case 'r': + putChar('\r'); + break; + case 't': + putChar('\t'); + break; + case '\\': + putChar('\\'); + break; + case 'Z': + putChar((char) 0x1A); // ctrl + Z + break; + default: + putChar(ch); + break; + } + scanChar(); + } + + if (ch == '\'') { + scanChar(); + if (ch != '\'') { + token = LITERAL_CHARS; + break; + } else { + initBuff(bufPos); + arraycopy(mark + 1, buf, 0, bufPos); + hasSpecial = true; + putChar('\''); + continue; + } + } + + if (!hasSpecial) { + bufPos++; + continue; + } + + if (bufPos == buf.length) { + putChar(ch); + } else { + buf[bufPos++] = ch; + } + } + + if (!hasSpecial) { + stringVal = ""; + stringVal = subString(mark + 1, bufPos); + } else { + stringVal = new String(buf, 0, bufPos); + } + } + + public void scanComment() { + Token lastToken = this.token; + + if (ch != '/' && ch != '-') { + throw new IllegalStateException(); + } + + mark = pos; + bufPos = 0; + scanChar(); + + // /*+ */ + if (ch == '*') { + scanChar(); + bufPos++; + + while (ch == ' ') { + scanChar(); + bufPos++; + } + + boolean isHint = false; + int startHintSp = bufPos + 1; + if (ch == '!') { + isHint = true; + scanChar(); + bufPos++; + } + + for (;;) { + if (ch == EOI) { + this.token = Token.ERROR; + return; + } + if (ch == '*' && charAt(pos + 1) == '/') { + bufPos += 3; + scanChar(); + scanChar(); + break; + } + + scanChar(); + bufPos++; + } + + if (isHint) { + stringVal = subString(mark + startHintSp, (bufPos - startHintSp) - 2); + token = Token.HINT; + } else { + stringVal = subString(mark, bufPos); + token = Token.MULTI_LINE_COMMENT; + } + + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { + return; + } + + if (!isAllowComment()) { + throw new NotAllowCommentException(); + } + + return; + } + if (ch == '/' || ch == '-') { + scanChar(); + bufPos++; + + for (;;) { + if (ch == '\r') { + if (charAt(pos + 1) == '\n') { + bufPos += 2; + scanChar(); + break; + } + bufPos++; + break; + } else if (ch == EOI) { + break; + } + + if (ch == '\n') { + scanChar(); + bufPos++; + break; + } + + scanChar(); + bufPos++; + } + + stringVal = subString(mark, bufPos + 1); + token = Token.LINE_COMMENT; + + if (commentHandler != null && commentHandler.handle(lastToken, stringVal)) { + return; + } + + if (!isAllowComment()) { + throw new NotAllowCommentException(); + } + + return; + } + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest95.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest95.java new file mode 100644 index 0000000000..718a26e1e6 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest95.java @@ -0,0 +1,42 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * 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. + */ +package com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +/** + * SQLServerWallTest + * + * @author RaymondXiu + * @version 1.0, 2012-3-18 + * @see + */ +public class MySqlWallTest95 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + provider.getConfig().setCommentAllow(false); + + Assert.assertFalse(provider.checkValid(// + "select * from test /*!40101fff*/")); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_13.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_13.java new file mode 100644 index 0000000000..7342ff3d1f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_13.java @@ -0,0 +1,67 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * 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. + */ +package com.alibaba.druid.bvt.sql.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class MySqlSelectTest_13 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "select * from test /*!40101fff*/"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; + + SQLSelect select = selectStmt.getSelect(); + Assert.assertNotNull(select.getQuery()); + MySqlSelectQueryBlock queryBlock = (MySqlSelectQueryBlock) select.getQuery(); + Assert.assertNull(queryBlock.getOrderBy()); + + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + Assert.assertEquals(0, visitor.getOrderByColumns().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + String output = SQLUtils.toMySqlString(stmt); + Assert.assertEquals("SELECT *" // + + "\nFROM test", // + output); + } +}