mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -446,7 +446,7 @@ public class SQLTransformUtils {
|
||||
int precision, scale = 0;
|
||||
if (arg0 instanceof SQLAllColumnExpr) {
|
||||
precision = 19;
|
||||
scale = 0;
|
||||
scale = -1;
|
||||
} else {
|
||||
precision = ((SQLIntegerExpr) arg0).getNumber().intValue();
|
||||
}
|
||||
@@ -476,6 +476,8 @@ public class SQLTransformUtils {
|
||||
} else {
|
||||
dataType = new SQLDataTypeImpl(SQLDataType.Constants.DECIMAL, precision);
|
||||
}
|
||||
} else if (scale == -1) {
|
||||
dataType = new SQLDataTypeImpl(SQLDataType.Constants.DOUBLE_PRECISION);
|
||||
} else {
|
||||
dataType = new SQLDataTypeImpl(SQLDataType.Constants.DECIMAL, precision, scale);
|
||||
}
|
||||
@@ -622,4 +624,13 @@ public class SQLTransformUtils {
|
||||
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public static SQLExpr transformOracleToPostgresql(SQLMethodInvokeExpr x) {
|
||||
long nameHashCode64 = x.methodNameHashCode64();
|
||||
if (nameHashCode64 == FnvHash.Constants.SYS_GUID) {
|
||||
SQLMethodInvokeExpr uuid_generate_v4 = new SQLMethodInvokeExpr("uuid_generate_v4");
|
||||
return uuid_generate_v4;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ public interface SQLDataType extends SQLObject {
|
||||
String CHAR = "CHAR";
|
||||
String NCHAR = "NCHAR";
|
||||
String VARCHAR = "VARCHAR";
|
||||
String DATE = "DATE";
|
||||
String TIMESTAMP = "TIMESTAMP";
|
||||
String XML = "XML";
|
||||
|
||||
|
||||
@@ -26,11 +26,12 @@ import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLReplaceable;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
|
||||
public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String methodName;
|
||||
private String name;
|
||||
private SQLExpr owner;
|
||||
private final List<SQLExpr> parameters = new ArrayList<SQLExpr>();
|
||||
|
||||
@@ -40,34 +41,50 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
|
||||
private String trimOption;
|
||||
|
||||
private long nameHashCode64;
|
||||
|
||||
public SQLMethodInvokeExpr(){
|
||||
|
||||
}
|
||||
|
||||
public SQLMethodInvokeExpr(String methodName){
|
||||
this.methodName = methodName;
|
||||
this.name = methodName;
|
||||
}
|
||||
|
||||
public SQLMethodInvokeExpr(String methodName, long nameHashCode64){
|
||||
this.name = methodName;
|
||||
this.nameHashCode64 = nameHashCode64;
|
||||
}
|
||||
|
||||
public SQLMethodInvokeExpr(String methodName, SQLExpr owner){
|
||||
|
||||
this.methodName = methodName;
|
||||
this.name = methodName;
|
||||
setOwner(owner);
|
||||
}
|
||||
|
||||
public SQLMethodInvokeExpr(String methodName, SQLExpr owner, SQLExpr... params){
|
||||
this.methodName = methodName;
|
||||
this.name = methodName;
|
||||
setOwner(owner);
|
||||
for (SQLExpr param : params) {
|
||||
this.addParameter(param);
|
||||
}
|
||||
}
|
||||
|
||||
public long methodNameHashCode64() {
|
||||
if (nameHashCode64 == 0
|
||||
&& name != null) {
|
||||
nameHashCode64 = FnvHash.hashCode64(name);
|
||||
}
|
||||
return nameHashCode64;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return this.methodName;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
this.name = methodName;
|
||||
this.nameHashCode64 = 0L;
|
||||
}
|
||||
|
||||
public SQLExpr getOwner() {
|
||||
@@ -106,7 +123,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
buf.append(".");
|
||||
}
|
||||
|
||||
buf.append(this.methodName);
|
||||
buf.append(this.name);
|
||||
buf.append("(");
|
||||
for (int i = 0, size = this.parameters.size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
@@ -144,7 +161,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
|
||||
SQLMethodInvokeExpr that = (SQLMethodInvokeExpr) o;
|
||||
|
||||
if (methodName != null ? !methodName.equals(that.methodName) : that.methodName != null) return false;
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) return false;
|
||||
if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false;
|
||||
if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) return false;
|
||||
return from != null ? from.equals(that.from) : that.from == null;
|
||||
@@ -153,7 +170,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = methodName != null ? methodName.hashCode() : 0;
|
||||
int result = name != null ? name.hashCode() : 0;
|
||||
result = 31 * result + (owner != null ? owner.hashCode() : 0);
|
||||
result = 31 * result + (parameters != null ? parameters.hashCode() : 0);
|
||||
result = 31 * result + (from != null ? from.hashCode() : 0);
|
||||
@@ -163,7 +180,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
public SQLMethodInvokeExpr clone() {
|
||||
SQLMethodInvokeExpr x = new SQLMethodInvokeExpr();
|
||||
|
||||
x.methodName = methodName;
|
||||
x.name = name;
|
||||
|
||||
if (owner != null) {
|
||||
x.setOwner(owner.clone());
|
||||
@@ -204,7 +221,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SQLUtils.nameEquals(function, methodName)) {
|
||||
if (!SQLUtils.nameEquals(function, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -224,19 +241,19 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (SQLUtils.nameEquals("to_date", methodName)
|
||||
|| SQLUtils.nameEquals("add_months", methodName)) {
|
||||
if (SQLUtils.nameEquals("to_date", name)
|
||||
|| SQLUtils.nameEquals("add_months", name)) {
|
||||
return SQLDateExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
|
||||
if (parameters.size() == 1) {
|
||||
if (SQLUtils.nameEquals("trunc", methodName)) {
|
||||
if (SQLUtils.nameEquals("trunc", name)) {
|
||||
return parameters.get(0).computeDataType();
|
||||
}
|
||||
} else if (parameters.size() == 2) {
|
||||
SQLExpr param0 = parameters.get(0);
|
||||
SQLExpr param1 = parameters.get(1);
|
||||
if (SQLUtils.nameEquals("nvl", methodName) || SQLUtils.nameEquals("ifnull", methodName)) {
|
||||
if (SQLUtils.nameEquals("nvl", name) || SQLUtils.nameEquals("ifnull", name)) {
|
||||
SQLDataType dataType = param0.computeDataType();
|
||||
if (dataType != null) {
|
||||
return dataType;
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class SQLNumberExpr extends SQLNumericLiteralExpr implements SQLValuableExpr {
|
||||
private static SQLDataType defaultDataType = new SQLDataTypeImpl("number");
|
||||
public final static SQLDataType defaultDataType = new SQLDataTypeImpl("number");
|
||||
|
||||
private Number number;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElement, SQLObjectWithDataType {
|
||||
public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElement, SQLObjectWithDataType, SQLReplaceable {
|
||||
protected String dbType;
|
||||
|
||||
protected SQLName name;
|
||||
@@ -250,6 +250,21 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(SQLExpr expr, SQLExpr target) {
|
||||
if (defaultExpr == expr) {
|
||||
setDefaultExpr(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == expr) {
|
||||
setName((SQLName) target);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class Identity extends SQLObjectImpl {
|
||||
|
||||
private Integer seed;
|
||||
|
||||
@@ -124,6 +124,12 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
lexer.reset(6, ' ', Token.UPDATE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == '/' && c1 == '*' && isEnabled(SQLParserFeature.OptimizedForParameterized)) {
|
||||
MySqlLexer mySqlLexer = (MySqlLexer) lexer;
|
||||
mySqlLexer.skipFirstHintsOrMultiCommentAndNextToken();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.lexer.nextToken();
|
||||
|
||||
|
||||
@@ -401,6 +401,89 @@ public class MySqlLexer extends Lexer {
|
||||
scanString2();
|
||||
}
|
||||
|
||||
public void skipFirstHintsOrMultiCommentAndNextToken() {
|
||||
int starIndex = pos + 2;
|
||||
|
||||
for (;;) {
|
||||
starIndex = text.indexOf('*', starIndex);
|
||||
if (starIndex == -1 || starIndex == text.length() - 1) {
|
||||
this.token = Token.ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
int slashIndex = starIndex + 1;
|
||||
if (charAt(slashIndex) == '/') {
|
||||
pos = slashIndex + 1;
|
||||
ch = text.charAt(pos);
|
||||
if (pos < text.length() - 6) {
|
||||
int pos_6 = pos + 6;
|
||||
char c0 = ch;
|
||||
char c1 = text.charAt(pos + 1);
|
||||
char c2 = text.charAt(pos + 2);
|
||||
char c3 = text.charAt(pos + 3);
|
||||
char c4 = text.charAt(pos + 4);
|
||||
char c5 = text.charAt(pos + 5);
|
||||
char c6 = text.charAt(pos_6);
|
||||
if (c0 == 's' && c1 == 'e' && c2 == 'l' && c3 == 'e' && c4 == 'c' && c5 == 't' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.SELECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'i' && c1 == 'n' && c2 == 's' && c3 == 'e' && c4 == 'r' && c5 == 't' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.INSERT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'u' && c1 == 'p' && c2 == 'd' && c3 == 'a' && c4 == 't' && c5 == 'e' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.UPDATE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (c0 == 'd' && c1 == 'e' && c2 == 'l' && c3 == 'e' && c4 == 't' && c5 == 'e' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.DELETE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'S' && c1 == 'E' && c2 == 'L' && c3 == 'E' && c4 == 'C' && c5 == 'T' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.SELECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'I' && c1 == 'N' && c2 == 'S' && c3 == 'E' && c4 == 'R' && c5 == 'T' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.INSERT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'U' && c1 == 'P' && c2 == 'D' && c3 == 'A' && c4 == 'T' && c5 == 'E' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.UPDATE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'D' && c1 == 'E' && c2 == 'L' && c3 == 'E' && c4 == 'T' && c5 == 'E' && c6 == ' ') {
|
||||
this.comments = null;
|
||||
reset(pos_6, ' ', Token.DELETE);
|
||||
return;
|
||||
}
|
||||
|
||||
nextToken();
|
||||
return;
|
||||
} else {
|
||||
nextToken();
|
||||
return;
|
||||
}
|
||||
}
|
||||
starIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public void scanComment() {
|
||||
Token lastToken = this.token;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class Lexer {
|
||||
protected long hash;
|
||||
|
||||
protected int commentCount = 0;
|
||||
protected List<String> comments = new ArrayList<String>(2);
|
||||
protected List<String> comments = null;
|
||||
protected boolean skipComment = true;
|
||||
private SavePoint savePoint = null;
|
||||
|
||||
|
||||
@@ -913,7 +913,7 @@ public class SQLExprParser extends SQLParser {
|
||||
SQLExpr owner = null;
|
||||
String trimOption = null;
|
||||
|
||||
long hash_lower;
|
||||
long hash_lower = 0L;
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
|
||||
methodName = identifierExpr.getName();
|
||||
@@ -964,7 +964,7 @@ public class SQLExprParser extends SQLParser {
|
||||
return aggregateExpr;
|
||||
}
|
||||
|
||||
methodInvokeExpr = new SQLMethodInvokeExpr(methodName);
|
||||
methodInvokeExpr = new SQLMethodInvokeExpr(methodName, hash_lower);
|
||||
if (owner != null) {
|
||||
methodInvokeExpr.setOwner(owner);
|
||||
}
|
||||
|
||||
@@ -565,10 +565,16 @@ public class SQLSelectParser extends SQLParser {
|
||||
|
||||
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
|
||||
if ((tableSource.getAlias() == null) || (tableSource.getAlias().length() == 0)) {
|
||||
if (lexer.token != Token.LEFT && lexer.token != Token.RIGHT && lexer.token != Token.FULL
|
||||
&& (!lexer.identifierEquals(FnvHash.Constants.STRAIGHT_JOIN))
|
||||
&& (!lexer.identifierEquals(FnvHash.Constants.CROSS))
|
||||
&& lexer.token != Token.OUTER) {
|
||||
Token token = lexer.token;
|
||||
long hash;
|
||||
if (token != Token.LEFT
|
||||
&& token != Token.RIGHT
|
||||
&& token != Token.FULL
|
||||
&& token != Token.OUTER
|
||||
&& !(token == Token.IDENTIFIER
|
||||
&& ((hash = lexer.hash_lower()) == FnvHash.Constants.STRAIGHT_JOIN
|
||||
|| hash == FnvHash.Constants.CROSS)))
|
||||
{
|
||||
String alias = tableAlias();
|
||||
if (alias != null) {
|
||||
tableSource.setAlias(alias);
|
||||
|
||||
@@ -15,10 +15,14 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.parser;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* @author wenshao[szujobs@hotmail.com]
|
||||
*/
|
||||
public class SymbolTable {
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
public static SymbolTable global = new SymbolTable(8192);
|
||||
|
||||
private final Entry[] entries;
|
||||
@@ -29,15 +33,12 @@ public class SymbolTable {
|
||||
this.entries = new Entry[tableSize];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String addSymbol(String buffer, int offset, int len, long hash) {
|
||||
final int bucket = ((int) hash) & indexMask;
|
||||
|
||||
Entry entry = entries[bucket];
|
||||
if (entry != null) {
|
||||
if (hash == entry.hash //
|
||||
&& len == entry.len) {
|
||||
if (hash == entry.hash) {
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
@@ -52,12 +53,64 @@ public class SymbolTable {
|
||||
return str;
|
||||
}
|
||||
|
||||
public String addSymbol(byte[] buffer, int offset, int len, long hash) {
|
||||
final int bucket = ((int) hash) & indexMask;
|
||||
|
||||
Entry entry = entries[bucket];
|
||||
if (entry != null) {
|
||||
if (hash == entry.hash) {
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
String str = subString(buffer, offset, len);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
String str = subString(buffer, offset, len);
|
||||
entry = new Entry(hash, len, str);
|
||||
entries[bucket] = entry;
|
||||
return str;
|
||||
}
|
||||
|
||||
public String addSymbol(String symbol, long hash) {
|
||||
final int bucket = ((int) hash) & indexMask;
|
||||
|
||||
Entry entry = entries[bucket];
|
||||
if (entry != null) {
|
||||
if (hash == entry.hash) {
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
entry = new Entry(hash, symbol.length(), symbol);
|
||||
entries[bucket] = entry;
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public String findSymbol(long hash) {
|
||||
final int bucket = ((int) hash) & indexMask;
|
||||
Entry entry = entries[bucket];
|
||||
if (entry != null && entry.hash == hash) {
|
||||
return entry.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String subString(String src, int offset, int len) {
|
||||
char[] chars = new char[len];
|
||||
src.getChars(offset, offset + len, chars, 0);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
private static String subString(byte[] bytes, int from, int len) {
|
||||
byte[] strBytes = new byte[len];
|
||||
System.arraycopy(bytes, from, strBytes, 0, len);
|
||||
return new String(strBytes, UTF8);
|
||||
}
|
||||
|
||||
private static class Entry {
|
||||
public final long hash;
|
||||
public final int len;
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ParameterizedOutputVisitorUtils {
|
||||
}
|
||||
|
||||
if (visitor.getReplaceCount() == 0
|
||||
&& parser.getLexer().getCommentCount() == 0) {
|
||||
&& parser.getLexer().getCommentCount() == 0 && sql.charAt(0) != '/') {
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,25 @@ public final class FnvHash {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static long fnv1a_64(byte[] input, int offset, int end) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (input.length < end) {
|
||||
end = input.length;
|
||||
}
|
||||
|
||||
long hash = BASIC;
|
||||
for (int i = offset; i < end; ++i) {
|
||||
byte c = input[i];
|
||||
hash ^= c;
|
||||
hash *= PRIME;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static long fnv1a_64(char[] chars) {
|
||||
if (chars == null) {
|
||||
return 0;
|
||||
@@ -468,5 +487,13 @@ public final class FnvHash {
|
||||
long SOURCE = fnv1a_64_lower("SOURCE");
|
||||
|
||||
long STAR = fnv1a_64_lower("*");
|
||||
|
||||
long TO_CHAR = fnv1a_64_lower("TO_CHAR");
|
||||
long SYS_GUID = fnv1a_64_lower("SYS_GUID");
|
||||
|
||||
long STATISTICS = fnv1a_64_lower("STATISTICS");
|
||||
long TRANSACTION = fnv1a_64_lower("TRANSACTION");
|
||||
long OFF = fnv1a_64_lower("OFF");
|
||||
long IDENTITY_INSERT = fnv1a_64_lower("IDENTITY_INSERT");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.alibaba.druid.bvt.sql;
|
||||
|
||||
import com.alibaba.druid.sql.parser.SymbolTable;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SymbolTableTest extends TestCase {
|
||||
public void test_symbols() throws Exception {
|
||||
SymbolTable symbols = new SymbolTable(65535);
|
||||
|
||||
String[] strings = new String[10];
|
||||
for (int i = 0; i < strings.length; ++i) {
|
||||
String str = "abc" + i;
|
||||
strings[i] = str;
|
||||
symbols.addSymbol(str, FnvHash.fnv1a_64(str));
|
||||
}
|
||||
|
||||
for (int i = 0; i < strings.length; ++i) {
|
||||
String str = strings[i];
|
||||
long hash = FnvHash.fnv1a_64(str);
|
||||
String symbol = symbols.findSymbol(hash);
|
||||
assertSame(str, symbol);
|
||||
}
|
||||
{
|
||||
byte[] bytes = "kkk#abc0#aa".getBytes();
|
||||
long hash = FnvHash.fnv1a_64(bytes, 4, 8);
|
||||
String symbol = symbols.addSymbol(bytes, 4, 8, hash);
|
||||
assertSame(strings[0], symbol);
|
||||
}
|
||||
|
||||
byte[] bytes = "xab#time:3333".getBytes();
|
||||
System.out.println(indexOfTime(bytes, 1));
|
||||
System.out.println("xab#time:3333".indexOf("#time"));
|
||||
}
|
||||
|
||||
public static int indexOfTime(byte[] bytes, int fromIndex) {
|
||||
int end = bytes.length - 5;
|
||||
for (int i = fromIndex; i < end; ++i) {
|
||||
if (bytes[i] == '#'
|
||||
&& bytes[i + 1] == 't'
|
||||
&& bytes[i + 2] == 'i'
|
||||
&& bytes[i + 3] == 'm'
|
||||
&& bytes[i + 4] == 'e') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
package com.alibaba.druid.bvt.sql;
|
||||
|
||||
import com.alibaba.druid.sql.parser.SymbolTable;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by yunning on 16/7/10.
|
||||
*/
|
||||
public class TestNewSpout {
|
||||
|
||||
|
||||
public static int indexOf_nsharp(byte[] bytes, int fromIndex) {
|
||||
int end = bytes.length - 2;
|
||||
for (int i = fromIndex; i < end; ++i) {
|
||||
if (bytes[i] == '\n'
|
||||
&& bytes[i + 1] == '#') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int indexOf_nReturn(byte[] bytes, int fromIndex) {
|
||||
for (int i = fromIndex; i < bytes.length; ++i) {
|
||||
if (bytes[i] == '\n') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int indexOfTime(byte[] bytes, int fromIndex) {
|
||||
int end = bytes.length - 5;
|
||||
for (int i = fromIndex; i < end; ++i) {
|
||||
if (bytes[i] == '#'
|
||||
&& bytes[i + 1] == 't'
|
||||
&& bytes[i + 2] == 'i'
|
||||
&& bytes[i + 3] == 'm'
|
||||
&& bytes[i + 4] == 'e') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static final SymbolTable dbSymbols = new SymbolTable(1024 * 256);
|
||||
|
||||
public static String substring(byte[] bytes, int from, int to) {
|
||||
int newLength = to - from;
|
||||
byte[] copy = new byte[newLength];
|
||||
System.arraycopy(bytes, from, copy, 0, newLength);
|
||||
return new String(copy, Charset.forName("UTF-8"));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final String datass = "#time:1470191976686205\n" +
|
||||
"#user@host:monitor[monitor] @ [127.0.0.1]\n" +
|
||||
"#db:test\n" +
|
||||
"#table_name:aa\n" +
|
||||
"set session time_zone='+08:00';\n" +
|
||||
"#query_time:0.000028123456789987654321\n" +
|
||||
"#lock_time:0.000000\n" +
|
||||
"#rows_sent:0\n" +
|
||||
"#rows_examined:0\n" +
|
||||
"#rows_affected:0\n" +
|
||||
"#innodb_pages_read:1\n" +
|
||||
"#innodb_pages_io_read:2\n" +
|
||||
"#id:55438\n" +
|
||||
"#time:1470191976686207\n" +
|
||||
"#user@host:monitor[monitor] @ [127.0.0.1]\n" +
|
||||
"#db:test\n" +
|
||||
"#table_name:aa\n" +
|
||||
"#time:1470191976686206\n" +
|
||||
"#user@host:monitor[monitor] @ [127.0.0.1]\n" +
|
||||
"#db:test\n" +
|
||||
"#table_name:aa\n" +
|
||||
"set session time_zone='+0800';\n" +
|
||||
"#query_time:0.000028123456789987654322\n" +
|
||||
"#lock_time:0.000000\n" +
|
||||
"#rows_sent:0\n" +
|
||||
"#rows_examined:0\n" +
|
||||
"#rows_affected:0\n" +
|
||||
"#innodb_pages_read:0\n" +
|
||||
"#innodb_pages_io_read:0\n" +
|
||||
"#id:123";
|
||||
|
||||
byte[] datas = datass.getBytes();
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 1; i++) {
|
||||
final int len = datas.length;
|
||||
int offset = indexOfTime(datas, 0);
|
||||
long now = System.nanoTime();
|
||||
while (offset != -1) {
|
||||
int rowOffset = offset;
|
||||
int k = 0;
|
||||
final int[] offsets = new int[12];
|
||||
boolean isNoFirst = false;
|
||||
while (rowOffset != -1 && k < 12) {
|
||||
if (isNoFirst && rowOffset + 5 <= len - 1) {
|
||||
if (datas[rowOffset + 2] == 't' &&
|
||||
datas[rowOffset + 3] == 'i' &&
|
||||
datas[rowOffset + 4] == 'm' &&
|
||||
datas[rowOffset + 5] == 'e') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
offsets[k] = rowOffset;
|
||||
rowOffset = indexOf_nsharp(datas, rowOffset + 1);
|
||||
k = k + 1;
|
||||
isNoFirst = true;
|
||||
}
|
||||
offset = rowOffset == -1 ? -1 : indexOfTime(datas, rowOffset + 1);
|
||||
if (k < 12) {
|
||||
continue;
|
||||
}
|
||||
SqlInfo sqlInfo = new SqlInfo();
|
||||
// sqlInfo.setHostName(hostName);
|
||||
|
||||
boolean isError = false;
|
||||
String sql = null;
|
||||
|
||||
//time
|
||||
int currItemOffset = offsets[0];
|
||||
int nextItemOffset = offsets[1];
|
||||
/* String item = datas.substring(currItemOffset + 6, nextItemOffset);
|
||||
long itemTime = Long.parseLong(item);*/
|
||||
long itemTime = MathUtil.str2Long(datas, currItemOffset + 6, nextItemOffset);
|
||||
System.out.println("TIME : " + itemTime);
|
||||
if (itemTime < 0 || itemTime > 2000000000000000L) {
|
||||
}
|
||||
sqlInfo.setTime(itemTime);
|
||||
|
||||
//user@host
|
||||
currItemOffset = offsets[1];
|
||||
nextItemOffset = offsets[2];
|
||||
String item = substring(datas, currItemOffset + 12, nextItemOffset);
|
||||
System.out.println("user@host : " + item);
|
||||
// sqlInfo.setUserHost(item);
|
||||
|
||||
//db
|
||||
currItemOffset = offsets[2];
|
||||
nextItemOffset = offsets[3];
|
||||
int dbOffset = currItemOffset + 5;
|
||||
int dbLen = nextItemOffset - dbOffset;
|
||||
long dbHash = FnvHash.fnv1a_64(datas, dbOffset, nextItemOffset);
|
||||
String db = dbSymbols.addSymbol(datas, dbOffset, dbLen, dbHash);
|
||||
|
||||
// String db = substring(datas, currItemOffset + 5, nextItemOffset);
|
||||
System.out.println("db : " + db);
|
||||
if (dbLen > 0 && SqlUtil.filterDbs.indexOf(db) != -1) {
|
||||
// sqlInfo.setNotValiDB(true);
|
||||
} else {
|
||||
}
|
||||
|
||||
//table_name
|
||||
currItemOffset = offsets[3];
|
||||
nextItemOffset = offsets[4];
|
||||
int tsqlPos = currItemOffset + 13;
|
||||
int idx2 = indexOf_nReturn(datas, tsqlPos);
|
||||
String table = substring(datas, tsqlPos, idx2);
|
||||
sql = substring(datas, idx2 + 1, nextItemOffset);
|
||||
System.out.println("table : " + table + " : " + sql);
|
||||
|
||||
int totalLen = sql.length();
|
||||
if (totalLen < 9 ||
|
||||
totalLen >= 8000) {
|
||||
// sqlInfo.setParseRes(0);
|
||||
} else {
|
||||
}
|
||||
|
||||
//query_time
|
||||
currItemOffset = offsets[4];
|
||||
nextItemOffset = offsets[5];
|
||||
int rtBound = Math.min(nextItemOffset - currItemOffset, 24);
|
||||
double itemRt = MathUtil.str2Double(datas, currItemOffset + 13, currItemOffset + rtBound);
|
||||
sqlInfo.setQueryTime(itemRt);
|
||||
|
||||
//lock_time
|
||||
currItemOffset = offsets[5];
|
||||
nextItemOffset = offsets[6];
|
||||
int lockTimeBound = Math.min(nextItemOffset - currItemOffset, 23);
|
||||
double itemLockTime = MathUtil.str2Double(datas, currItemOffset + 12, currItemOffset + lockTimeBound);
|
||||
sqlInfo.setLockTime(itemLockTime);
|
||||
|
||||
//rows_sent
|
||||
currItemOffset = offsets[6];
|
||||
nextItemOffset = offsets[7];
|
||||
long itemRowsSent = MathUtil.str2Long(datas, currItemOffset + 12, nextItemOffset);
|
||||
if (itemRowsSent < 0 || itemRowsSent > 1000000000) {
|
||||
}
|
||||
// sqlInfo.setRowsSent(itemRowsSent);
|
||||
|
||||
//rows_examined
|
||||
currItemOffset = offsets[7];
|
||||
nextItemOffset = offsets[8];
|
||||
long itemRowsExam = MathUtil.str2Long(datas, currItemOffset + 16, nextItemOffset);
|
||||
if (itemRowsExam < 0 || itemRowsExam > 1000000000) {
|
||||
}
|
||||
// sqlInfo.setRowsExamined(itemRowsExam);
|
||||
|
||||
//rows_affected
|
||||
currItemOffset = offsets[8];
|
||||
nextItemOffset = offsets[9];
|
||||
long itemRowsAffected = MathUtil.str2Long(datas, currItemOffset + 16, nextItemOffset);
|
||||
if (itemRowsAffected < 0 || itemRowsAffected > 1000000000) {
|
||||
}
|
||||
sqlInfo.setRowsAffected(itemRowsAffected);
|
||||
|
||||
//innodb_pages_read
|
||||
currItemOffset = offsets[9];
|
||||
nextItemOffset = offsets[10];
|
||||
long itemPageRead = MathUtil.str2Long(datas, currItemOffset + 20, nextItemOffset);
|
||||
if (itemPageRead < 0 || itemPageRead > 1000000000) {
|
||||
}
|
||||
sqlInfo.setInnodbPagesRead(itemPageRead);
|
||||
|
||||
//innodb_pages_io_read
|
||||
currItemOffset = offsets[10];
|
||||
nextItemOffset = offsets[11];
|
||||
long itemPageIORead = MathUtil.str2Long(datas, currItemOffset + 23, nextItemOffset);
|
||||
if (itemPageIORead < 0 || itemPageIORead > 1000000000) {
|
||||
}
|
||||
// sqlInfo.setInnodbPagesIoRead(itemPageIORead);
|
||||
// currItemOffset = nextItemOffset;
|
||||
|
||||
/*nextItemOffset = datas.indexOf("\n#", currItemOffset + 1);
|
||||
if (nextItemOffset >= end) {
|
||||
return null;
|
||||
}
|
||||
itemEnd = nextItemOffset == -1 ? end : nextItemOffset;
|
||||
item = datas.substring(currItemOffset + 1, itemEnd);
|
||||
sqlInfo.setId(Long.parseLong(item.trim().substring(4)));
|
||||
num++;*/
|
||||
// sqlInfo.setId(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
System.out.println(System.currentTimeMillis() - start);
|
||||
}
|
||||
|
||||
static class SqlInfo {
|
||||
private long innodbPagesRead;
|
||||
private long time;
|
||||
private double queryTime;
|
||||
private double lockTime;
|
||||
public long rowsAffected;
|
||||
|
||||
public long getInnodbPagesRead() {
|
||||
return innodbPagesRead;
|
||||
}
|
||||
|
||||
public void setInnodbPagesRead(long innodbPagesRead) {
|
||||
this.innodbPagesRead = innodbPagesRead;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public void setQueryTime(double queryTime) {
|
||||
this.queryTime = queryTime;
|
||||
}
|
||||
|
||||
public void setLockTime(double lockTime) {
|
||||
this.lockTime = lockTime;
|
||||
}
|
||||
|
||||
public void setRowsAffected(long rowsAffected) {
|
||||
this.rowsAffected = rowsAffected;
|
||||
}
|
||||
}
|
||||
|
||||
static class MathUtil {
|
||||
public static long str2Long(byte[] data, int start, int end) {
|
||||
long value = 0;
|
||||
for (int i = start; i < end; ++i) {
|
||||
byte ch = data[i];
|
||||
if (ch == '.') break;
|
||||
int digit = data[i] - '0';
|
||||
value = value * 10 + digit;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static double str2Double(byte[] data,int start,int end) {
|
||||
long value = 0;
|
||||
long power = 0;
|
||||
for (int i = start; i < end; ++i) {
|
||||
byte ch = data[i];
|
||||
if (ch == '.') {
|
||||
power = 1;
|
||||
continue;
|
||||
}
|
||||
int digit = ch - '0';
|
||||
value = value * 10 + digit;
|
||||
power *= 10;
|
||||
}
|
||||
double doubleValue = (double) value;
|
||||
if (power == 0) {
|
||||
return doubleValue;
|
||||
} else {
|
||||
return doubleValue / power;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class SqlUtil {
|
||||
|
||||
public static Set<String> filterDb = new HashSet<String>();
|
||||
|
||||
private static int[] orders = new int[]{2, 3, 0, 1};
|
||||
|
||||
static {
|
||||
filterDb.add("DRC");
|
||||
filterDb.add("INFORMATION_SCHEMA");
|
||||
filterDb.add("INNODB_MEMCACHE");
|
||||
filterDb.add("MYSQL");
|
||||
filterDb.add("PERFORMANCE_SCHEMA");
|
||||
filterDb.add("RECYCLE_BIN");
|
||||
filterDb.add("ROCKSDB");
|
||||
filterDb.add("TEST");
|
||||
filterDb.add("DRC".toLowerCase());
|
||||
filterDb.add("INFORMATION_SCHEMA".toLowerCase());
|
||||
filterDb.add("INNODB_MEMCACHE".toLowerCase());
|
||||
filterDb.add("MYSQL".toLowerCase());
|
||||
filterDb.add("PERFORMANCE_SCHEMA".toLowerCase());
|
||||
filterDb.add("RECYCLE_BIN".toLowerCase());
|
||||
filterDb.add("ROCKSDB".toLowerCase());
|
||||
filterDb.add("TEST".toLowerCase());
|
||||
}
|
||||
|
||||
public static final String filterDbs = org.apache.commons.lang3.StringUtils.join(SqlUtil.filterDb, ",");
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.bvt.sql.mysql.select;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.sql.parser.SQLParserUtils;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlSelectTest_60_firstComment extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "/* xxx * xxxx */SELECT * from t where t ! = 1";
|
||||
|
||||
System.out.println(sql);
|
||||
|
||||
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, JdbcConstants.MYSQL, SQLParserFeature.OptimizedForParameterized);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL);
|
||||
stmt.accept(visitor);
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM t\n" +
|
||||
"WHERE t != 1", //
|
||||
output);
|
||||
}
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
|
||||
assertEquals("select *\n" +
|
||||
"from t\n" +
|
||||
"where t != 1", //
|
||||
output);
|
||||
}
|
||||
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true));
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM t\n" +
|
||||
"WHERE t != ?", //
|
||||
output);
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.bvt.sql.mysql.select;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.sql.parser.SQLParserUtils;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlSelectTest_61_firstComment_2 extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "/* xxx * xxxx */ SELECT * from t where t ! = 1";
|
||||
|
||||
System.out.println(sql);
|
||||
|
||||
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, JdbcConstants.MYSQL, SQLParserFeature.OptimizedForParameterized);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL);
|
||||
stmt.accept(visitor);
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM t\n" +
|
||||
"WHERE t != 1", //
|
||||
output);
|
||||
}
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
|
||||
assertEquals("select *\n" +
|
||||
"from t\n" +
|
||||
"where t != 1", //
|
||||
output);
|
||||
}
|
||||
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true));
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM t\n" +
|
||||
"WHERE t != ?", //
|
||||
output);
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.bvt.sql.mysql.select;
|
||||
|
||||
import com.alibaba.druid.sql.MysqlTest;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.sql.parser.SQLParserUtils;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MySqlSelectTest_62_optimized extends MysqlTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "SELECT * from t where t ! = 1";
|
||||
|
||||
System.out.println(sql);
|
||||
|
||||
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, JdbcConstants.MYSQL, SQLParserFeature.OptimizedForParameterized);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL);
|
||||
stmt.accept(visitor);
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM t\n" +
|
||||
"WHERE t != 1", //
|
||||
output);
|
||||
}
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
|
||||
assertEquals("select *\n" +
|
||||
"from t\n" +
|
||||
"where t != 1", //
|
||||
output);
|
||||
}
|
||||
|
||||
{
|
||||
String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true));
|
||||
assertEquals("SELECT *\n" +
|
||||
"FROM t\n" +
|
||||
"WHERE t != ?", //
|
||||
output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.bvt.sql.postgresql.select;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PGSelectTest57 extends TestCase {
|
||||
private final String dbType = JdbcConstants.POSTGRESQL;
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "SELECT ts#, file#, block#, cols, IFNULL(size$, -1), pctfree$, pctused$\n" +
|
||||
" , initrans, maxtrans, hashkeys, func, extind\n" +
|
||||
" , avgchn, IFNULL(degree, 1)\n" +
|
||||
" , IFNULL(instances, 1)\n" +
|
||||
" , IFNULL(flags, 0)\n" +
|
||||
" , IFNULL(spare1, 0)\n" +
|
||||
"FROM clu$\n" +
|
||||
"WHERE obj# ='633'";
|
||||
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
|
||||
SQLStatement stmt = stmtList.get(0);
|
||||
|
||||
assertEquals("SELECT ts#, file#, block#, cols\n" +
|
||||
"\t, IFNULL(size$, -1), pctfree$\n" +
|
||||
"\t, pctused$, initrans, maxtrans, hashkeys, func\n" +
|
||||
"\t, extind, avgchn, IFNULL(degree, 1)\n" +
|
||||
"\t, IFNULL(instances, 1)\n" +
|
||||
"\t, IFNULL(flags, 0)\n" +
|
||||
"\t, IFNULL(spare1, 0)\n" +
|
||||
"FROM clu$\n" +
|
||||
"WHERE obj# = '633'", SQLUtils.toPGString(stmt));
|
||||
|
||||
assertEquals("select ts#, file#, block#, cols\n" +
|
||||
"\t, IFNULL(size$, -1), pctfree$\n" +
|
||||
"\t, pctused$, initrans, maxtrans, hashkeys, func\n" +
|
||||
"\t, extind, avgchn, IFNULL(degree, 1)\n" +
|
||||
"\t, IFNULL(instances, 1)\n" +
|
||||
"\t, IFNULL(flags, 0)\n" +
|
||||
"\t, IFNULL(spare1, 0)\n" +
|
||||
"from clu$\n" +
|
||||
"where obj# = '633'", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION));
|
||||
|
||||
assertEquals(1, stmtList.size());
|
||||
|
||||
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
|
||||
stmt.accept(visitor);
|
||||
|
||||
// System.out.println("Tables : " + visitor.getTables());
|
||||
// System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
|
||||
assertEquals(18, visitor.getColumns().size());
|
||||
assertEquals(1, visitor.getTables().size());
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.alibaba.druid.bvt.sql.transform.datatype.oracle2pg;
|
||||
|
||||
import com.alibaba.druid.sql.SQLTransformUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.parser.SQLParserUtils;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class Oracle2MySql_method_sys_guid extends TestCase {
|
||||
public void test_oracle2pg_int_1() throws Exception {
|
||||
String sql = "sys_guid()";
|
||||
SQLMethodInvokeExpr expr = (SQLMethodInvokeExpr) SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).expr();
|
||||
SQLExpr targetExpr = SQLTransformUtils.transformOracleToPostgresql(expr);
|
||||
assertEquals("uuid_generate_v4()", targetExpr.toString());
|
||||
}
|
||||
}
|
||||
+8
@@ -98,4 +98,12 @@ public class Oracle2PG_DataTypeTest_chars extends TestCase {
|
||||
SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType);
|
||||
assertEquals("TEXT", pgDataType.toString());
|
||||
}
|
||||
|
||||
|
||||
public void test_oracle2pg_bfile() throws Exception {
|
||||
String sql = "bfile";
|
||||
SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType();
|
||||
SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType);
|
||||
assertEquals("VARCHAR(255)", pgDataType.toString());
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -48,5 +48,13 @@ public class Oracle2PG_DataTypeTest_double extends TestCase {
|
||||
SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType);
|
||||
assertEquals("DOUBLE PRECISION", pgDataType.toString());
|
||||
}
|
||||
|
||||
|
||||
public void test_oracle2pg_number_star() throws Exception {
|
||||
String sql = "number(*)";
|
||||
SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType();
|
||||
SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType);
|
||||
assertEquals("DOUBLE PRECISION", pgDataType.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -158,7 +158,7 @@ public class Oracle2PG_DataTypeTest_number_int extends TestCase {
|
||||
String sql = "number(*)";
|
||||
SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType();
|
||||
SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType);
|
||||
assertEquals("BIGINT", pgDataType.toString());
|
||||
assertEquals("DOUBLE PRECISION", pgDataType.toString());
|
||||
}
|
||||
|
||||
public void test_oracle2pg_int_21() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user