Description:
The following test case triggered a java.lang.NumberFormatException in JDBC driver:
```
DROP DATABASE IF EXISTS database6;
CREATE DATABASE database6;
USE database6;
CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
INSERT INTO t0(c0) VALUES("-0.0");
SELECT t0.c0 FROM t0;
```
When I run it in command line, I get the following outputs:
```
mysql> DROP DATABASE IF EXISTS database6;
Query OK, 1 row affected (0.24 sec)
mysql> CREATE DATABASE database6;
Query OK, 1 row affected (0.07 sec)
mysql> USE database6;
Database changed, 1 warning
mysql> CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
Query OK, 0 rows affected, 1 warning (0.20 sec)
mysql> INSERT INTO t0(c0) VALUES("-0.0");
Query OK, 1 row affected (0.06 sec)
mysql> SELECT t0.c0 FROM t0;
+--------------+
| c0 |
+--------------+
| 0000000000-0 |
+--------------+
1 row in set (0.00 sec)
```
But when I run it with a harness, it triggers an exception. This is the outputs:
```
Connect ...
Connect success.
Query: DROP DATABASE IF EXISTS database6;
Query: CREATE DATABASE database6;
Query: USE database6;
Query: CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
Query: INSERT INTO t0(c0) VALUES("-0.0");
Query: SELECT t0.c0 FROM t0;
For input string: "0000000000-0"
java.lang.NumberFormatException: For input string: "0000000000-0"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:543)
at com.mysql.cj.protocol.a.MysqlTextValueDecoder.getDouble(MysqlTextValueDecoder.java:249)
at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDouble(MysqlTextValueDecoder.java:134)
at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeFloat(MysqlTextValueDecoder.java:130)
at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:116)
at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:243)
at com.mysql.cj.protocol.a.result.ByteArrayRow.getValue(ByteArrayRow.java:91)
at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1334)
at com.mysql.cj.jdbc.result.ResultSetImpl.getFloat(ResultSetImpl.java:819)
at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1207)
at reproduce_mysql$MySQLHandle.batchDate(reproduce_mysql.java:80)
at reproduce_mysql$MySQLHandle.runSqlByReadFileContent(reproduce_mysql.java:144)
at reproduce_mysql.main(reproduce_mysql.java:24)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:404)
at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:179)
at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:119)
```
How to repeat:
This is the harness:
```
```
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.text.SimpleDateFormat;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
public class reproduce_mysql {
public static void main(String[] args) throws Exception {
MySQLHandle sh = new MySQLHandle();
try {
sh.runSqlByReadFileContent(args[0]);
} catch (Exception e) {
e.printStackTrace();
} finally {
sh.ReleaseConnect();
}
}
static class MySQLHandle {
private Connection connection;
String host = "127.0.0.1";
int port = 3306;
String username = "root";
String password = "123456";
String url = String.format("jdbc:mysql://%s:%d?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true", host, port);
public MySQLHandle(){
try {
System.out.println("Connect ...");
connection = DriverManager.getConnection(url, username, password);
System.out.println("Connect success.");
} catch (Exception e) {
e.printStackTrace();
connection = null;
}
}
public Connection getConnection(){
return connection;
}
public void ReleaseConnect(){
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public int batchDate(ArrayList<String> sql){
try (Statement statement = connection.createStatement()){
for(String script: sql) {
if (script.startsWith("--")) {
continue;
}
System.out.println("Query: " + script);
if (script.startsWith("SELECT") || script.startsWith("WITH")) {
try (ResultSet rs = statement.executeQuery(script)) {
ResultSetMetaData metaData = rs.getMetaData();
Integer columnCount = metaData.getColumnCount();
while (rs.next()) {
for (int i = 1; i <= columnCount; i++) {
try {
Object value = rs.getObject(i);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(0);
}
}
}
} catch(Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(0);
}
} else {
try {
statement.execute(script);
} catch (Exception e) {
System.out.println("Error Query: " + script);
}
}
}
return 1;
}catch (Exception e) {
e.printStackTrace();
return 0;
}
}
private ArrayList<String> readFileByLines(String filePath) throws Exception {
ArrayList<String> listStr=new ArrayList<>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(filePath), "UTF-8"));
String tempString = null;
while ((tempString = reader.readLine()) != null) {
if(tempString.trim().equals(""))
continue;
if(tempString.startsWith("--"))
continue;
listStr.add(tempString);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return listStr;
}
public void runSqlByReadFileContent(String sqlPath){
try {
ArrayList<String> sqlStr = readFileByLines(sqlPath);
if (sqlStr.size() > 0) {
int num=batchDate(sqlStr);
if(num>0)
System.out.println("success!");
else
System.out.println("failed!");
}
else{
System.out.println("no sql statements!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
```
```
I run the MySQL in docker with version `Server version: 9.1.0 MySQL Community Server - GPL`
I use the jdbc driver 8.0.30
I reproduce the exception with the following command:
```
java -cp ~/.m2/repository/mysql/mysql-connector-java/8.0.30/mysql-connector-java-8.0.30.jar ./reproduce_mysql.java database6-reduce.sql
```
Description: The following test case triggered a java.lang.NumberFormatException in JDBC driver: ``` DROP DATABASE IF EXISTS database6; CREATE DATABASE database6; USE database6; CREATE TABLE t0(c0 FLOAT ZEROFILL) ; INSERT INTO t0(c0) VALUES("-0.0"); SELECT t0.c0 FROM t0; ``` When I run it in command line, I get the following outputs: ``` mysql> DROP DATABASE IF EXISTS database6; Query OK, 1 row affected (0.24 sec) mysql> CREATE DATABASE database6; Query OK, 1 row affected (0.07 sec) mysql> USE database6; Database changed, 1 warning mysql> CREATE TABLE t0(c0 FLOAT ZEROFILL) ; Query OK, 0 rows affected, 1 warning (0.20 sec) mysql> INSERT INTO t0(c0) VALUES("-0.0"); Query OK, 1 row affected (0.06 sec) mysql> SELECT t0.c0 FROM t0; +--------------+ | c0 | +--------------+ | 0000000000-0 | +--------------+ 1 row in set (0.00 sec) ``` But when I run it with a harness, it triggers an exception. This is the outputs: ``` Connect ... Connect success. Query: DROP DATABASE IF EXISTS database6; Query: CREATE DATABASE database6; Query: USE database6; Query: CREATE TABLE t0(c0 FLOAT ZEROFILL) ; Query: INSERT INTO t0(c0) VALUES("-0.0"); Query: SELECT t0.c0 FROM t0; For input string: "0000000000-0" java.lang.NumberFormatException: For input string: "0000000000-0" at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054) at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at java.base/java.lang.Double.parseDouble(Double.java:543) at com.mysql.cj.protocol.a.MysqlTextValueDecoder.getDouble(MysqlTextValueDecoder.java:249) at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDouble(MysqlTextValueDecoder.java:134) at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeFloat(MysqlTextValueDecoder.java:130) at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:116) at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:243) at com.mysql.cj.protocol.a.result.ByteArrayRow.getValue(ByteArrayRow.java:91) at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1334) at com.mysql.cj.jdbc.result.ResultSetImpl.getFloat(ResultSetImpl.java:819) at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1207) at reproduce_mysql$MySQLHandle.batchDate(reproduce_mysql.java:80) at reproduce_mysql$MySQLHandle.runSqlByReadFileContent(reproduce_mysql.java:144) at reproduce_mysql.main(reproduce_mysql.java:24) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:404) at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:179) at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:119) ``` How to repeat: This is the harness: ``` ``` import java.math.BigDecimal; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.text.SimpleDateFormat; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.IOException; public class reproduce_mysql { public static void main(String[] args) throws Exception { MySQLHandle sh = new MySQLHandle(); try { sh.runSqlByReadFileContent(args[0]); } catch (Exception e) { e.printStackTrace(); } finally { sh.ReleaseConnect(); } } static class MySQLHandle { private Connection connection; String host = "127.0.0.1"; int port = 3306; String username = "root"; String password = "123456"; String url = String.format("jdbc:mysql://%s:%d?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true", host, port); public MySQLHandle(){ try { System.out.println("Connect ..."); connection = DriverManager.getConnection(url, username, password); System.out.println("Connect success."); } catch (Exception e) { e.printStackTrace(); connection = null; } } public Connection getConnection(){ return connection; } public void ReleaseConnect(){ if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } public int batchDate(ArrayList<String> sql){ try (Statement statement = connection.createStatement()){ for(String script: sql) { if (script.startsWith("--")) { continue; } System.out.println("Query: " + script); if (script.startsWith("SELECT") || script.startsWith("WITH")) { try (ResultSet rs = statement.executeQuery(script)) { ResultSetMetaData metaData = rs.getMetaData(); Integer columnCount = metaData.getColumnCount(); while (rs.next()) { for (int i = 1; i <= columnCount; i++) { try { Object value = rs.getObject(i); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); System.exit(0); } } } } catch(Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); System.exit(0); } } else { try { statement.execute(script); } catch (Exception e) { System.out.println("Error Query: " + script); } } } return 1; }catch (Exception e) { e.printStackTrace(); return 0; } } private ArrayList<String> readFileByLines(String filePath) throws Exception { ArrayList<String> listStr=new ArrayList<>(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader( new FileInputStream(filePath), "UTF-8")); String tempString = null; while ((tempString = reader.readLine()) != null) { if(tempString.trim().equals("")) continue; if(tempString.startsWith("--")) continue; listStr.add(tempString); } reader.close(); } catch (IOException e) { e.printStackTrace(); throw e; } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } return listStr; } public void runSqlByReadFileContent(String sqlPath){ try { ArrayList<String> sqlStr = readFileByLines(sqlPath); if (sqlStr.size() > 0) { int num=batchDate(sqlStr); if(num>0) System.out.println("success!"); else System.out.println("failed!"); } else{ System.out.println("no sql statements!"); } } catch (Exception e) { e.printStackTrace(); } } } } ``` ``` I run the MySQL in docker with version `Server version: 9.1.0 MySQL Community Server - GPL` I use the jdbc driver 8.0.30 I reproduce the exception with the following command: ``` java -cp ~/.m2/repository/mysql/mysql-connector-java/8.0.30/mysql-connector-java-8.0.30.jar ./reproduce_mysql.java database6-reduce.sql ```