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:
@@ -48,6 +48,11 @@ public class SQLDataTypeImpl extends SQLObjectImpl implements SQLDataType {
|
||||
addArgument(new SQLIntegerExpr(precision));
|
||||
}
|
||||
|
||||
public SQLDataTypeImpl(String name, SQLExpr arg) {
|
||||
this(name);
|
||||
addArgument(arg);
|
||||
}
|
||||
|
||||
public SQLDataTypeImpl(String name, int precision, int scale) {
|
||||
this(name);
|
||||
addArgument(new SQLIntegerExpr(precision));
|
||||
|
||||
@@ -2922,7 +2922,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
if (count != 0) {
|
||||
print0(", ");
|
||||
}
|
||||
print0(ucase ? "FOREIGHN KEY" : "foreighn key");
|
||||
print0(ucase ? "FOREIGN KEY" : "foreign key");
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
+18
-2
@@ -41,6 +41,7 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.Fetc
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.ForClause;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -453,17 +454,32 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
@Override
|
||||
public boolean visit(PGTypeCastExpr x) {
|
||||
SQLExpr expr = x.getExpr();
|
||||
SQLDataType dataType = x.getDataType();
|
||||
|
||||
if (dataType.nameHashCode64() == FnvHash.Constants.VARBIT) {
|
||||
dataType.accept(this);
|
||||
print(' ');
|
||||
printExpr(expr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expr != null) {
|
||||
if (expr instanceof SQLBinaryOpExpr) {
|
||||
print('(');
|
||||
expr.accept(this);
|
||||
print(')');
|
||||
} else if (expr instanceof PGTypeCastExpr && dataType.getArguments().size() == 0) {
|
||||
dataType.accept(this);
|
||||
print('(');
|
||||
visit((PGTypeCastExpr) expr);
|
||||
print(')');
|
||||
return false;
|
||||
} else {
|
||||
expr.accept(this);
|
||||
}
|
||||
}
|
||||
print0("::");
|
||||
x.getDataType().accept(this);
|
||||
dataType.accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1775,7 +1791,7 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
if (count != 0) {
|
||||
print0(", ");
|
||||
}
|
||||
print0(ucase ? "FOREIGHN KEY" : "foreighn key");
|
||||
print0(ucase ? "FOREIGN KEY" : "foreign key");
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
@@ -1012,6 +1013,19 @@ public class SQLExprParser extends SQLParser {
|
||||
} else if (hash_lower == FnvHash.Constants.POSITION
|
||||
&& JdbcConstants.MYSQL.equals(dbType)) {
|
||||
return parsePosition();
|
||||
} else if (hash_lower == FnvHash.Constants.INT4 && JdbcConstants.POSTGRESQL.equals(dbType)) {
|
||||
PGTypeCastExpr castExpr = new PGTypeCastExpr();
|
||||
castExpr.setExpr(this.expr());
|
||||
castExpr.setDataType(new SQLDataTypeImpl(methodName));
|
||||
accept(Token.RPAREN);
|
||||
return castExpr;
|
||||
} else if (hash_lower == FnvHash.Constants.VARBIT && JdbcConstants.POSTGRESQL.equals(dbType)) {
|
||||
PGTypeCastExpr castExpr = new PGTypeCastExpr();
|
||||
SQLExpr len = this.primary();
|
||||
castExpr.setDataType(new SQLDataTypeImpl(methodName, len));
|
||||
accept(Token.RPAREN);
|
||||
castExpr.setExpr(this.expr());
|
||||
return castExpr;
|
||||
}
|
||||
aggMethodName = getAggreateFunction(hash_lower);
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.parser;
|
||||
|
||||
public enum SQLParserFeature {
|
||||
KeepInsertValueClauseOriginalString,
|
||||
KeepSelectListOriginalString, // for improved sql parameterized performance
|
||||
UseInsertColumnsCache,
|
||||
EnableSQLBinaryOpExprGroup,
|
||||
OptimizedForParameterized,
|
||||
|
||||
@@ -99,7 +99,7 @@ public class OracleCreateTableTest41 extends OracleTest {
|
||||
"\tSUPPLEMENTAL LOG GROUP \"GGS_16346\" (\"NUM\") ALWAYS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (UNIQUE INDEX) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (FOREIGHN KEY) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (ALL) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG GROUP \"ALLINS_POLNO\" (\"NUM\") ALWAYS\n" +
|
||||
")\n" +
|
||||
|
||||
@@ -73,7 +73,7 @@ public class OracleCreateTableTest42 extends OracleTest {
|
||||
"\tSUPPLEMENTAL LOG GROUP \"GGS_15754\" (\"GROUP_NAME\", \"GROUP_KEY\", \"LOG_CMPLT_CSN\", \"LOG_CMPLT_XIDS_SEQ\") ALWAYS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (UNIQUE INDEX) COLUMNS,\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (FOREIGHN KEY) COLUMNS\n" +
|
||||
"\tSUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS\n" +
|
||||
")\n" +
|
||||
"PCTFREE 10\n" +
|
||||
"PCTUSED 40\n" +
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.oracle.pl;
|
||||
|
||||
import com.alibaba.druid.sql.OracleTest;
|
||||
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 java.util.List;
|
||||
|
||||
public class Oracle_pl_4 extends OracleTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "begin buf_b := HEXTORAW('636865642f4c'); \n" +
|
||||
" dbms_lob.write(loc_b, 2048, 28493, buf_b);\n" +
|
||||
"END;\n" +
|
||||
"\n "; //
|
||||
|
||||
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE);
|
||||
assertEquals(1, statementList.size());
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ORACLE);
|
||||
for (SQLStatement statement : statementList) {
|
||||
statement.accept(visitor);
|
||||
}
|
||||
|
||||
// System.out.println("Tables : " + visitor.getTables());
|
||||
// System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("relationships : " + visitor.getRelationships());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
assertEquals(0, visitor.getTables().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees")));
|
||||
// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("emp_name")));
|
||||
|
||||
// Assert.assertEquals(7, visitor.getColumns().size());
|
||||
// Assert.assertEquals(3, visitor.getConditions().size());
|
||||
// Assert.assertEquals(1, visitor.getRelationships().size());
|
||||
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary")));
|
||||
|
||||
{
|
||||
String output = SQLUtils.toOracleString(stmt);
|
||||
assertEquals("BEGIN\n" +
|
||||
"\tbuf_b := HEXTORAW('636865642f4c');\n" +
|
||||
"\tdbms_lob.write(loc_b, 2048, 28493, buf_b);\n" +
|
||||
"END;", //
|
||||
output);
|
||||
}
|
||||
{
|
||||
String output = SQLUtils.toOracleString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
|
||||
assertEquals("begin\n" +
|
||||
"\tbuf_b := HEXTORAW('636865642f4c');\n" +
|
||||
"\tdbms_lob.write(loc_b, 2048, 28493, buf_b);\n" +
|
||||
"end;", //
|
||||
output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.alibaba.druid.sql.PGTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PGInsertTest10 extends PGTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "INSERT INTO test VALUES (B'101', B'00');";
|
||||
|
||||
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
// print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
|
||||
assertTrue(visitor.getTables().containsKey(new TableStat.Name("test")));
|
||||
assertEquals(0, visitor.getColumns().size());
|
||||
//
|
||||
// assertTrue(visitor.getColumns().contains(new TableStat.Column("distributors", "did")));
|
||||
// assertTrue(visitor.getColumns().contains(new TableStat.Column("distributors", "dname")));
|
||||
|
||||
assertEquals("INSERT INTO test\n" +
|
||||
"VALUES (B'101', B'00');", stmt.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.alibaba.druid.sql.PGTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PGInsertTest11 extends PGTest {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "INSERT INTO test VALUES (B'10'::bit(3), B'101');";
|
||||
|
||||
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
// print(statementList);
|
||||
|
||||
assertEquals(1, statementList.size());
|
||||
|
||||
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
|
||||
assertTrue(visitor.getTables().containsKey(new TableStat.Name("test")));
|
||||
assertEquals(0, visitor.getColumns().size());
|
||||
//
|
||||
// assertTrue(visitor.getColumns().contains(new TableStat.Column("distributors", "did")));
|
||||
// assertTrue(visitor.getColumns().contains(new TableStat.Column("distributors", "dname")));
|
||||
|
||||
assertEquals("INSERT INTO test\n" +
|
||||
"VALUES (B'10'::bit(3), B'101');", stmt.toString());
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 PGSelectTest61_type_string extends TestCase {
|
||||
private final String dbType = JdbcConstants.POSTGRESQL;
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "select int4(varbit(4) '1010');";
|
||||
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
|
||||
SQLStatement stmt = stmtList.get(0);
|
||||
|
||||
assertEquals("SELECT int4(varbit(4) '1010');", SQLUtils.toPGString(stmt));
|
||||
|
||||
assertEquals("select int4(varbit(4) '1010');", 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(0, visitor.getColumns().size());
|
||||
assertEquals(0, visitor.getTables().size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user