improved oracle sql parser.

This commit is contained in:
wenshao
2017-09-21 22:05:27 +08:00
parent f006fbecb8
commit 7268c17624
33 changed files with 1273 additions and 21 deletions
@@ -588,6 +588,10 @@ public class SQLTransformUtils {
dataType = new SQLDataTypeImpl(SQLDataType.Constants.TIMESTAMP, 0);
} else if (nameHash == FnvHash.Constants.TIMESTAMP) {
x.setName(SQLDataType.Constants.TIMESTAMP);
if (x.isWithLocalTimeZone()) {
x.setWithLocalTimeZone(false);
x.setWithTimeZone(null);
}
dataType = x;
} else if (nameHash == FnvHash.Constants.DATETIME) {
int len = -1;
@@ -669,6 +673,13 @@ public class SQLTransformUtils {
}
}
if (nameHashCode64 == FnvHash.Constants.SYSTIMESTAMP) {
SQLMethodInvokeExpr xx = x.clone();
xx.setMethodName("CURRENT_TIMESTAMP");
xx.setParent(x.getParent());
return xx;
}
return x;
}
@@ -31,6 +31,7 @@ public interface SQLDataType extends SQLObject {
void setWithTimeZone(Boolean value);
boolean isWithLocalTimeZone();
void setWithLocalTimeZone(boolean value);
SQLDataType clone();
@@ -110,7 +110,10 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr implements SQLValuableE
}
public SQLNumberExpr clone() {
return new SQLNumberExpr(number);
SQLNumberExpr x = new SQLNumberExpr();
x.chars = chars;
x.number = number;
return x;
}
public SQLDataType computeDataType() {
@@ -0,0 +1,62 @@
/*
* 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.SQLStatementImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAlterFunctionStatement extends SQLStatementImpl {
private SQLName name;
private boolean debug;
private boolean reuseSettings;
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
if (name != null) {
name.setParent(this);
}
this.name = name;
}
public boolean isReuseSettings() {
return reuseSettings;
}
public void setReuseSettings(boolean x) {
this.reuseSettings = x;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,79 @@
/*
* 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.SQLStatementImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAlterTypeStatement extends SQLStatementImpl {
private SQLName name;
private boolean compile;
private boolean debug;
private boolean body;
private boolean reuseSettings;
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
if (name != null) {
name.setParent(this);
}
this.name = name;
}
public boolean isCompile() {
return compile;
}
public void setCompile(boolean compile) {
this.compile = compile;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public boolean isBody() {
return body;
}
public void setBody(boolean body) {
this.body = body;
}
public boolean isReuseSettings() {
return reuseSettings;
}
public void setReuseSettings(boolean reuseSettings) {
this.reuseSettings = reuseSettings;
}
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
}
visitor.endVisit(this);
}
}
@@ -46,6 +46,9 @@ public class SQLCreateFunctionStatement extends SQLStatementImpl implements SQLC
private String comment;
private boolean deterministic = false;
private boolean parallelEnable;
private boolean aggregate;
private SQLName using;
public SQLCreateFunctionStatement clone() {
SQLCreateFunctionStatement x = new SQLCreateFunctionStatement();
@@ -210,4 +213,29 @@ public class SQLCreateFunctionStatement extends SQLStatementImpl implements SQLC
public void setDataType(SQLDataType dataType) {
this.setReturnDataType(dataType);
}
public boolean isParallelEnable() {
return parallelEnable;
}
public void setParallelEnable(boolean parallel_enable) {
this.parallelEnable = parallel_enable;
}
public boolean isAggregate() {
return aggregate;
}
public void setAggregate(boolean aggregate) {
this.aggregate = aggregate;
}
public SQLName getUsing() {
return using;
}
public void setUsing(SQLName using) {
this.using = using;
}
}
@@ -47,6 +47,8 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
protected SQLExprTableSource like;
public SQLCreateTableStatement(){
}
@@ -928,4 +930,5 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
public String toString() {
return SQLUtils.toSQLString(this, dbType);
}
}
@@ -1005,4 +1005,14 @@ public class OracleToMySqlOutputVisitor extends MySqlOutputVisitor implements Or
public void endVisit(OracleCreateSynonymStatement x) {
}
@Override
public boolean visit(OracleCreateTypeStatement x) {
return false;
}
@Override
public void endVisit(OracleCreateTypeStatement x) {
}
}
@@ -0,0 +1,96 @@
/*
* 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;
import com.alibaba.druid.sql.ast.SQLParameter;
import com.alibaba.druid.sql.ast.statement.SQLCreateStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
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 List<SQLParameter> parameters = new ArrayList<SQLParameter>();
@Override
public void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, name);
acceptChild(visitor, oid);
acceptChild(visitor, parameters);
}
visitor.endVisit(this);
}
public SQLName getName() {
return name;
}
public void setName(SQLName name) {
if (name != null) {
name.setParent(this);
}
this.name = name;
}
public boolean isOrReplace() {
return orReplace;
}
public void setOrReplace(boolean orReplace) {
this.orReplace = orReplace;
}
public boolean isForce() {
return force;
}
public void setForce(boolean force) {
this.force = force;
}
public SQLName getOid() {
return oid;
}
public void setOid(SQLName oid) {
if (oid != null) {
oid.setParent(this);
}
this.oid = oid;
}
public List<SQLParameter> getParameters() {
return parameters;
}
public boolean isBody() {
return body;
}
public void setBody(boolean body) {
this.body = body;
}
}
@@ -994,6 +994,12 @@ public class OracleExprParser extends SQLExprParser {
dbLink.setDbLink(link);
return dbLink;
}
//
// if (name.nameHashCode64() == FnvHash.Constants.UNSUPPORTED
// && lexer.identifierEquals(FnvHash.Constants.TYPE)) {
// name = new SQLIdentifierExpr(name.getSimpleName() + " " + lexer.stringVal());
// lexer.nextToken();
// }
return name;
}
@@ -0,0 +1,87 @@
/*
* 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 com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;
public class OracleFunctionDataType extends SQLDataTypeImpl {
private boolean isStatic = false;
private final List<SQLParameter> parameters = new ArrayList<SQLParameter>();
private SQLDataType returnDataType;
private SQLStatement block;
public boolean isStatic() {
return isStatic;
}
public void setStatic(boolean aStatic) {
isStatic = aStatic;
}
public List<SQLParameter> getParameters() {
return parameters;
}
public SQLDataType getReturnDataType() {
return returnDataType;
}
public void setReturnDataType(SQLDataType x) {
if (x != null) {
x.setParent(this);
}
this.returnDataType = x;
}
public OracleFunctionDataType clone() {
OracleFunctionDataType x = new OracleFunctionDataType();
cloneTo(x);
x.isStatic = isStatic;
if (returnDataType != null) {
x.setReturnDataType(returnDataType.clone());
}
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;
}
}
@@ -249,7 +249,7 @@ public class OracleLexer extends Lexer {
stringVal = subString(mark + startHintSp, (bufPos - startHintSp) - 1);
token = Token.HINT;
} else {
stringVal = subString(mark, bufPos);
stringVal = subString(mark, bufPos + 1);
token = Token.MULTI_LINE_COMMENT;
commentCount++;
if (keepComments) {
@@ -29,6 +29,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartit
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterTableSplitPartition.UpdateIndexesClause;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleLockTableStatement.LockMode;
import com.alibaba.druid.sql.parser.*;
import com.alibaba.druid.util.FnvHash;
import com.alibaba.druid.util.JdbcConstants;
public class OracleStatementParser extends SQLStatementParser {
@@ -752,7 +753,6 @@ public class OracleStatementParser extends SQLStatementParser {
}
public SQLCreateFunctionStatement parseCreateFunction() {
accept(Token.CREATE);
SQLCreateFunctionStatement stmt = (SQLCreateFunctionStatement) parseFunction();
stmt.setCreate(true);
return stmt;
@@ -770,6 +770,9 @@ public class OracleStatementParser extends SQLStatementParser {
stmt.setOrReplace(true);
}
} else {
if (lexer.token() == Token.DECLARE) {
lexer.nextToken();
}
stmt.setCreate(false);
}
@@ -805,10 +808,8 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
if (lexer.token() == Token.IS) {
if (lexer.token() == Token.IS || lexer.token() == Token.AS) {
lexer.nextToken();
} else {
accept(Token.AS);
}
if (lexer.identifierEquals("LANGUAGE")) {
@@ -825,7 +826,30 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
SQLStatement block = this.parseBlock();
if (lexer.identifierEquals("PARALLEL_ENABLE")) {
lexer.nextToken();
stmt.setParallelEnable(true);
}
if (lexer.identifierEquals("AGGREGATE")) {
lexer.nextToken();
stmt.setAggregate(true);
}
if (lexer.token() == Token.USING) {
lexer.nextToken();
SQLName using = this.exprParser.name();
stmt.setUsing(using);
}
SQLStatement block;
if (lexer.token() == Token.SEMI) {
stmt.setAfterSemi(true);
lexer.nextToken();
block = null;
} else {
block = this.parseBlock();
}
stmt.setBlock(block);
@@ -1031,6 +1055,7 @@ public class OracleStatementParser extends SQLStatementParser {
}
public SQLStatement parserAlter() {
Lexer.SavePoint savePoint = lexer.mark();
accept(Token.ALTER);
if (lexer.token() == Token.SESSION) {
lexer.nextToken();
@@ -1227,11 +1252,76 @@ public class OracleStatementParser extends SQLStatementParser {
}
return stmt;
} else if (lexer.token() == Token.FUNCTION) {
lexer.reset(savePoint);
return parseAlterFunction();
} else if (lexer.identifierEquals(FnvHash.Constants.TYPE)) {
lexer.reset(savePoint);
return parseAlterType();
}
throw new ParserException("TODO : " + lexer.info());
}
protected SQLStatement parseAlterType() {
accept(Token.ALTER);
acceptIdentifier("TYPE");
SQLAlterTypeStatement stmt = new SQLAlterTypeStatement();
stmt.setDbType(dbType);
SQLName name = this.exprParser.name();
stmt.setName(name);
if (lexer.identifierEquals("COMPILE")) {
stmt.setCompile(true);
lexer.nextToken();
}
if (lexer.identifierEquals("DEBUG")) {
stmt.setDebug(true);
lexer.nextToken();
}
if (lexer.identifierEquals("BODY")) {
stmt.setBody(true);
lexer.nextToken();
}
if (lexer.identifierEquals("REUSE")) {
stmt.setReuseSettings(true);
lexer.nextToken();
acceptIdentifier("SETTINGS");
}
return stmt;
}
protected SQLStatement parseAlterFunction() {
accept(Token.ALTER);
accept(Token.FUNCTION);
SQLAlterFunctionStatement stmt = new SQLAlterFunctionStatement();
stmt.setDbType(dbType);
SQLName name = this.exprParser.name();
stmt.setName(name);
acceptIdentifier("COMPILE");
if (lexer.identifierEquals("DEBUG")) {
stmt.setDebug(true);
lexer.nextToken();
}
if (lexer.identifierEquals("REUSE")) {
stmt.setReuseSettings(true);
lexer.nextToken();
acceptIdentifier("SETTINGS");
}
return stmt;
}
private SQLStatement parseAlterTable() {
lexer.nextToken();
SQLAlterTableStatement stmt = new SQLAlterTableStatement(getDbType());
@@ -1528,6 +1618,8 @@ public class OracleStatementParser extends SQLStatementParser {
SQLBlockStatement block = new SQLBlockStatement();
block.setDbType(JdbcConstants.ORACLE);
Lexer.SavePoint savePoint = lexer.mark();
if (lexer.token() == Token.DECLARE) {
lexer.nextToken();
}
@@ -1548,6 +1640,11 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
if (lexer.token() == Token.FUNCTION) {
lexer.reset(savePoint);
return this.parseCreateFunction();
}
accept(Token.BEGIN);
parseStatementList(block.getStatementList(), -1, block);
@@ -1573,6 +1670,7 @@ public class OracleStatementParser extends SQLStatementParser {
private void parserParameters(List<SQLParameter> parameters, SQLObject parent) {
for (;;) {
SQLParameter parameter = new SQLParameter();
parameter.setParent(parent);
SQLName name;
SQLDataType dataType = null;
@@ -1666,9 +1764,31 @@ public class OracleStatementParser extends SQLStatementParser {
parameter.setConstant(true);
}
dataType = this.exprParser.parseDataType(false);
if ((name.nameHashCode64() == FnvHash.Constants.MEMBER
|| name.nameHashCode64() == FnvHash.Constants.STATIC)
&& lexer.token() == Token.FUNCTION) {
OracleFunctionDataType functionDataType = new OracleFunctionDataType();
functionDataType.setStatic(name.nameHashCode64() == FnvHash.Constants.STATIC);
lexer.nextToken();
functionDataType.setName(lexer.stringVal());
accept(Token.IDENTIFIER);
accept(Token.LPAREN);
this.parserParameters(functionDataType.getParameters(), functionDataType);
accept(Token.RPAREN);
accept(Token.RETURN);
functionDataType.setReturnDataType(this.exprParser.parseDataType());
dataType = functionDataType;
name = null;
if (lexer.token() == Token.COLONEQ) {
if (lexer.token() == Token.IS) {
lexer.nextToken();
SQLStatement block = this.parseBlock();
functionDataType.setBlock(block);
}
} else {
dataType = this.exprParser.parseDataType(false);
}
if (lexer.token() == Token.COLONEQ || lexer.token() == Token.DEFAULT) {
lexer.nextToken();
parameter.setDefaultValue(this.exprParser.expr());
}
@@ -1679,11 +1799,12 @@ public class OracleStatementParser extends SQLStatementParser {
parameters.add(parameter);
Token token = lexer.token();
if (token == Token.COMMA || token == Token.SEMI) {
if (token == Token.COMMA || token == Token.SEMI || token == Token.IS) {
lexer.nextToken();
}
if (lexer.token() != Token.BEGIN && lexer.token() != Token.RPAREN) {
token = lexer.token();
if (token != Token.BEGIN && token != Token.RPAREN && token != Token.EOF) {
continue;
}
@@ -2397,4 +2518,47 @@ public class OracleStatementParser extends SQLStatementParser {
stmt.setObject(this.exprParser.name());
return stmt;
}
public SQLStatement parseCreateType() {
OracleCreateTypeStatement stmt = new OracleCreateTypeStatement();
accept(Token.CREATE);
if (lexer.token() == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
stmt.setOrReplace(true);
}
acceptIdentifier("TYPE");
if (lexer.identifierEquals("BODY")) {
lexer.nextToken();
stmt.setBody(true);
}
SQLName name = this.exprParser.name();
stmt.setName(name);
if (lexer.token() == Token.AS || lexer.token() == Token.IS) {
lexer.nextToken();
}
if (lexer.identifierEquals("OBJECT")) {
lexer.nextToken();
}
if (lexer.identifierEquals(FnvHash.Constants.STATIC)) {
this.parserParameters(stmt.getParameters(), stmt);
} else {
accept(Token.LPAREN);
this.parserParameters(stmt.getParameters(), stmt);
accept(Token.RPAREN);
}
if (lexer.token() == Token.SEMI) {
lexer.nextToken();
stmt.setAfterSemi(true);
}
return stmt;
}
}
@@ -429,4 +429,8 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleCreateSynonymStatement x);
void endVisit(OracleCreateSynonymStatement x);
boolean visit(OracleCreateTypeStatement x);
void endVisit(OracleCreateTypeStatement x);
}
@@ -1063,4 +1063,14 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
public void endVisit(OracleCreateSynonymStatement x) {
}
@Override
public boolean visit(OracleCreateTypeStatement x) {
return true;
}
@Override
public void endVisit(OracleCreateTypeStatement x) {
}
}
@@ -2683,7 +2683,25 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
return false;
}
block.accept(this);
if (x.isParallelEnable()) {
print0(ucase ? "PARALLEL_ENABLE" : "parallel_enable");
println();
}
if (x.isAggregate()) {
print0(ucase ? "AGGREGATE" : "aggregate");
println();
}
SQLName using = x.getUsing();
if (using != null) {
print0(ucase ? "USING " : "using ");
using.accept(this);
}
if (block != null) {
block.accept(this);
}
return false;
}
@@ -3259,7 +3277,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
@Override
public boolean visit(OracleCreateSynonymStatement x) {
if (x.isOrReplace()) {
print0(ucase ? "CREATE OR REPLACE " : "create or replace ");
} else {
@@ -3284,4 +3301,34 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public void endVisit(OracleCreateSynonymStatement x) {
}
@Override
public boolean visit(OracleCreateTypeStatement x) {
if (x.isOrReplace()) {
print0(ucase ? "CREATE OR REPLACE TYPE " : "create or replace type ");
} else {
print0(ucase ? "CREATE TYPE " : "create type ");
}
x.getName().accept(this);
if (x.isForce()) {
print0(ucase ? "FORCE " : "force ");
}
print0(" AS OBJECT (");
indentCount++;
println();
printlnAndAccept(x.getParameters(), ", ");
indentCount--;
println();
print0(")");
return false;
}
@Override
public void endVisit(OracleCreateTypeStatement x) {
}
}
@@ -1355,4 +1355,14 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
public void endVisit(OracleCreateSynonymStatement x) {
}
@Override
public boolean visit(OracleCreateTypeStatement x) {
return false;
}
@Override
public void endVisit(OracleCreateTypeStatement x) {
}
}
@@ -1874,11 +1874,21 @@ public class SQLStatementParser extends SQLParser {
return parseCreateTrigger();
}
if (lexer.token == Token.FUNCTION) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateFunction();
}
if (lexer.identifierEquals(FnvHash.Constants.PACKAGE)) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreatePackage();
}
if (lexer.identifierEquals(FnvHash.Constants.TYPE)) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateType();
}
// lexer.reset(mark_bp, mark_ch, Token.CREATE);
throw new ParserException("TODO " + lexer.info());
} else if (token == Token.DATABASE) {
@@ -1927,11 +1937,18 @@ public class SQLStatementParser extends SQLParser {
} else if (lexer.identifierEquals(FnvHash.Constants.MATERIALIZED)) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateMaterializedView();
} else if (lexer.identifierEquals(FnvHash.Constants.TYPE)) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateType();
}
throw new ParserException("TODO " + lexer.token);
}
public SQLStatement parseCreateType() {
throw new ParserException("TODO " + lexer.token);
}
public SQLStatement parseCreateUser() {
accept(Token.CREATE);
accept(Token.USER);
@@ -39,6 +39,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
import com.alibaba.druid.sql.ast.statement.SQLDeclareStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
import oracle.sql.SQLUtil;
@@ -4239,8 +4240,32 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
return false;
}
public boolean visit(OracleFunctionDataType x) {
if (x.isStatic()) {
print0(ucase ? "STATIC " : "static ");
}
print0(ucase ? "FUNCTION " : "function ");
print0(x.getName());
print(" (");
printAndAccept(x.getParameters(), ", ");
print(")");
print0(ucase ? " RETURN " : " return ");
x.getReturnDataType().accept(this);
SQLStatement block = x.getBlock();
if (block != null) {
block.accept(this);
}
return false;
}
@Override
public boolean visit(SQLParameter x) {
SQLName name = x.getName();
if (x.getDataType().getName().equalsIgnoreCase("CURSOR")) {
print0(ucase ? "CURSOR " : "cursor ");
x.getName().accept(this);
@@ -4255,6 +4280,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
SQLDataType dataType = x.getDataType();
if (JdbcConstants.ORACLE.equals(dbType)) {
if (dataType instanceof OracleFunctionDataType) {
OracleFunctionDataType functionDataType = (OracleFunctionDataType) dataType;
visit(functionDataType);
return false;
}
String dataTypeName = dataType.getName();
boolean printType = (dataTypeName.startsWith("TABLE OF") && x.getDefaultValue() == null)
|| dataTypeName.equalsIgnoreCase("REF CURSOR")
@@ -4263,7 +4293,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print0(ucase ? "TYPE " : "type ");
}
x.getName().accept(this);
name.accept(this);
if (x.getParamType() == SQLParameter.ParameterType.IN) {
print0(ucase ? " IN " : " in ");
} else if (x.getParamType() == SQLParameter.ParameterType.OUT) {
@@ -5277,6 +5307,44 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
return false;
}
public boolean visit(SQLAlterFunctionStatement x) {
print0(ucase ? "ALTER FUNCTION " : "alter function ");
x.getName().accept(this);
if (x.isDebug()) {
print0(ucase ? " DEBUG" : " debug");
}
if (x.isReuseSettings()) {
print0(ucase ? " REUSE SETTINGS" : " reuse settings");
}
return false;
}
public boolean visit(SQLAlterTypeStatement x) {
print0(ucase ? "ALTER TYPE " : "alter type ");
x.getName().accept(this);
if (x.isCompile()) {
print0(ucase ? " COMPILE" : " compile");
}
if (x.isBody()) {
print0(ucase ? " BODY" : " body");
}
if (x.isDebug()) {
print0(ucase ? " DEBUG" : " debug");
}
if (x.isReuseSettings()) {
print0(ucase ? " REUSE SETTINGS" : " reuse settings");
}
return false;
}
public Boolean getPrintStatementAfterSemi() {
return printStatementAfterSemi;
}
@@ -750,4 +750,12 @@ public interface SQLASTVisitor {
boolean visit(SQLCreateUserStatement x);
void endVisit(SQLCreateUserStatement x);
boolean visit(SQLAlterFunctionStatement x);
void endVisit(SQLAlterFunctionStatement x);
boolean visit(SQLAlterTypeStatement x);
void endVisit(SQLAlterTypeStatement x);
}
@@ -1719,6 +1719,26 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
}
@Override
public boolean visit(SQLAlterFunctionStatement x) {
return true;
}
@Override
public void endVisit(SQLAlterFunctionStatement x) {
}
@Override
public boolean visit(SQLAlterTypeStatement x) {
return true;
}
@Override
public void endVisit(SQLAlterTypeStatement x) {
}
public final boolean isEnabled(VisitorFeature feature) {
return VisitorFeature.isEnabled(this.features, feature);
}
@@ -2365,4 +2365,12 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
x.accept(this);
}
}
public boolean visit(SQLAlterFunctionStatement x) {
return false;
}
public boolean visit(SQLAlterTypeStatement x) {
return false;
}
}
@@ -501,5 +501,10 @@ public final class FnvHash {
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 MEMBER = fnv1a_64_lower("MEMBER");
long STATIC = fnv1a_64_lower("STATIC");
long UNSUPPORTED = fnv1a_64_lower("UNSUPPORTED");
}
}