diff --git a/src/main/java/com/alibaba/druid/filter/FilterEventAdapter.java b/src/main/java/com/alibaba/druid/filter/FilterEventAdapter.java index 1dab2dc312..2e7585cd25 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterEventAdapter.java +++ b/src/main/java/com/alibaba/druid/filter/FilterEventAdapter.java @@ -460,7 +460,7 @@ public abstract class FilterEventAdapter extends FilterAdapter { try { statementExecuteQueryBefore(statement, statement.getSql()); - ResultSetProxy resultSet = super.preparedStatement_executeQuery(chain, statement); + ResultSetProxy resultSet = chain.preparedStatement_executeQuery(statement); statementExecuteQueryAfter(statement, statement.getSql(), resultSet); diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index f1839236ef..3562700a5c 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -526,10 +526,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { out.writeObject(value); } else if (value instanceof InputStream) { out.writeString(""); - } else if (value instanceof Clob) { - out.writeString(""); } else if (value instanceof NClob) { out.writeString(""); + } else if (value instanceof Clob) { + out.writeString(""); } else if (value instanceof Blob) { out.writeString(""); } else { diff --git a/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java b/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java index ff69946319..14e4f0cc96 100644 --- a/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java +++ b/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java @@ -45,7 +45,7 @@ public class MockPreparedStatement extends PreparedStatementBase implements Mock MockConnection conn = getConnection(); if (conn != null && conn.getDriver() != null) { - return getConnection().getDriver().createResultSet(this); + return conn.getDriver().executeQuery(this, sql); } if (conn != null) { diff --git a/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java b/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java index 14d348acf9..f6d1b4ed66 100644 --- a/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java +++ b/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java @@ -6,6 +6,9 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.List; +import org.apache.derby.iapi.types.SQLVarchar; + +import com.alibaba.druid.mock.MockPreparedStatement; import com.alibaba.druid.mock.MockResultSet; import com.alibaba.druid.mock.MockResultSetMetaData; import com.alibaba.druid.mock.MockStatementBase; @@ -19,6 +22,7 @@ import com.alibaba.druid.sql.ast.expr.SQLNCharExpr; import com.alibaba.druid.sql.ast.expr.SQLNullExpr; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectItem; @@ -138,9 +142,17 @@ public class MySqlMockExecuteHandlerImpl implements MockExecuteHandler { } else { throw new SQLException("TODO"); } - + } else if (expr instanceof SQLVariantRefExpr) { + SQLVariantRefExpr varExpr = (SQLVariantRefExpr) expr; + int varIndex = varExpr.getIndex(); + if (statement instanceof MockPreparedStatement) { + MockPreparedStatement mockPstmt = (MockPreparedStatement) statement; + row[i] = mockPstmt.getParameters().get(varIndex); + } else { + row[i] = null; + } } else { - throw new SQLException("TODO"); + row[i] = null; } metaData.getColumns().add(column); diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterBuildSlowParameterTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterBuildSlowParameterTest.java new file mode 100644 index 0000000000..e56932b8e5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterBuildSlowParameterTest.java @@ -0,0 +1,227 @@ +package com.alibaba.druid.bvt.filter; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Time; +import java.sql.Types; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; +import org.nutz.lang.util.ByteInputStream; + +import com.alibaba.druid.mock.MockBlob; +import com.alibaba.druid.mock.MockClob; +import com.alibaba.druid.mock.MockDriver; +import com.alibaba.druid.mock.MockNClob; +import com.alibaba.druid.mock.MockRowId; +import com.alibaba.druid.mock.MockStatementBase; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.stat.JdbcSqlStat; +import com.alibaba.druid.support.json.JSONUtils; +import com.alibaba.druid.util.JdbcUtils; + +public class StatFilterBuildSlowParameterTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setFilters("stat"); + dataSource.setTestOnBorrow(false); + dataSource.setConnectionProperties("druid.stat.slowSqlMillis=1"); + + MockDriver driver = new MockDriver() { + + public ResultSet executeQuery(MockStatementBase stmt, String sql) throws SQLException { + try { + Thread.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return super.executeQuery(stmt, sql); + } + }; + + dataSource.setDriver(driver); + + dataSource.init(); + } + + protected void tearDown() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_buildSlowSql() throws Exception { + long currentMillis = System.currentTimeMillis(); + String sql = "select ?, ?, ?, ?, ?"; + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(System.currentTimeMillis()); + String dateText = dateFormat.format(date); + + { + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + + stmt.setBoolean(1, true); + stmt.setInt(2, 123); + stmt.setLong(3, 10001); + stmt.setTimestamp(4, new java.sql.Timestamp(currentMillis)); + stmt.setDate(5, new java.sql.Date(currentMillis)); + + ResultSet rs = stmt.executeQuery(); + rs.close(); + + stmt.close(); + + conn.close(); + + // ////// + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + Assert.assertNotNull(sqlStat); + + String slowParameters = sqlStat.getLastSlowParameters(); + Assert.assertNotNull(slowParameters); + + List parameters = (List) JSONUtils.parse(slowParameters); + Assert.assertEquals(5, parameters.size()); + + Assert.assertEquals(true, parameters.get(0)); + Assert.assertEquals(123, parameters.get(1)); + Assert.assertEquals(10001, parameters.get(2)); + Assert.assertEquals(dateText, parameters.get(3)); + Assert.assertEquals(dateText, parameters.get(4)); + } + + currentMillis = System.currentTimeMillis(); + date = new Date(System.currentTimeMillis()); + dateText = dateFormat.format(date); + { + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + + stmt.setBoolean(1, false); + stmt.setInt(2, 234); + stmt.setLong(3, 10002); + stmt.setTimestamp(4, new java.sql.Timestamp(currentMillis)); + stmt.setDate(5, new java.sql.Date(currentMillis)); + + ResultSet rs = stmt.executeQuery(); + rs.close(); + + stmt.close(); + + conn.close(); + + // ////// + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + Assert.assertNotNull(sqlStat); + + String slowParameters = sqlStat.getLastSlowParameters(); + Assert.assertNotNull(slowParameters); + + List parameters = (List) JSONUtils.parse(slowParameters); + Assert.assertEquals(5, parameters.size()); + + Assert.assertEquals(false, parameters.get(0)); + Assert.assertEquals(234, parameters.get(1)); + Assert.assertEquals(10002, parameters.get(2)); + Assert.assertEquals(dateText, parameters.get(3)); + Assert.assertEquals(dateText, parameters.get(4)); + } + + { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < 10; ++i) { + buf.append("abcdefghijklmnABCDEFGHIJKLMN1234567890!@#$%^&*("); + } + + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + + stmt.setNull(1, Types.VARCHAR); + stmt.setString(2, buf.toString()); + stmt.setClob(3, new MockClob()); + stmt.setNClob(4, new MockNClob()); + stmt.setBlob(5, new MockBlob()); + + ResultSet rs = stmt.executeQuery(); + rs.close(); + + stmt.close(); + + conn.close(); + + // ////// + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + Assert.assertNotNull(sqlStat); + + String slowParameters = sqlStat.getLastSlowParameters(); + Assert.assertNotNull(slowParameters); + + List parameters = (List) JSONUtils.parse(slowParameters); + Assert.assertEquals(5, parameters.size()); + + Assert.assertEquals(null, parameters.get(0)); + Assert.assertEquals(buf.substring(0, 97) + "...", parameters.get(1)); + Assert.assertEquals("", parameters.get(2)); + Assert.assertEquals("", parameters.get(3)); + Assert.assertEquals("", parameters.get(4)); + } + { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < 10; ++i) { + buf.append("中国abcdefghijklmnABCDEFGHIJKLMN1234567890!@#$%^&*("); + } + + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + + stmt.setBinaryStream(1, new ByteInputStream(new byte[0])); + stmt.setString(2, buf.toString()); + stmt.setTime(3, new Time(currentMillis)); + stmt.setBigDecimal(4, new BigDecimal("56789.123")); + stmt.setRowId(5, new MockRowId()); + + ResultSet rs = stmt.executeQuery(); + rs.close(); + + stmt.close(); + + conn.close(); + + // ////// + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + Assert.assertNotNull(sqlStat); + + String slowParameters = sqlStat.getLastSlowParameters(); + Assert.assertNotNull(slowParameters); + + List parameters = (List) JSONUtils.parse(slowParameters); + Assert.assertEquals(5, parameters.size()); + + Assert.assertEquals("", parameters.get(0)); + Assert.assertEquals(buf.substring(0, 97) + "...", parameters.get(1)); + Assert.assertEquals(dateText, parameters.get(2)); + Assert.assertEquals(56789.123, parameters.get(3)); + Assert.assertEquals("", parameters.get(4)); + } + } +}