improved parser performance.

This commit is contained in:
wenshao
2017-08-21 15:34:10 +08:00
parent 17772cde69
commit 5804eea0c9
20 changed files with 484 additions and 151 deletions
@@ -19,30 +19,54 @@ import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.io.IOException;
import java.math.BigDecimal;
public class SQLNumberExpr extends SQLNumericLiteralExpr {
private static SQLDataType defaultDataType = new SQLDataTypeImpl("number");
private Number number;
private char[] chars;
public SQLNumberExpr(){
}
public SQLNumberExpr(Number number){
this.number = number;
}
public SQLNumberExpr(char[] chars){
this.chars = chars;
}
public Number getNumber() {
if (chars != null && number == null) {
this.number = new BigDecimal(chars);
}
return this.number;
}
public void setNumber(Number number) {
this.number = number;
this.chars = null;
}
public void output(StringBuilder buf) {
if (chars != null) {
buf.append(chars);
} else {
buf.append(this.number.toString());
}
}
public void output(StringBuffer buf) {
buf.append(this.number.toString());
if (chars != null) {
buf.append(chars);
} else {
buf.append(this.number.toString());
}
}
protected void accept0(SQLASTVisitor visitor) {
@@ -52,6 +76,9 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
@Override
public int hashCode() {
if (chars != null && number == null) {
this.number = new BigDecimal(chars);
}
final int prime = 31;
int result = 1;
result = prime * result + ((number == null) ? 0 : number.hashCode());
@@ -60,6 +87,10 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
@Override
public boolean equals(Object obj) {
if (chars != null && number == null) {
this.number = new BigDecimal(chars);
}
if (this == obj) {
return true;
}
@@ -70,6 +101,10 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
return false;
}
SQLNumberExpr other = (SQLNumberExpr) obj;
if (other.chars != null && other.number == null) {
other.number = new BigDecimal(other.chars);
}
if (number == null) {
if (other.number != null) {
return false;
@@ -53,6 +53,7 @@ import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.util.JdbcConstants;
import java.io.IOException;
import java.security.AccessControlException;
import java.util.List;
import java.util.Map;
@@ -567,44 +568,59 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
public boolean visit(SQLCharExpr x) {
if (this.parameterized
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
print('?');
incrementReplaceCunt();
if (this instanceof ExportParameterVisitor || this.parameters != null) {
ExportParameterVisitorUtils.exportParameter(this.parameters, x);
}
if (this.appender == null) {
return false;
}
print('\'');
String text = x.getText();
StringBuilder buf = new StringBuilder(text.length());
for (int i = 0; i < text.length(); ++i) {
char ch = text.charAt(i);
if (ch == '\'') {
buf.append('\'');
buf.append('\'');
} else if (ch == '\\') {
buf.append('\\');
buf.append('\\');
} else if (ch == '\0') {
buf.append('\\');
buf.append('0');
} else {
buf.append(ch);
try {
if (this.parameterized
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
this.appender.append('?');
incrementReplaceCunt();
if (this instanceof ExportParameterVisitor || this.parameters != null) {
ExportParameterVisitorUtils.exportParameter(this.parameters, x);
}
return false;
}
}
if (buf.length() != text.length()) {
text = buf.toString();
}
print0(text);
this.appender.append('\'');
print('\'');
String text = x.getText();
boolean hasSpecial = false;
for (int i = 0; i < text.length(); ++i) {
char ch = text.charAt(i);
if (ch == '\'' || ch == '\\' || ch == '\0') {
hasSpecial = true;
break;
}
}
if (hasSpecial) {
for (int i = 0; i < text.length(); ++i) {
char ch = text.charAt(i);
if (ch == '\'') {
appender.append('\'');
appender.append('\'');
} else if (ch == '\\') {
appender.append('\\');
appender.append('\\');
} else if (ch == '\0') {
appender.append('\\');
appender.append('0');
} else {
appender.append(ch);
}
}
} else {
appender.append(text);
}
appender.append('\'');
return false;
} catch (IOException e) {
throw new RuntimeException("println error", e);
}
}
public boolean visit(SQLVariantRefExpr x) {
@@ -924,12 +940,18 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? "INTO " : "into ");
x.getTableSource().accept(this);
SQLExprTableSource tableSource = x.getTableSource();
if (tableSource.getClass() == SQLExprTableSource.class) {
visit(tableSource);
} else {
tableSource.accept(this);
}
if (x.getColumns().size() > 0) {
List<SQLExpr> columns = x.getColumns();
if (columns.size() > 0) {
incrementIndent();
print0(" (");
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
for (int i = 0, size = columns.size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
@@ -937,15 +959,22 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(", ");
}
x.getColumns().get(i).accept(this);
SQLExpr columnn = columns.get(i);
if (columnn instanceof SQLIdentifierExpr) {
visit((SQLIdentifierExpr) columnn);
}
else {
columnn.accept(this);
}
}
print(')');
decrementIndent();
}
if (!x.getValuesList().isEmpty()) {
List<SQLInsertStatement.ValuesClause> valuesList = x.getValuesList();
if (!valuesList.isEmpty()) {
println();
printValuesList(x);
printValuesList(valuesList);
}
if (x.getQuery() != null) {
@@ -970,8 +999,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
return false;
}
protected void printValuesList(MySqlInsertStatement x) {
List<SQLInsertStatement.ValuesClause> valuesList = x.getValuesList();
protected void printValuesList(List<SQLInsertStatement.ValuesClause> valuesList) {
if (parameterized) {
print0(ucase ? "VALUES " : "values ");
@@ -985,18 +1013,20 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
print0(ucase ? "VALUES " : "values ");
if (x.getValuesList().size() > 1) {
incrementIndent();
if (valuesList.size() > 1) {
this.indentCount++;
}
for (int i = 0, size = valuesList.size(); i < size; ++i) {
if (i != 0) {
print(',');
println();
}
valuesList.get(i).accept(this);
SQLInsertStatement.ValuesClause item = valuesList.get(i);
visit(item);
}
if (valuesList.size() > 1) {
decrementIndent();
this.indentCount--;
}
}
@@ -1,3 +1,18 @@
/*
* Copyright 1999-2017 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.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.SQLStatement;
@@ -1,3 +1,18 @@
/*
* Copyright 1999-2017 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.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.SQLName;
@@ -330,7 +330,7 @@ public class OracleExprParser extends SQLExprParser {
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue());
sqlExpr = lexer.numberExpr();
lexer.nextToken();
break;
case BINARY_FLOAT:
@@ -382,7 +382,7 @@ public class OracleExprParser extends SQLExprParser {
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue().negate());
sqlExpr = lexer.numberExpr();
lexer.nextToken();
break;
case BINARY_FLOAT:
@@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.StringUtils;
@@ -89,6 +90,8 @@ public class Lexer {
protected String dbType;
protected boolean hasSpecial = false;
private int startPos;
private int posLine;
private int posColumn;
@@ -144,6 +147,12 @@ public class Lexer {
return text.substring(offset, offset + count);
}
public final char[] sub_chars(int offset, int count) {
char[] chars = new char[count];
text.getChars(offset, offset + count, chars, 0);
return chars;
}
protected void initBuff(int size) {
if (buf == null) {
if (size < 32) {
@@ -1522,11 +1531,36 @@ public class Lexer {
}
public BigDecimal decimalValue() {
String value = subString(mark, bufPos);
char[] value = sub_chars(mark, bufPos);
if (!StringUtils.isNumber(value)){
throw new ParserException(value+" is not a number! " + info());
}
return new BigDecimal(value.toCharArray());
return new BigDecimal(value);
}
public SQLNumberExpr numberExpr() {
char[] value = sub_chars(mark, bufPos);
if (!StringUtils.isNumber(value)){
throw new ParserException(value+" is not a number! " + info());
}
return new SQLNumberExpr(value);
}
public SQLNumberExpr numberExpr(boolean negate) {
char[] value = sub_chars(mark, bufPos);
if (!StringUtils.isNumber(value)){
throw new ParserException(value+" is not a number! " + info());
}
if (negate) {
char[] chars = new char[value.length + 1];
chars[0] = '-';
System.arraycopy(value, 0, chars, 1, value.length);
return new SQLNumberExpr(chars);
} else {
return new SQLNumberExpr(value);
}
}
public static interface CommentHandler {
@@ -297,7 +297,7 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue());
sqlExpr = lexer.numberExpr();
lexer.nextToken();
break;
case LITERAL_CHARS:
@@ -521,7 +521,7 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue().negate());
sqlExpr = lexer.numberExpr(true);
lexer.nextToken();
break;
case IDENTIFIER: // 当负号后面为字段的情况
@@ -559,7 +559,7 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue());
sqlExpr = lexer.numberExpr();
lexer.nextToken();
break;
case IDENTIFIER: // 当+号后面为字段的情况
@@ -53,7 +53,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
protected final Appendable appender;
private String indent = "\t";
private int indentCount = 0;
protected int indentCount = 0;
private boolean prettyFormat = true;
protected boolean ucase = true;
protected int selectListNumberOfLine = 5;
@@ -166,11 +166,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
public void decrementIndent() {
this.indentCount -= 1;
this.indentCount--;
}
public void incrementIndent() {
this.indentCount += 1;
this.indentCount++;
}
public boolean isParameterized() {
@@ -214,9 +214,30 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
return;
}
print0(Integer.toString(value));
if (appender instanceof StringBuffer) {
((StringBuffer) appender).append(value);
} else if (appender instanceof StringBuilder) {
((StringBuilder) appender).append(value);
} else {
print0(Integer.toString(value));
}
}
public void print(long value) {
if (this.appender == null) {
return;
}
if (appender instanceof StringBuilder) {
((StringBuilder) appender).append(value);
} else if (appender instanceof StringBuffer) {
((StringBuffer) appender).append(value);
} else {
print0(Long.toString(value));
}
}
public void print(Date date) {
if (this.appender == null) {
return;
@@ -231,13 +252,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print0("'" + dateFormat.format(date) + "'");
}
public void print(long value) {
if (this.appender == null) {
return;
}
print0(Long.toString(value));
}
public void print(String text) {
if (this.appender == null) {
return;
@@ -707,7 +721,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print0(ucase ? "NULL" : "null");
} else {
print('\'');
print0(text.replaceAll("'", "''"));
int index = text.indexOf('\'');
if (index >= 0) {
text = text.replaceAll("'", "''");
}
print0(text);
print('\'');
}
}
@@ -957,7 +975,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
public boolean visit(SQLIntegerExpr x) {
int val = x.getNumber().intValue();
long val = x.getNumber().longValue();
SQLObject parent = x.getParent();
if (val == 1) {
@@ -980,7 +998,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
if (this.parameterized
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
if (!ParameterizedOutputVisitorUtils.checkParameterize(x)) {
return SQLASTOutputVisitorUtils.visit(this, x);
print(val);
return false;
}
print('?');
@@ -992,7 +1011,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
return false;
}
return SQLASTOutputVisitorUtils.visit(this, x);
print(val);
return false;
}
public boolean visit(SQLMethodInvokeExpr x) {
@@ -1180,7 +1200,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
return false;
}
return SQLASTOutputVisitorUtils.visit(this, x);
if (appender instanceof StringBuilder) {
x.output((StringBuilder) appender);
} else if (appender instanceof StringBuilder) {
x.output((StringBuilder) appender);
} else {
print0(x.getNumber().toString());
}
return false;
}
public boolean visit(SQLPropertyExpr x) {
@@ -1612,7 +1639,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
}
expr.accept(this);
if (expr instanceof SQLIdentifierExpr) {
visit((SQLIdentifierExpr) expr);
} else if (expr instanceof SQLPropertyExpr) {
visit((SQLPropertyExpr) expr);
} else {
expr.accept(this);
}
}
public boolean visit(SQLExprTableSource x) {
@@ -2315,8 +2349,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
@Override
public boolean visit(ValuesClause x) {
print('(');
incrementIndent();
for (int i = 0, size = x.getValues().size(); i < size; ++i) {
this.indentCount++;
final List<SQLExpr> values = x.getValues();
for (int i = 0, size = values.size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
@@ -2324,11 +2360,27 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print0(", ");
}
SQLExpr expr = x.getValues().get(i);
expr.setParent(x);
expr.accept(this);
SQLExpr expr = values.get(i);
if (expr instanceof SQLIntegerExpr) {
visit((SQLIntegerExpr) expr);
} else if (expr instanceof SQLCharExpr) {
visit((SQLCharExpr) expr);
} else if (expr instanceof SQLBooleanExpr) {
visit((SQLBooleanExpr) expr);
} else if (expr instanceof SQLNumberExpr) {
visit((SQLNumberExpr) expr);
} else if (expr instanceof SQLNullExpr) {
visit((SQLNullExpr) expr);
} else if (expr instanceof SQLVariantRefExpr) {
visit((SQLVariantRefExpr) expr);
} else if (expr instanceof SQLNCharExpr) {
visit((SQLNCharExpr) expr);
} else {
expr.accept(this);
}
}
decrementIndent();
this.indentCount--;
print(')');
return false;
}
@@ -3374,7 +3426,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
public boolean visit(SQLBooleanExpr x) {
print0(x.getValue() ? "true" : "false");
return false;
}
@@ -1,46 +0,0 @@
/*
* Copyright 1999-2017 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.visitor;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
public class SQLASTOutputVisitorUtils {
public static boolean visit(PrintableVisitor visitor, SQLIntegerExpr x) {
visitor.print(x.getNumber().toString());
return false;
}
public static boolean visit(PrintableVisitor visitor, SQLNumberExpr x) {
visitor.print(x.getNumber().toString());
return false;
}
public static boolean visit(PrintableVisitor visitor, SQLCharExpr x) {
visitor.print('\'');
String text = x.getText();
text = text.replaceAll("'", "''");
text = text.replaceAll("\\\\", "\\\\");
visitor.print(text);
visitor.print('\'');
return false;
}
}
@@ -152,10 +152,108 @@ public class StringUtils {
}
public static boolean isNumber(String str) {
if (isEmpty(str)) {
if (str.length() == 0) {
return false;
}
int sz = str.length();
boolean hasExp = false;
boolean hasDecPoint = false;
boolean allowSigns = false;
boolean foundDigit = false;
// deal with any possible sign up front
int start = (str.charAt(0) == '-') ? 1 : 0;
if (sz > start + 1) {
if (str.charAt(start) == '0' && str.charAt(start + 1) == 'x') {
int i = start + 2;
if (i == sz) {
return false; // str == "0x"
}
// checking hex (it can't be anything else)
for (; i < str.length(); i++) {
char ch = str.charAt(i);
if ((ch < '0' || ch > '9')
&& (ch < 'a' || ch > 'f')
&& (ch < 'A' || ch > 'F')) {
return false;
}
}
return true;
}
}
sz--; // don't want to loop to the last char, check it afterwords
// for type qualifiers
int i = start;
// loop to the next to last char or to the last char if we need another digit to
// make a valid number (e.g. chars[0..5] = "1234E")
while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
char ch = str.charAt(i);
if (ch >= '0' && ch <= '9') {
foundDigit = true;
allowSigns = false;
} else if (ch == '.') {
if (hasDecPoint || hasExp) {
// two decimal points or dec in exponent
return false;
}
hasDecPoint = true;
} else if (ch == 'e' || ch == 'E') {
// we've already taken care of hex.
if (hasExp) {
// two E's
return false;
}
if (!foundDigit) {
return false;
}
hasExp = true;
allowSigns = true;
} else if (ch == '+' || ch == '-') {
if (!allowSigns) {
return false;
}
allowSigns = false;
foundDigit = false; // we need a digit after the E
} else {
return false;
}
i++;
}
if (i < str.length()) {
char ch = str.charAt(i);
if (ch >= '0' && ch <= '9') {
// no type qualifier, OK
return true;
}
if (ch == 'e' || ch == 'E') {
// can't have an E at the last byte
return false;
}
if (!allowSigns
&& (ch == 'd'
|| ch == 'D'
|| ch == 'f'
|| ch == 'F')) {
return foundDigit;
}
if (ch == 'l'
|| ch == 'L') {
// not allowing L with an exponent
return foundDigit && !hasExp;
}
// last character is illegal
return false;
}
// allowSigns is true iff the val ends in 'E'
// found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
return !allowSigns && foundDigit;
}
public static boolean isNumber(char[] chars) {
if (chars.length == 0) {
return false;
}
char[] chars = str.toCharArray();
int sz = chars.length;
boolean hasExp = false;
boolean hasDecPoint = false;
@@ -171,9 +269,10 @@ public class StringUtils {
}
// checking hex (it can't be anything else)
for (; i < chars.length; i++) {
if ((chars[i] < '0' || chars[i] > '9')
&& (chars[i] < 'a' || chars[i] > 'f')
&& (chars[i] < 'A' || chars[i] > 'F')) {
char ch = chars[i];
if ((ch < '0' || ch > '9')
&& (ch < 'a' || ch > 'f')
&& (ch < 'A' || ch > 'F')) {
return false;
}
}
@@ -186,17 +285,18 @@ public class StringUtils {
// loop to the next to last char or to the last char if we need another digit to
// make a valid number (e.g. chars[0..5] = "1234E")
while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
if (chars[i] >= '0' && chars[i] <= '9') {
char ch = chars[i];
if (ch >= '0' && ch <= '9') {
foundDigit = true;
allowSigns = false;
} else if (chars[i] == '.') {
} else if (ch == '.') {
if (hasDecPoint || hasExp) {
// two decimal points or dec in exponent
return false;
}
hasDecPoint = true;
} else if (chars[i] == 'e' || chars[i] == 'E') {
} else if (ch == 'e' || ch == 'E') {
// we've already taken care of hex.
if (hasExp) {
// two E's
@@ -207,7 +307,7 @@ public class StringUtils {
}
hasExp = true;
allowSigns = true;
} else if (chars[i] == '+' || chars[i] == '-') {
} else if (ch == '+' || ch == '-') {
if (!allowSigns) {
return false;
}
@@ -219,23 +319,24 @@ public class StringUtils {
i++;
}
if (i < chars.length) {
if (chars[i] >= '0' && chars[i] <= '9') {
char ch = chars[i];
if (ch >= '0' && ch <= '9') {
// no type qualifier, OK
return true;
}
if (chars[i] == 'e' || chars[i] == 'E') {
if (ch == 'e' || ch == 'E') {
// can't have an E at the last byte
return false;
}
if (!allowSigns
&& (chars[i] == 'd'
|| chars[i] == 'D'
|| chars[i] == 'f'
|| chars[i] == 'F')) {
&& (ch == 'd'
|| ch == 'D'
|| ch == 'f'
|| ch == 'F')) {
return foundDigit;
}
if (chars[i] == 'l'
|| chars[i] == 'L') {
if (ch == 'l'
|| ch == 'L') {
// not allowing L with an exponent
return foundDigit && !hasExp;
}
@@ -0,0 +1,48 @@
package com.alibaba.druid.benckmark.sql;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.TestCase;
import org.apache.ibatis.jdbc.SQL;
import java.util.List;
public class MySqlInsertBenchmark extends TestCase {
static String sql = "INSERT INTO test_table VALUES (1, '1', '2017-10-10', true, false, '2017-10-10 10:10:10', '10:10:10', 1.111, null);";
List<SQLStatement> stmtList;
protected void setUp() throws Exception {
stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
}
public void test_perf() throws Exception {
for (int i = 0; i < 5; ++i) {
perf();
// perf_toString(); // 425
}
}
public void perf_toString() {
long startMillis = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
SQLUtils.toMySqlString(stmtList.get(0));
}
long millis = System.currentTimeMillis() - startMillis;
System.out.println("millis : " + millis);
}
public void perf() {
long startMillis = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
List<SQLStatement> stmt = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
// stmt.toString();
}
long millis = System.currentTimeMillis() - startMillis;
System.out.println("millis : " + millis);
}
}
@@ -0,0 +1,50 @@
package com.alibaba.druid.benckmark.sql;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.TestCase;
import java.util.List;
public class MySqlInsertBenchmark_2 extends TestCase {
static String sql = "INSERT INTO test_table VALUES (1, '1', '2017-10-10', true, false, '2017-10-10 10:10:10', '10:10:10', 1.111, NULL), (2, '2', '2017-10-10', true, false, '2017-10-10 10:10:10', '10:10:10', 2.222, NULL)" +
", (2, '2', '2017-09-09', true, false, '2017-10-10 10:10:10', '10:10:10', 3.333, NULL)" +
", (3, '3', '2017-10-10', true, false, '2017-10-10 10:10:10', '11:11:11', 4.333, NULL)" +
", (4, '4', '2017-10-10', true, false, '2017-10-10 10:10:10', '11:11:11', 4.333, NULL)" +
", (5, '5', '2017-10-10', true, false, '2017-10-10 10:10:10', '11:11:11', 4.333, NULL);";
List<SQLStatement> stmtList;
protected void setUp() throws Exception {
stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
}
public void test_perf() throws Exception {
System.out.println(sql);
for (int i = 0; i < 5; ++i) {
perf(); // 5043
// perf_toString(); // 2101
}
}
public void perf() {
long startMillis = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
List<SQLStatement> stmt = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
// stmt.toString();
}
long millis = System.currentTimeMillis() - startMillis;
System.out.println("millis : " + millis);
}
public void perf_toString() {
long startMillis = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
SQLUtils.toMySqlString(stmtList.get(0));
}
long millis = System.currentTimeMillis() - startMillis;
System.out.println("millis : " + millis);
}
}
@@ -61,7 +61,7 @@ public class DMLInsertParserTest extends TestCase {
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1\nVALUES (0.12, 1, 2)," + //
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1\nVALUES (12e-2, 1, 2)," + //
"\n\t(?)," + //
"\n\t(DEFAULT)", output);
}
@@ -59,7 +59,7 @@ public class DMLReplaceParserTest extends TestCase {
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1\nVALUES (0.12), (?)", output);
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1\nVALUES (12e-2), (?)", output);
}
public void testReplace_4() throws Exception {
@@ -268,7 +268,7 @@ public class MathematicalFunctionsTest extends TestCase {
String text = output(stmtList);
Assert.assertEquals("SELECT PI() + 0E-18", text);
Assert.assertEquals("SELECT PI() + 0.000000000000000000", text);
}
public void test_22() throws Exception {
@@ -323,7 +323,7 @@ public class MathematicalFunctionsTest extends TestCase {
String text = output(stmtList);
Assert.assertEquals("SELECT ROUND(2.5), ROUND(2.5)", text);
Assert.assertEquals("SELECT ROUND(2.5), ROUND(25E-1)", text);
}
private String output(List<SQLStatement> stmtList) {
@@ -38,7 +38,7 @@ public class NumberTest extends TestCase {
String text = SQLUtils.toSQLString(stmtList, JdbcConstants.MYSQL);
Assert.assertEquals("SELECT -3.20326809E+14;", text);
Assert.assertEquals("SELECT -32032.6809e+10;", text);
}
public void test_1() throws Exception {
@@ -56,10 +56,10 @@ public class OdpsSelectTest22 extends TestCase {
") A\n" +
"group by bucket_id;";//
assertEquals("SELECT bucket_id, SUM(pv) AS pv, SUM(clk) AS clk\n" +
"\t, SUM(clk) / (SUM(pv) + 1E-10) AS ctr\n" +
"\t, SUM(clk) / (SUM(pv) + 1e-10) AS ctr\n" +
"\t, SUM(ut_ad_clk) AS ut_ad_clk, SUM(ad_clk) AS ad_clk\n" +
"\t, SUM(cost) AS cost\n" +
"\t, SUM(cost) * 1000 / (SUM(pv) + 1E-10) / 100 AS rpm\n" +
"\t, SUM(cost) * 1000 / (SUM(pv) + 1e-10) / 100 AS rpm\n" +
"FROM (\n" +
"\tSELECT bucket_id, UT.pv AS pv, UT.clk AS clk, UT.ad_clk AS ut_ad_clk, CLK.clk AS ad_clk\n" +
"\t\t, CLK.cost AS cost\n" +
@@ -95,10 +95,10 @@ public class OdpsSelectTest22 extends TestCase {
"GROUP BY bucket_id;", SQLUtils.formatOdps(sql));
assertEquals("select bucket_id, sum(pv) as pv, sum(clk) as clk\n" +
"\t, sum(clk) / (sum(pv) + 1E-10) as ctr\n" +
"\t, sum(clk) / (sum(pv) + 1e-10) as ctr\n" +
"\t, sum(ut_ad_clk) as ut_ad_clk, sum(ad_clk) as ad_clk\n" +
"\t, sum(cost) as cost\n" +
"\t, sum(cost) * 1000 / (sum(pv) + 1E-10) / 100 as rpm\n" +
"\t, sum(cost) * 1000 / (sum(pv) + 1e-10) / 100 as rpm\n" +
"from (\n" +
"\tselect bucket_id, UT.pv as pv, UT.clk as clk, UT.ad_clk as ut_ad_clk, CLK.clk as ad_clk\n" +
"\t\t, CLK.cost as cost\n" +
@@ -32,7 +32,7 @@ public class OracleNumberLiteralTest extends TestCase {
String text = TestUtils.outputOracle(stmt);
Assert.assertEquals("SELECT 7, 255, 0.5, 6.34, 0.025\n\t, 6.34F, 0.5D, -1.0D\nFROM DUAL", text);
Assert.assertEquals("SELECT 7, 255, 0.5, 6.34, 25e-03\n\t, 6.34F, 0.5D, -1.0D\nFROM DUAL", text);
System.out.println(text);
}
@@ -46,7 +46,7 @@ public class OracleInsertTest12 extends OracleTest {
+ "\n\t(employee_id, last_name, email, hire_date, job_id" //
+ "\n\t, salary, commission_pct)" //
+ "\nVALUES (207, 'Gregory', 'pgregory@example.com', SYSDATE, 'PU_CLERK'" //
+ "\n\t, 1.2E+3, NULL);",//
+ "\n\t, 1.2E3, NULL);",//
SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
@@ -45,7 +45,7 @@ public class OracleInsertTest14 extends OracleTest {
Assert.assertEquals("INSERT INTO raises" //
+ "\nSELECT employee_id, salary * 1.1"//
+ "\nFROM employees"//
+ "\nWHERE commission_pct > 0.2"//
+ "\nWHERE commission_pct > .2"//
+ "\nLOG ERRORS INTO errlog ('my_bad') REJECT LIMIT 10;",//
SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE));