diff --git a/src/main/java/com/alibaba/druid/sql/SQLTransformUtils.java b/src/main/java/com/alibaba/druid/sql/SQLTransformUtils.java index a264ea0a10..075cd291fd 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLTransformUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLTransformUtils.java @@ -432,7 +432,9 @@ public class SQLTransformUtils { } else if (nameHash == FnvHash.Constants.BINARY_DOUBLE || nameHash == FnvHash.Constants.FLOAT - || nameHash == FnvHash.Constants.REAL) { + || nameHash == FnvHash.Constants.DOUBLE + || nameHash == FnvHash.Constants.REAL + || nameHash == FnvHash.Constants.DOUBLE_PRECISION) { dataType = new SQLDataTypeImpl("double precision"); } else if (nameHash == FnvHash.Constants.NUMBER) { @@ -497,8 +499,23 @@ public class SQLTransformUtils { } } - } else if (nameHash == FnvHash.Constants.CHAR - || nameHash == FnvHash.Constants.CHARACTER) { + } else if (nameHash == FnvHash.Constants.CHARACTER) { + if (argumentns.size() == 1) { + SQLExpr arg0 = argumentns.get(0); + + int len; + if (arg0 instanceof SQLNumericLiteralExpr) { + len = ((SQLNumericLiteralExpr) arg0).getNumber().intValue(); + } else { + throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); + } + dataType = new SQLCharacterDataType("char", len); + } else if (argumentns.size() == 0) { + dataType = new SQLCharacterDataType("char"); + } else { + throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); + } + } else if (nameHash == FnvHash.Constants.CHAR) { if (argumentns.size() == 1) { SQLExpr arg0 = argumentns.get(0); @@ -509,40 +526,21 @@ public class SQLTransformUtils { throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); } - if (len <= 255) { - dataType = new SQLCharacterDataType("char", len); + if (len <= 2000) { + dataType = x; } else { - dataType = new SQLCharacterDataType("varchar", len); + dataType = new SQLCharacterDataType("text"); } } else if (argumentns.size() == 0) { dataType = new SQLCharacterDataType("char"); } else { throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); } - } else if (nameHash == FnvHash.Constants.NCHAR) { - if (argumentns.size() == 1) { - SQLExpr arg0 = argumentns.get(0); - - int len; - if (arg0 instanceof SQLNumericLiteralExpr) { - len = ((SQLNumericLiteralExpr) arg0).getNumber().intValue(); - } else { - throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); - } - - if (len <= 255) { - dataType = new SQLCharacterDataType("char", len); - } else { - dataType = new SQLCharacterDataType("varchar", len); - } - } else if (argumentns.size() == 0) { - dataType = new SQLCharacterDataType("char"); - } else { - throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); - } - - } else if (nameHash == FnvHash.Constants.VARCHAR2) { + // no changed + dataType = x; + } else if (nameHash == FnvHash.Constants.VARCHAR + || nameHash == FnvHash.Constants.VARCHAR2) { if (argumentns.size() > 0) { int len; SQLExpr arg0 = argumentns.get(0); @@ -551,7 +549,12 @@ public class SQLTransformUtils { } else { throw new UnsupportedOperationException(SQLUtils.toOracleString(x)); } - dataType = new SQLCharacterDataType("varchar", len); + + if (len <= 4000) { + dataType = new SQLCharacterDataType("varchar", len); + } else { + dataType = new SQLCharacterDataType("text"); + } } else { dataType = new SQLCharacterDataType("varchar"); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java index 44442a3849..0a0da89e16 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -28,10 +28,22 @@ import com.alibaba.druid.sql.parser.*; import com.alibaba.druid.util.JdbcUtils; public class ParameterizedOutputVisitorUtils { + private final static SQLParserFeature[] features = { + SQLParserFeature.EnableSQLBinaryOpExprGroup, + SQLParserFeature.OptimizedForParameterized + }; + public static String parameterize(String sql, String dbType) { - SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); - parser.config(SQLParserFeature.EnableSQLBinaryOpExprGroup, true); - parser.config(SQLParserFeature.OptimizedForParameterized, true); + return parameterize(sql, dbType, null); + } + + public static String parameterize(String sql, String dbType, SQLSelectListCache selectListCache) { + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, features); + + if (selectListCache != null) { + parser.setSelectListCache(selectListCache); + } + List statementList = parser.parseStatementList(); if (statementList.size() == 0) { return sql; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_chars.java b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_chars.java new file mode 100644 index 0000000000..c608ca287b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_chars.java @@ -0,0 +1,86 @@ +package com.alibaba.druid.bvt.sql.transform; + +import com.alibaba.druid.sql.SQLTransformUtils; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +public class Oracle2PG_DataTypeTest_chars extends TestCase { + public void test_oracle2pg_char() throws Exception { + String sql = "char(10)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("char(10)", pgDataType.toString()); + } + + public void test_oracle2pg_char_2000() throws Exception { + String sql = "char(2000)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("char(2000)", pgDataType.toString()); + } + + public void test_oracle2pg_char_4000() throws Exception { + String sql = "char(4000)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("text", pgDataType.toString()); + } + + public void test_oracle2pg_nchar() throws Exception { + String sql = "nchar(10)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("nchar(10)", pgDataType.toString()); + } + + public void test_oracle2pg_varchar() throws Exception { + String sql = "varchar(10)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("varchar(10)", pgDataType.toString()); + } + + public void test_oracle2pg_varchar_2000() throws Exception { + String sql = "varchar(2000)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("varchar(2000)", pgDataType.toString()); + } + + public void test_oracle2pg_varchar_4000() throws Exception { + String sql = "varchar(4000)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("varchar(4000)", pgDataType.toString()); + } + + public void test_oracle2pg_varchar_8000() throws Exception { + String sql = "varchar(8000)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("text", pgDataType.toString()); + } + + public void test_oracle2pg_nvarchar() throws Exception { + String sql = "nvarchar(10)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("nvarchar(10)", pgDataType.toString()); + } + + public void test_urowid() throws Exception { + String sql = "urowid(100)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("varchar(100)", pgDataType.toString()); + } + + public void test_bfile() throws Exception { + String sql = "bfile"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("varchar(255)", pgDataType.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_double.java b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_double.java new file mode 100644 index 0000000000..6e051ca44d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_double.java @@ -0,0 +1,52 @@ +package com.alibaba.druid.bvt.sql.transform; + +import com.alibaba.druid.sql.SQLTransformUtils; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +public class Oracle2PG_DataTypeTest_double extends TestCase { + public void test_oracle2pg_float() throws Exception { + String sql = "float"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("double precision", pgDataType.toString()); + } + + public void test_oracle2pg_double() throws Exception { + String sql = "double"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("double precision", pgDataType.toString()); + } + + public void test_oracle2pg_real() throws Exception { + String sql = "real"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("double precision", pgDataType.toString()); + } + + public void test_oracle2pg_binary_float() throws Exception { + String sql = "BINARY_FLOAT"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("real", pgDataType.toString()); + } + + public void test_oracle2pg_binary_double() throws Exception { + String sql = "BINARY_DOUBLE"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("double precision", pgDataType.toString()); + } + + public void test_oracle2pg_binary_double_precision() throws Exception { + String sql = "double precision"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("double precision", pgDataType.toString()); + } +} + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_int.java b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_int.java new file mode 100644 index 0000000000..c6e58d2dde --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_int.java @@ -0,0 +1,31 @@ +package com.alibaba.druid.bvt.sql.transform; + +import com.alibaba.druid.sql.SQLTransformUtils; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +public class Oracle2PG_DataTypeTest_int extends TestCase { + public void test_oracle2pg_int() throws Exception { + String sql = "int"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("decimal(38)", pgDataType.toString()); + } + + public void test_oracle2pg_integer() throws Exception { + String sql = "integer"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("decimal(38)", pgDataType.toString()); + } + + public void test_oracle2pg_smallint() throws Exception { + String sql = "smallint"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("smallint", pgDataType.toString()); + } +} + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_lob.java b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_lob.java new file mode 100644 index 0000000000..ba26ab43f8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_lob.java @@ -0,0 +1,37 @@ +package com.alibaba.druid.bvt.sql.transform; + +import com.alibaba.druid.sql.SQLTransformUtils; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +public class Oracle2PG_DataTypeTest_lob extends TestCase { + public void test_oracle2pg_char() throws Exception { + String sql = "blob"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("bytea", pgDataType.toString()); + } + + public void test_oracle2pg_long() throws Exception { + String sql = "long"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("text", pgDataType.toString()); + } + + public void test_oracle2pg_long_raw() throws Exception { + String sql = "long raw"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("bytea", pgDataType.toString()); + } + + public void test_oracle2pg_raw() throws Exception { + String sql = "raw(100)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("bytea", pgDataType.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_number_int.java b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_number_int.java index 9e3002dff3..c4e8a42c4e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_number_int.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/transform/Oracle2PG_DataTypeTest_number_int.java @@ -167,4 +167,18 @@ public class Oracle2PG_DataTypeTest_number_int extends TestCase { SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); assertEquals("decimal(21)", pgDataType.toString()); } + + public void test_oracle2pg_decimal() throws Exception { + String sql = "decimal(19,1)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("decimal(19, 1)", pgDataType.toString()); + } + + public void test_oracle2pg_dec() throws Exception { + String sql = "dec(19,1)"; + SQLDataType dataType = SQLParserUtils.createExprParser(sql, JdbcConstants.ORACLE).parseDataType(); + SQLDataType pgDataType = SQLTransformUtils.transformOracleToPostgresql(dataType); + assertEquals("decimal(19, 1)", pgDataType.toString()); + } }