Bug #51666 StatementInterceptors don't bypass original statement
Submitted: 2 Mar 2010 23:42 Modified: 3 Mar 2010 14:21
Reporter: Todd Farmer (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:5.1.12 OS:Any
Assigned to: Mark Matthews CPU Architecture:Any

[2 Mar 2010 23:42] Todd Farmer
Description:
When a StatementInterceptor is used and an alternate ResultSet is returned from preProcess(), the original statement is still executed, regardless.

How to repeat:
Test case to be attached.

Suggested fix:
Bypass execution of original Statement when non-null ResultSet is returned.
[3 Mar 2010 0:48] Todd Farmer
Test case:

	public void testBug51666() throws Exception {
		Connection testConn = getConnectionWithProps(
				"statementInterceptors=" + IncrementStatementCountInterceptor.class.getName());
		createTable("testStatementInterceptorCount", "(field1 int)");
		this.stmt.executeUpdate("INSERT INTO testStatementInterceptorCount VALUES (0)");
		ResultSet rs = testConn.createStatement().executeQuery("SHOW SESSION STATUS LIKE 'Com_select'" );
		rs.next();
		int s = rs.getInt(2);
		testConn.createStatement().executeQuery("SELECT 1");
		rs = testConn.createStatement().executeQuery("SHOW SESSION STATUS LIKE 'Com_select'" );
		rs.next();
		assertEquals(s+ 1, rs.getInt(2));
		
	}

		
	public static class IncrementStatementCountInterceptor implements StatementInterceptorV2{
		public void destroy() {}

		public boolean executeTopLevelOnly() {
			return false;
		}

		public void init(com.mysql.jdbc.Connection conn, Properties props)
				throws SQLException {}

		public ResultSetInternalMethods postProcess(String sql,
				com.mysql.jdbc.Statement interceptedStatement,
				ResultSetInternalMethods originalResultSet,
				com.mysql.jdbc.Connection connection, int warningCount,
				boolean noIndexUsed, boolean noGoodIndexUsed,
				SQLException statementException) throws SQLException {
			return null;
		}

		public ResultSetInternalMethods preProcess(String sql,
				com.mysql.jdbc.Statement interceptedStatement,
				com.mysql.jdbc.Connection conn) throws SQLException {
			java.sql.Statement test = conn.createStatement();
			if(sql.equals("SELECT 1")){
				return (ResultSetInternalMethods) test.executeQuery("/* execute this, not the original */ SELECT 1");
			}
			return null;
		}
		
	}
[3 Mar 2010 0:51] Todd Farmer
Verified fix by Mark Matthews in r909 using test case.  Pushed test case and CHANGES updates in r910.
[3 Mar 2010 14:21] Tony Bedford
An entry has been added to the 5.1.13 changelog:

When a StatementInterceptor was used and an alternate ResultSet was returned from preProcess(), the original statement was still executed.