Adding a smoke test for server-side cursor support

This commit is contained in:
Jason Fulghum
2025-04-22 16:57:07 -07:00
parent e68b462c1c
commit 371b39bd0c

View File

@@ -1,8 +1,10 @@
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class MySQLConnectorTest {
@@ -62,6 +64,59 @@ public class MySQLConnectorTest {
};
public static void main(String[] args) {
testStatements(args);
testServerSideCursors(args);
System.exit(0);
}
// testServerSideCursors does a simple smoke test with server-side cursors to make sure
// results can be read. Note that we don't test results here; this is just a high level
// smoke test that we can execute server-side cursors logic without the server erroring out.
// This test was added for a regression where server-side cursor logic was getting
// corrupted result set memory and sending invalid data to the client, which caused the
// server to error out and crash the connection. If any errors are encountered, a stack trace
// is printed and this function exits with a non-zero code.
// For more details, see: https://github.com/dolthub/dolt/issues/9125
private static void testServerSideCursors(String[] args) {
String user = args[0];
String port = args[1];
String db = args[2];
try {
String url = "jdbc:mysql://127.0.0.1:" + port + "/" + db +
"?useServerPrepStmts=true&useCursorFetch=true";
Connection conn = DriverManager.getConnection(url, user, "");
executePreparedQuery(conn, "SELECT 1;");
executePreparedQuery(conn, "SELECT database();");
executePreparedQuery(conn, "SHOW COLLATION;");
executePreparedQuery(conn, "SHOW COLLATION;");
executePreparedQuery(conn, "SHOW COLLATION;");
} catch (SQLException ex) {
System.out.println("An error occurred.");
ex.printStackTrace();
System.exit(1);
}
}
// executePreparedQuery executes the specified |query| using |conn| as a prepared statement,
// and uses server-side cursor to fetch results. This method does not do any validation of
// results from the query. It is simply a smoke test to ensure the connection doesn't crash.
private static void executePreparedQuery(Connection conn, String query) throws SQLException {
PreparedStatement stmt = conn.prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY);
stmt.setFetchSize(25); // needed to ensure a server-side cursor is used
ResultSet rs = stmt.executeQuery();
while (rs.next()) {}
rs.close();
stmt.close();
}
// testStatements executes the queries from |queries| and asserts their results from
// |expectedResults|. If any errors are encountered, a stack trace is printed and this
// function exits with a non-zero code.
private static void testStatements(String[] args) {
Connection conn = null;
String user = args[0];
@@ -109,7 +164,6 @@ public class MySQLConnectorTest {
}
}
}
System.exit(0);
} catch (SQLException ex) {
System.out.println("An error occurred.");
ex.printStackTrace();