Bug #84163 NPE inside statement interceptor with rewriteBatchedStatements=true

Submitted: 12 Dec 2016 12:28 Modified: 3 Sep 2021 10:38
Reporter: Dmitry Adamian Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:5.1.40 OS:Any
Assigned to: Filipe Silva CPU Architecture:Any

[12 Dec 2016 12:28] Dmitry Adamian
Description:
PreparedStatement.getPreparedSql() method throws NullPointerException when called inside StatementInterceptorV2.preProcess() if JDBC connection sets parameter rewriteBatchedStatements=true.

Exception stack trace:
Caused by: java.sql.SQLException: Unexpected exception encountered during query.
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2582)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
	at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
	at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
	at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098)
	at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1543)
	... 35 more
Caused by: java.lang.NullPointerException
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
	at com.mysql.jdbc.StringUtils.findCharset(StringUtils.java:124)
	at com.mysql.jdbc.StringUtils.toString(StringUtils.java:2199)
	at com.mysql.jdbc.PreparedStatement$ParseInfo.getSqlForBatch(PreparedStatement.java:484)
	at com.mysql.jdbc.PreparedStatement.getPreparedSql(PreparedStatement.java:5049)
	at example.Interceptor.preProcess(Interceptor.java:26)
	at com.mysql.jdbc.MysqlIO.invokeStatementInterceptorsPre(MysqlIO.java:2859)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2580)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
	... 40 more

How to repeat:
1. Use rewriteBatchedStatements=true parameter in JDBC connection
2. Register statement interceptor with JDBC URL. Statement interceptor should call PreparedStatement.getPreparedSql()
3. Execute batch update using connection.prepareStatement(), statement.addBatch() and statement.executeBatch().

I've created a reproducible test as a Maven project (https://github.com/dmitry-at-genestack/mysql-jdbc-bug-report). Will also add it as an attachment.

Suggested fix:
Add a check for null charEncoding in method getSqlForBatch(ParseInfo batchInfo)
[12 Dec 2016 12:30] Dmitry Adamian
Maven project with test case for reproducing the bug

Attachment: connector-j-npe-bug-report.zip (application/zip, text), 5.12 KiB.

[14 Dec 2016 10:54] Filipe Silva
Hi Dmitry,

Thank you for this bug report. It is as you described.

As a workaround you can use server-side prepared statements (useServerPrepStmts=true) in which this seems not to be a problem.

Please let us know if this workaround works for you at the moment.

Thank you,
[19 Dec 2016 10:12] Dmitry Adamian
Using parameter useServerPrepStmts=true fixes this problem but negatively affects insert/update performance.

Actually this is not a major problem for me. I am using OpenZipkin/Brave (https://github.com/openzipkin/brave) for collecting performance tracing information. Exception is thrown from statement interceptor of this library. But I can just write custom statement interceptor using PreparedStatement.asSql() instead of PreparedStatement.getPreparedSql().
[3 Sep 2021 10:38] Alexander Soklakov
Posted by developer:
 
This bug is not reproducible with the latest Connector/J 8.0.

Connector/J 5.1 series came to EOL on Feb 9th, 2021, see https://www.mysql.com/support/eol-notice.html, so this bug will not be fixed there.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.051 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.