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:
@@ -21,16 +21,17 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class SQLParameter extends SQLObjectImpl implements SQLObjectWithDataType {
|
||||
|
||||
private SQLName name;
|
||||
private SQLDataType dataType;
|
||||
private SQLExpr defaultValue;
|
||||
private ParameterType paramType;
|
||||
private boolean noCopy = false;
|
||||
private boolean constant = false;
|
||||
|
||||
private SQLName cursorName;
|
||||
private SQLName name;
|
||||
private SQLDataType dataType;
|
||||
private SQLExpr defaultValue;
|
||||
private ParameterType paramType;
|
||||
private boolean noCopy = false;
|
||||
private boolean constant = false;
|
||||
private SQLName cursorName;
|
||||
private final List<SQLParameter> cursorParameters = new ArrayList<SQLParameter>();
|
||||
private boolean order;
|
||||
private boolean map;
|
||||
private boolean member;
|
||||
|
||||
public SQLExpr getDefaultValue() {
|
||||
return defaultValue;
|
||||
@@ -135,6 +136,8 @@ public final class SQLParameter extends SQLObjectImpl implements SQLObjectWithDa
|
||||
x.paramType = paramType;
|
||||
x.noCopy = noCopy;
|
||||
x.constant = constant;
|
||||
x.order = order;
|
||||
x.map = map;
|
||||
if (cursorName != null) {
|
||||
x.setCursorName(cursorName.clone());
|
||||
}
|
||||
@@ -145,4 +148,28 @@ public final class SQLParameter extends SQLObjectImpl implements SQLObjectWithDa
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public boolean isOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(boolean order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public boolean isMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(boolean map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public boolean isMember() {
|
||||
return member;
|
||||
}
|
||||
|
||||
public void setMember(boolean member) {
|
||||
this.member = member;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SQLDropSynonymStatement extends SQLStatementImpl implements SQLDropStatement {
|
||||
|
||||
private SQLName name;
|
||||
private boolean ifExists;
|
||||
private boolean isPublic;
|
||||
private boolean force;
|
||||
|
||||
public SQLDropSynonymStatement() {
|
||||
|
||||
}
|
||||
|
||||
public SQLDropSynonymStatement(String dbType) {
|
||||
super (dbType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, name);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SQLObject> getChildren() {
|
||||
List<SQLObject> children = new ArrayList<SQLObject>();
|
||||
if (name != null) {
|
||||
children.add(name);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
public SQLName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(SQLName name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isIfExists() {
|
||||
return ifExists;
|
||||
}
|
||||
|
||||
public void setIfExists(boolean ifExists) {
|
||||
this.ifExists = ifExists;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
SQLName name = getName();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name instanceof SQLPropertyExpr) {
|
||||
return ((SQLPropertyExpr) name).getOwnernName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
public void setPublic(boolean aPublic) {
|
||||
isPublic = aPublic;
|
||||
}
|
||||
|
||||
public boolean isForce() {
|
||||
return force;
|
||||
}
|
||||
|
||||
public void setForce(boolean force) {
|
||||
this.force = force;
|
||||
}
|
||||
}
|
||||
+115
-9
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLParameter;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateStatement;
|
||||
@@ -26,20 +28,37 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OracleCreateTypeStatement extends OracleStatementImpl implements SQLCreateStatement {
|
||||
private boolean orReplace;
|
||||
private SQLName name;
|
||||
private boolean force;
|
||||
private SQLName oid;
|
||||
private boolean body;
|
||||
private boolean orReplace;
|
||||
private SQLName name;
|
||||
private SQLName authId;
|
||||
private boolean force;
|
||||
private SQLName oid;
|
||||
private boolean body;
|
||||
private boolean object;
|
||||
private boolean paren;
|
||||
private Boolean isFinal;
|
||||
private Boolean instantiable;
|
||||
|
||||
private SQLName under;
|
||||
|
||||
private List<SQLParameter> parameters = new ArrayList<SQLParameter>();
|
||||
|
||||
private SQLDataType tableOf;
|
||||
|
||||
private SQLExpr varraySizeLimit;
|
||||
private SQLDataType varrayDataType;
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, name);
|
||||
acceptChild(visitor, authId);
|
||||
acceptChild(visitor, oid);
|
||||
acceptChild(visitor, under);
|
||||
acceptChild(visitor, parameters);
|
||||
acceptChild(visitor, tableOf);
|
||||
acceptChild(visitor, varraySizeLimit);
|
||||
acceptChild(visitor, varrayDataType);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
@@ -75,11 +94,22 @@ public class OracleCreateTypeStatement extends OracleStatementImpl implements SQ
|
||||
return oid;
|
||||
}
|
||||
|
||||
public void setOid(SQLName oid) {
|
||||
if (oid != null) {
|
||||
oid.setParent(this);
|
||||
public void setOid(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.oid = oid;
|
||||
this.oid = x;
|
||||
}
|
||||
|
||||
public SQLName getAuthId() {
|
||||
return authId;
|
||||
}
|
||||
|
||||
public void setAuthId(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.authId = x;
|
||||
}
|
||||
|
||||
public List<SQLParameter> getParameters() {
|
||||
@@ -93,4 +123,80 @@ public class OracleCreateTypeStatement extends OracleStatementImpl implements SQ
|
||||
public void setBody(boolean body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Boolean getFinal() {
|
||||
return isFinal;
|
||||
}
|
||||
|
||||
public void setFinal(boolean aFinal) {
|
||||
isFinal = aFinal;
|
||||
}
|
||||
|
||||
public Boolean getInstantiable() {
|
||||
return instantiable;
|
||||
}
|
||||
|
||||
public void setInstantiable(boolean instantiable) {
|
||||
this.instantiable = instantiable;
|
||||
}
|
||||
|
||||
public SQLDataType getTableOf() {
|
||||
return tableOf;
|
||||
}
|
||||
|
||||
public void setTableOf(SQLDataType x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.tableOf = x;
|
||||
}
|
||||
|
||||
public SQLExpr getVarraySizeLimit() {
|
||||
return varraySizeLimit;
|
||||
}
|
||||
|
||||
public void setVarraySizeLimit(SQLExpr x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.varraySizeLimit = x;
|
||||
}
|
||||
|
||||
public SQLDataType getVarrayDataType() {
|
||||
return varrayDataType;
|
||||
}
|
||||
|
||||
public void setVarrayDataType(SQLDataType x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.varrayDataType = x;
|
||||
}
|
||||
|
||||
public SQLName getUnder() {
|
||||
return under;
|
||||
}
|
||||
|
||||
public void setUnder(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.under = x;
|
||||
}
|
||||
|
||||
public boolean isObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObject(boolean object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public boolean isParen() {
|
||||
return paren;
|
||||
}
|
||||
|
||||
public void setParen(boolean paren) {
|
||||
this.paren = paren;
|
||||
}
|
||||
}
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLParameter;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OracleProcedureDataType extends SQLDataTypeImpl {
|
||||
private boolean isStatic = false;
|
||||
private final List<SQLParameter> parameters = new ArrayList<SQLParameter>();
|
||||
|
||||
private SQLStatement block;
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public void setStatic(boolean aStatic) {
|
||||
isStatic = aStatic;
|
||||
}
|
||||
|
||||
public List<SQLParameter> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public OracleProcedureDataType clone() {
|
||||
OracleProcedureDataType x = new OracleProcedureDataType();
|
||||
cloneTo(x);
|
||||
|
||||
x.isStatic = isStatic;
|
||||
for (SQLParameter parameter : parameters) {
|
||||
SQLParameter p2 = parameter.clone();
|
||||
p2.setParent(x);
|
||||
x.parameters.add(p2);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
public SQLStatement getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
public void setBlock(SQLStatement block) {
|
||||
if (block != null) {
|
||||
block.setParent(this);
|
||||
}
|
||||
this.block = block;
|
||||
}
|
||||
}
|
||||
+133
-4
@@ -512,6 +512,7 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.DROP) {
|
||||
Lexer.SavePoint savePoint = lexer.mark();
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.TABLE) {
|
||||
@@ -587,6 +588,15 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.SYNONYM)) {
|
||||
lexer.reset(savePoint);
|
||||
|
||||
SQLStatement stmt = parseDropSynonym();
|
||||
stmt.setParent(parent);
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new ParserException("TODO : " + lexer.info());
|
||||
}
|
||||
|
||||
@@ -679,6 +689,30 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
}
|
||||
}
|
||||
|
||||
public SQLStatement parseDropSynonym() {
|
||||
if (lexer.token() == Token.DROP) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
SQLDropSynonymStatement stmt = new SQLDropSynonymStatement();
|
||||
stmt.setDbType(dbType);
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.PUBLIC)) {
|
||||
lexer.nextToken();
|
||||
stmt.setPublic(true);
|
||||
}
|
||||
|
||||
acceptIdentifier("SYNONYM");
|
||||
|
||||
stmt.setName(this.exprParser.name());
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FORCE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setForce(true);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public SQLStatement parsePipeRow() {
|
||||
OraclePipeRowStatement stmt = new OraclePipeRowStatement();
|
||||
acceptIdentifier("PIPE");
|
||||
@@ -862,10 +896,10 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
stmt.setDeterministic(true);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("AUTHID")) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.AUTHID)) {
|
||||
lexer.nextToken();
|
||||
String strVal = lexer.stringVal();
|
||||
if (lexer.identifierEquals("CURRENT_USER")) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.CURRENT_USER)) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
acceptIdentifier("DEFINER");
|
||||
@@ -1753,6 +1787,18 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
SQLParameter parameter = new SQLParameter();
|
||||
parameter.setParent(parent);
|
||||
|
||||
if (parent instanceof OracleCreateTypeStatement) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.MAP)) {
|
||||
lexer.nextToken();
|
||||
parameter.setMap(true);
|
||||
} else if (lexer.token() == Token.ORDER) {
|
||||
lexer.nextToken();
|
||||
parameter.setOrder(true);
|
||||
}
|
||||
|
||||
// acceptIdentifier("MEMBER");
|
||||
}
|
||||
|
||||
SQLName name;
|
||||
SQLDataType dataType = null;
|
||||
if (lexer.token() == Token.CURSOR) {
|
||||
@@ -1777,7 +1823,7 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
|| lexer.token() == Token.END
|
||||
|| lexer.token() == Token.TABLE) {
|
||||
break;
|
||||
} else if (lexer.identifierEquals("TYPE")) {
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.TYPE)) {
|
||||
lexer.nextToken();
|
||||
name = this.exprParser.name();
|
||||
accept(Token.IS);
|
||||
@@ -1832,7 +1878,12 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
throw new ParserException("TODO : " + lexer.info());
|
||||
}
|
||||
} else {
|
||||
name = this.exprParser.name();
|
||||
if (lexer.token() == Token.KEY) {
|
||||
name = new SQLIdentifierExpr(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
name = this.exprParser.name();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.IN) {
|
||||
lexer.nextToken();
|
||||
@@ -1870,6 +1921,9 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
if ((name.nameHashCode64() == FnvHash.Constants.MEMBER
|
||||
|| name.nameHashCode64() == FnvHash.Constants.STATIC)
|
||||
&& lexer.token() == Token.FUNCTION) {
|
||||
if (name.nameHashCode64() == FnvHash.Constants.MEMBER) {
|
||||
parameter.setMember(true);
|
||||
}
|
||||
OracleFunctionDataType functionDataType = new OracleFunctionDataType();
|
||||
functionDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC);
|
||||
lexer.nextToken();
|
||||
@@ -1890,6 +1944,31 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
SQLStatement block = this.parseBlock();
|
||||
functionDataType.setBlock(block);
|
||||
}
|
||||
} else if ((name.nameHashCode64() == FnvHash.Constants.MEMBER
|
||||
|| name.nameHashCode64() == FnvHash.Constants.STATIC)
|
||||
&& lexer.token() == Token.PROCEDURE) {
|
||||
if (name.nameHashCode64() == FnvHash.Constants.MEMBER) {
|
||||
parameter.setMember(true);
|
||||
}
|
||||
OracleProcedureDataType procedureDataType = new OracleProcedureDataType();
|
||||
procedureDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC);
|
||||
lexer.nextToken();
|
||||
procedureDataType.setName(lexer.stringVal());
|
||||
accept(Token.IDENTIFIER);
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
this.parserParameters(procedureDataType.getParameters(), procedureDataType);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
dataType = procedureDataType;
|
||||
name = null;
|
||||
|
||||
if (lexer.token() == Token.IS) {
|
||||
lexer.nextToken();
|
||||
SQLStatement block = this.parseBlock();
|
||||
procedureDataType.setBlock(block);
|
||||
}
|
||||
} else {
|
||||
dataType = this.exprParser.parseDataType(false);
|
||||
}
|
||||
@@ -2661,20 +2740,49 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
SQLName name = this.exprParser.name();
|
||||
stmt.setName(name);
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.UNDER)) {
|
||||
lexer.nextToken();
|
||||
SQLName under = this.exprParser.name();
|
||||
stmt.setUnder(under);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.AUTHID)) {
|
||||
lexer.nextToken();
|
||||
SQLName authId = this.exprParser.name();
|
||||
stmt.setAuthId(authId);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.AS || lexer.token() == Token.IS) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("OBJECT")) {
|
||||
lexer.nextToken();
|
||||
stmt.setObject(true);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.STATIC)) {
|
||||
this.parserParameters(stmt.getParameters(), stmt);
|
||||
} else if (lexer.token() == Token.TABLE) {
|
||||
lexer.nextToken();
|
||||
accept(Token.OF);
|
||||
SQLDataType dataType = this.exprParser.parseDataType();
|
||||
stmt.setTableOf(dataType);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.VARRAY)) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
SQLExpr sizeLimit = this.exprParser.primary();
|
||||
stmt.setVarraySizeLimit(sizeLimit);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
accept(Token.OF);
|
||||
SQLDataType dataType = this.exprParser.parseDataType();
|
||||
stmt.setVarrayDataType(dataType);
|
||||
} else {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
this.parserParameters(stmt.getParameters(), stmt);
|
||||
stmt.setParen(true);
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
this.parserParameters(stmt.getParameters(), stmt);
|
||||
@@ -2684,6 +2792,27 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (lexer.token() == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
if (lexer.identifierEquals(FnvHash.Constants.FINAL)) {
|
||||
lexer.nextToken();
|
||||
stmt.setFinal(false);
|
||||
} else {
|
||||
acceptIdentifier("INSTANTIABLE");
|
||||
stmt.setInstantiable(false);
|
||||
}
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.FINAL)) {
|
||||
lexer.nextToken();
|
||||
stmt.setFinal(true);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.INSTANTIABLE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setInstantiable(true);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.SEMI) {
|
||||
lexer.nextToken();
|
||||
stmt.setAfterSemi(true);
|
||||
|
||||
+93
-8
@@ -55,6 +55,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement.
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot.Item;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.CheckOption;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction.ReadOnly;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
@@ -1302,7 +1304,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
}
|
||||
}
|
||||
if (!(x.getParent() instanceof SQLCreateProcedureStatement
|
||||
|| x.getParent() instanceof SQLCreateFunctionStatement)
|
||||
|| x.getParent() instanceof SQLCreateFunctionStatement
|
||||
|| x.getParent() instanceof OracleFunctionDataType
|
||||
|| x.getParent() instanceof OracleProcedureDataType)
|
||||
) {
|
||||
print0(ucase ? "DECLARE" : "declare");
|
||||
println();
|
||||
@@ -3311,20 +3315,101 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
print0(ucase ? "CREATE TYPE " : "create type ");
|
||||
}
|
||||
|
||||
if (x.isBody()) {
|
||||
print0(ucase ? "BODY " : "body ");
|
||||
}
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
SQLName under = x.getUnder();
|
||||
if (under != null) {
|
||||
print0(ucase ? " UNDER " : " under ");
|
||||
under.accept(this);
|
||||
}
|
||||
|
||||
SQLName authId = x.getAuthId();
|
||||
if (authId != null) {
|
||||
print0(ucase ? " AUTHID " : " authid ");
|
||||
authId.accept(this);
|
||||
}
|
||||
|
||||
if (x.isForce()) {
|
||||
print0(ucase ? "FORCE " : "force ");
|
||||
}
|
||||
|
||||
print0(" AS OBJECT (");
|
||||
indentCount++;
|
||||
println();
|
||||
printlnAndAccept(x.getParameters(), ", ");
|
||||
List<SQLParameter> parameters = x.getParameters();
|
||||
SQLDataType tableOf = x.getTableOf();
|
||||
|
||||
if (x.isObject()) {
|
||||
print0(" AS OBJECT");
|
||||
}
|
||||
|
||||
if (parameters.size() > 0) {
|
||||
if (x.isParen()) {
|
||||
print(" (");
|
||||
} else {
|
||||
print0(ucase ? " IS" : " is");
|
||||
}
|
||||
indentCount++;
|
||||
println();
|
||||
|
||||
for (int i = 0; i < parameters.size(); ++i) {
|
||||
SQLParameter param = parameters.get(i);
|
||||
param.accept(this);
|
||||
|
||||
SQLDataType dataType = param.getDataType();
|
||||
|
||||
if (i < parameters.size() - 1) {
|
||||
if (dataType instanceof OracleFunctionDataType
|
||||
&& ((OracleFunctionDataType) dataType).getBlock() != null) {
|
||||
// skip
|
||||
println();
|
||||
} else if (dataType instanceof OracleProcedureDataType
|
||||
&& ((OracleProcedureDataType) dataType).getBlock() != null) {
|
||||
// skip
|
||||
println();
|
||||
} else {
|
||||
println(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
indentCount--;
|
||||
println();
|
||||
|
||||
if (x.isParen()) {
|
||||
print0(")");
|
||||
} else {
|
||||
print0("END");
|
||||
}
|
||||
} else if (tableOf != null) {
|
||||
print0(ucase ? " AS TABLE OF " : " as table of ");
|
||||
tableOf.accept(this);
|
||||
} else if (x.getVarraySizeLimit() != null) {
|
||||
print0(ucase ? " VARRAY (" : " varray (");
|
||||
x.getVarraySizeLimit().accept(this);
|
||||
print0(ucase ? ") OF " : ") of ");
|
||||
x.getVarrayDataType().accept(this);
|
||||
}
|
||||
|
||||
Boolean isFinal = x.getFinal();
|
||||
if (isFinal != null) {
|
||||
if (isFinal.booleanValue()) {
|
||||
print0(ucase ? " FINAL" : " final");
|
||||
} else {
|
||||
print0(ucase ? " NOT FINAL" : " not final");
|
||||
}
|
||||
}
|
||||
|
||||
Boolean instantiable = x.getInstantiable();
|
||||
if (instantiable != null) {
|
||||
if (instantiable.booleanValue()) {
|
||||
print0(ucase ? " INSTANTIABLE" : " instantiable");
|
||||
} else {
|
||||
print0(ucase ? " NOT INSTANTIABLE" : " not instantiable");
|
||||
}
|
||||
}
|
||||
|
||||
indentCount--;
|
||||
println();
|
||||
print0(")");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+90
-7
@@ -23,6 +23,8 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGCidrExpr;
|
||||
@@ -2000,20 +2002,101 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
print0(ucase ? "CREATE TYPE " : "create type ");
|
||||
}
|
||||
|
||||
if (x.isBody()) {
|
||||
print0(ucase ? "BODY " : "body ");
|
||||
}
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
SQLName under = x.getUnder();
|
||||
if (under != null) {
|
||||
print0(ucase ? " UNDER " : " under ");
|
||||
under.accept(this);
|
||||
}
|
||||
|
||||
SQLName authId = x.getAuthId();
|
||||
if (authId != null) {
|
||||
print0(ucase ? " AUTHID " : " authid ");
|
||||
authId.accept(this);
|
||||
}
|
||||
|
||||
if (x.isForce()) {
|
||||
print0(ucase ? "FORCE " : "force ");
|
||||
}
|
||||
|
||||
print0(" AS OBJECT (");
|
||||
indentCount++;
|
||||
println();
|
||||
printlnAndAccept(x.getParameters(), ", ");
|
||||
List<SQLParameter> parameters = x.getParameters();
|
||||
SQLDataType tableOf = x.getTableOf();
|
||||
|
||||
if (x.isObject()) {
|
||||
print0(" AS OBJECT");
|
||||
}
|
||||
|
||||
if (parameters.size() > 0) {
|
||||
if (x.isParen()) {
|
||||
print(" (");
|
||||
} else {
|
||||
print0(ucase ? " IS" : " is");
|
||||
}
|
||||
indentCount++;
|
||||
println();
|
||||
|
||||
for (int i = 0; i < parameters.size(); ++i) {
|
||||
SQLParameter param = parameters.get(i);
|
||||
param.accept(this);
|
||||
|
||||
SQLDataType dataType = param.getDataType();
|
||||
|
||||
if (i < parameters.size() - 1) {
|
||||
if (dataType instanceof OracleFunctionDataType
|
||||
&& ((OracleFunctionDataType) dataType).getBlock() != null) {
|
||||
// skip
|
||||
println();
|
||||
} else if (dataType instanceof OracleProcedureDataType
|
||||
&& ((OracleProcedureDataType) dataType).getBlock() != null) {
|
||||
// skip
|
||||
println();
|
||||
} else {
|
||||
println(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
indentCount--;
|
||||
println();
|
||||
|
||||
if (x.isParen()) {
|
||||
print0(")");
|
||||
} else {
|
||||
print0("END");
|
||||
}
|
||||
} else if (tableOf != null) {
|
||||
print0(ucase ? " AS TABLE OF " : " as table of ");
|
||||
tableOf.accept(this);
|
||||
} else if (x.getVarraySizeLimit() != null) {
|
||||
print0(ucase ? " VARRAY (" : " varray (");
|
||||
x.getVarraySizeLimit().accept(this);
|
||||
print0(ucase ? ") OF " : ") of ");
|
||||
x.getVarrayDataType().accept(this);
|
||||
}
|
||||
|
||||
Boolean isFinal = x.getFinal();
|
||||
if (isFinal != null) {
|
||||
if (isFinal.booleanValue()) {
|
||||
print0(ucase ? " FINAL" : " final");
|
||||
} else {
|
||||
print0(ucase ? " NOT FINAL" : " not final");
|
||||
}
|
||||
}
|
||||
|
||||
Boolean instantiable = x.getInstantiable();
|
||||
if (instantiable != null) {
|
||||
if (instantiable.booleanValue()) {
|
||||
print0(ucase ? " INSTANTIABLE" : " instantiable");
|
||||
} else {
|
||||
print0(ucase ? " NOT INSTANTIABLE" : " not instantiable");
|
||||
}
|
||||
}
|
||||
|
||||
indentCount--;
|
||||
println();
|
||||
print0(")");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,13 +193,13 @@ public class Keywords {
|
||||
}
|
||||
}
|
||||
|
||||
public Token getKeyword(long hash) {
|
||||
int index = Arrays.binarySearch(hashArray, hash);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
return tokens[index];
|
||||
public Token getKeyword(long hash) {
|
||||
int index = Arrays.binarySearch(hashArray, hash);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
return tokens[index];
|
||||
}
|
||||
|
||||
public Token getKeyword(String key) {
|
||||
long k = Utils.fnv_64_lower(key);
|
||||
|
||||
@@ -2031,6 +2031,11 @@ public class SQLStatementParser extends SQLParser {
|
||||
return parseCreateSynonym();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.SYNONYM)) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateSynonym();
|
||||
}
|
||||
|
||||
// lexer.reset(mark_bp, mark_ch, Token.CREATE);
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
} else if (token == Token.DATABASE) {
|
||||
@@ -2469,14 +2474,14 @@ public class SQLStatementParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("DEFINER")) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.DEFINER)) {
|
||||
lexer.nextToken();
|
||||
accept(Token.EQ);
|
||||
SQLName definer = (SQLName) ((MySqlExprParser) this.exprParser).userName();
|
||||
createView.setDefiner(definer);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("SQL")) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.SQL)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("SECURITY");
|
||||
String sqlSecurity = lexer.stringVal();
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatemen
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import oracle.sql.SQLUtil;
|
||||
@@ -3057,6 +3058,27 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDropSynonymStatement x) {
|
||||
if (x.isPublic()) {
|
||||
print0(ucase ? "DROP PUBLIC SYNONYM " : "drop public synonym ");
|
||||
} else {
|
||||
print0(ucase ? "DROP SYNONYM " : "drop synonym ");
|
||||
}
|
||||
|
||||
if (x.isIfExists()) {
|
||||
print0(ucase ? "IF EXISTS " : "if exists ");
|
||||
}
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
if (x.isForce()) {
|
||||
print0(ucase ? " FORCE" : " force");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSavePointStatement x) {
|
||||
print0(ucase ? "SAVEPOINT" : "savepoint");
|
||||
@@ -4445,6 +4467,35 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
SQLStatement block = x.getBlock();
|
||||
if (block != null) {
|
||||
println();
|
||||
print0(ucase ? "IS" : "is");
|
||||
println();
|
||||
block.accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleProcedureDataType x) {
|
||||
if (x.isStatic()) {
|
||||
print0(ucase ? "STATIC " : "static ");
|
||||
}
|
||||
|
||||
print0(ucase ? "PROCEDURE " : "procedure ");
|
||||
|
||||
print0(x.getName());
|
||||
|
||||
if (x.getParameters().size() > 0) {
|
||||
print(" (");
|
||||
printAndAccept(x.getParameters(), ", ");
|
||||
print(")");
|
||||
}
|
||||
|
||||
SQLStatement block = x.getBlock();
|
||||
if (block != null) {
|
||||
println();
|
||||
print0(ucase ? "IS" : "is");
|
||||
println();
|
||||
block.accept(this);
|
||||
}
|
||||
|
||||
@@ -4465,14 +4516,30 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
this.indentCount--;
|
||||
|
||||
} else {
|
||||
if (x.isMap()) {
|
||||
print0(ucase ? "MAP MEMBER " : "map member ");
|
||||
} else if (x.isOrder()) {
|
||||
print0(ucase ? "ORDER MEMBER " : "order member ");
|
||||
} else if (x.isMember()) {
|
||||
print0(ucase ? "MEMBER " : "member ");
|
||||
}
|
||||
SQLDataType dataType = x.getDataType();
|
||||
|
||||
if (JdbcConstants.ORACLE.equals(dbType)) {
|
||||
if (JdbcConstants.ORACLE.equals(dbType)
|
||||
|| dataType instanceof OracleFunctionDataType
|
||||
|| dataType instanceof OracleProcedureDataType) {
|
||||
if (dataType instanceof OracleFunctionDataType) {
|
||||
OracleFunctionDataType functionDataType = (OracleFunctionDataType) dataType;
|
||||
visit(functionDataType);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dataType instanceof OracleProcedureDataType) {
|
||||
OracleProcedureDataType procedureDataType = (OracleProcedureDataType) dataType;
|
||||
visit(procedureDataType);
|
||||
return false;
|
||||
}
|
||||
|
||||
String dataTypeName = dataType.getName();
|
||||
boolean printType = (dataTypeName.startsWith("TABLE OF") && x.getDefaultValue() == null)
|
||||
|| dataTypeName.equalsIgnoreCase("REF CURSOR")
|
||||
|
||||
@@ -790,4 +790,7 @@ public interface SQLASTVisitor {
|
||||
|
||||
boolean visit(SQLDropServerStatement x);
|
||||
void endVisit(SQLDropServerStatement x);
|
||||
|
||||
boolean visit(SQLDropSynonymStatement x);
|
||||
void endVisit(SQLDropSynonymStatement x);
|
||||
}
|
||||
|
||||
@@ -1836,6 +1836,16 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDropSynonymStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLDropSynonymStatement x) {
|
||||
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
}
|
||||
|
||||
@@ -2391,6 +2391,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
public boolean visit(SQLAlterFunctionStatement x) {
|
||||
return false;
|
||||
}
|
||||
public boolean visit(SQLDropSynonymStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLAlterTypeStatement x) {
|
||||
return false;
|
||||
|
||||
@@ -514,16 +514,23 @@ public final class FnvHash {
|
||||
long OWNER = fnv1a_64_lower("OWNER");
|
||||
long PORT = fnv1a_64_lower("PORT");
|
||||
long PUBLIC = fnv1a_64_lower("PUBLIC");
|
||||
long SYNONYM = fnv1a_64_lower("SYNONYM");
|
||||
long MATERIALIZED = fnv1a_64_lower("MATERIALIZED");
|
||||
long BITMAP = fnv1a_64_lower("BITMAP");
|
||||
long PACKAGE = fnv1a_64_lower("PACKAGE");
|
||||
long TRUNC = fnv1a_64_lower("TRUNC");
|
||||
long SYSTIMESTAMP = fnv1a_64_lower("SYSTIMESTAMP");
|
||||
long TYPE = fnv1a_64_lower("TYPE");
|
||||
long MAP = fnv1a_64_lower("MAP");
|
||||
long ONLY = fnv1a_64_lower("ONLY");
|
||||
long MEMBER = fnv1a_64_lower("MEMBER");
|
||||
long STATIC = fnv1a_64_lower("STATIC");
|
||||
long FINAL = fnv1a_64_lower("FINAL");
|
||||
long INSTANTIABLE = fnv1a_64_lower("INSTANTIABLE");
|
||||
long UNSUPPORTED = fnv1a_64_lower("UNSUPPORTED");
|
||||
long VARRAY = fnv1a_64_lower("VARRAY");
|
||||
long AUTHID = fnv1a_64_lower("AUTHID");
|
||||
long UNDER = fnv1a_64_lower("UNDER");
|
||||
long USERENV = fnv1a_64_lower("USERENV");
|
||||
long NUMTODSINTERVAL = fnv1a_64_lower("NUMTODSINTERVAL");
|
||||
|
||||
|
||||
@@ -237,59 +237,59 @@ public class Utils {
|
||||
*
|
||||
* @author Viliam Holub
|
||||
*/
|
||||
public static long murmurhash2_64(final byte[] data, int length, int seed) {
|
||||
final long m = 0xc6a4a7935bd1e995L;
|
||||
final int r = 47;
|
||||
public static long murmurhash2_64(final byte[] data, int length, int seed) {
|
||||
final long m = 0xc6a4a7935bd1e995L;
|
||||
final int r = 47;
|
||||
|
||||
long h = (seed & 0xffffffffl) ^ (length * m);
|
||||
long h = (seed & 0xffffffffl) ^ (length * m);
|
||||
|
||||
int length8 = length / 8;
|
||||
int length8 = length / 8;
|
||||
|
||||
for (int i = 0; i < length8; i++) {
|
||||
final int i8 = i * 8;
|
||||
long k = ((long) data[i8 + 0] & 0xff) //
|
||||
+ (((long) data[i8 + 1] & 0xff) << 8) //
|
||||
+ (((long) data[i8 + 2] & 0xff) << 16)//
|
||||
+ (((long) data[i8 + 3] & 0xff) << 24) //
|
||||
+ (((long) data[i8 + 4] & 0xff) << 32)//
|
||||
+ (((long) data[i8 + 5] & 0xff) << 40)//
|
||||
+ (((long) data[i8 + 6] & 0xff) << 48) //
|
||||
+ (((long) data[i8 + 7] & 0xff) << 56);
|
||||
for (int i = 0; i < length8; i++) {
|
||||
final int i8 = i * 8;
|
||||
long k = ((long) data[i8 + 0] & 0xff) //
|
||||
+ (((long) data[i8 + 1] & 0xff) << 8) //
|
||||
+ (((long) data[i8 + 2] & 0xff) << 16)//
|
||||
+ (((long) data[i8 + 3] & 0xff) << 24) //
|
||||
+ (((long) data[i8 + 4] & 0xff) << 32)//
|
||||
+ (((long) data[i8 + 5] & 0xff) << 40)//
|
||||
+ (((long) data[i8 + 6] & 0xff) << 48) //
|
||||
+ (((long) data[i8 + 7] & 0xff) << 56);
|
||||
|
||||
k *= m;
|
||||
k ^= k >>> r;
|
||||
k *= m;
|
||||
k *= m;
|
||||
k ^= k >>> r;
|
||||
k *= m;
|
||||
|
||||
h ^= k;
|
||||
h *= m;
|
||||
}
|
||||
|
||||
switch (length % 8) {
|
||||
case 7:
|
||||
h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48;
|
||||
case 6:
|
||||
h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40;
|
||||
case 5:
|
||||
h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32;
|
||||
case 4:
|
||||
h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24;
|
||||
case 3:
|
||||
h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16;
|
||||
case 2:
|
||||
h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8;
|
||||
case 1:
|
||||
h ^= (long) (data[length & ~7] & 0xff);
|
||||
h *= m;
|
||||
}
|
||||
;
|
||||
|
||||
h ^= h >>> r;
|
||||
h ^= k;
|
||||
h *= m;
|
||||
h ^= h >>> r;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
switch (length % 8) {
|
||||
case 7:
|
||||
h ^= (long) (data[(length & ~7) + 6] & 0xff) << 48;
|
||||
case 6:
|
||||
h ^= (long) (data[(length & ~7) + 5] & 0xff) << 40;
|
||||
case 5:
|
||||
h ^= (long) (data[(length & ~7) + 4] & 0xff) << 32;
|
||||
case 4:
|
||||
h ^= (long) (data[(length & ~7) + 3] & 0xff) << 24;
|
||||
case 3:
|
||||
h ^= (long) (data[(length & ~7) + 2] & 0xff) << 16;
|
||||
case 2:
|
||||
h ^= (long) (data[(length & ~7) + 1] & 0xff) << 8;
|
||||
case 1:
|
||||
h ^= (long) (data[length & ~7] & 0xff);
|
||||
h *= m;
|
||||
}
|
||||
;
|
||||
|
||||
h ^= h >>> r;
|
||||
h *= m;
|
||||
h ^= h >>> r;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
public static byte[] md5Bytes(String text) {
|
||||
MessageDigest msgDigest = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user