diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java index 8bcb81b2..f39ab0f2 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java @@ -55,6 +55,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.Pair; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; +import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; @@ -356,18 +357,29 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf *******************************************************************************/ private PreparedStatement createStatement(Connection connection, String sql, QueryInput queryInput) throws SQLException { - if(connection.getClass().getName().startsWith("com.mysql")) + ///////////////////////////////////////////////////////////////////////// + // if we're allowed to use the mysqlResultSetOptimization, and we have // + // the query hint of "potentially large no of results", then check if // + // our backend is indeed mysql, and if so, then apply those settings. // + ///////////////////////////////////////////////////////////////////////// + if(mysqlResultSetOptimizationEnabled && queryInput.hasQueryHint(QueryHint.POTENTIALLY_LARGE_NUMBER_OF_RESULTS)) { - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // if we're allowed to use the mysqlResultSetOptimization, and we have the query hint of "expected large result set", then do it. // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if(mysqlResultSetOptimizationEnabled && queryInput.getQueryHints() != null && queryInput.getQueryHints().contains(QueryHint.POTENTIALLY_LARGE_NUMBER_OF_RESULTS)) + RDBMSBackendMetaData rdbmsBackendMetaData = (RDBMSBackendMetaData) queryInput.getBackend(); + + //////////////////////////////////////////////////////////////////////////// + // todo - remove "aurora" - it's a legacy value here for a staged rollout // + //////////////////////////////////////////////////////////////////////////// + if(RDBMSBackendMetaData.VENDOR_MYSQL.equals(rdbmsBackendMetaData.getVendor()) || RDBMSBackendMetaData.VENDOR_AURORA_MYSQL.equals(rdbmsBackendMetaData.getVendor()) || "aurora".equals(rdbmsBackendMetaData.getVendor())) { - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // mysql "optimization", presumably here - from Result Set section of https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html // - // without this change, we saw ~10 seconds of "wait" time, before results would start to stream out of a large query (e.g., > 1,000,000 rows). // - // with this change, we start to get results immediately, and the total runtime also seems lower... // - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // mysql "optimization", presumably here - from Result Set section of // + // https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html without // + // this change, we saw ~10 seconds of "wait" time, before results would start to stream out of a // + // large query (e.g., > 1,000,000 rows). // + // with this change, we start to get results immediately, and the total runtime also seems lower... // + // perhaps more importantly, without this change, the whole result set goes into memory - but with // + // this change, it is streamed. // + ////////////////////////////////////////////////////////////////////////////////////////////////////// PreparedStatement statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); statement.setFetchSize(Integer.MIN_VALUE); return (statement); diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/ConnectionManager.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/ConnectionManager.java index 8068e725..084e5df1 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/ConnectionManager.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/ConnectionManager.java @@ -150,8 +150,11 @@ public class ConnectionManager return switch(backend.getVendor()) { - case "mysql", "aurora" -> "com.mysql.cj.jdbc.Driver"; - case "h2" -> "org.h2.Driver"; + //////////////////////////////////////////////////////////////////////////// + // todo - remove "aurora" - it's a legacy value here for a staged rollout // + //////////////////////////////////////////////////////////////////////////// + case RDBMSBackendMetaData.VENDOR_MYSQL, RDBMSBackendMetaData.VENDOR_AURORA_MYSQL, "aurora" -> "com.mysql.cj.jdbc.Driver"; + case RDBMSBackendMetaData.VENDOR_H2 -> "org.h2.Driver"; default -> throw (new IllegalStateException("We do not know what jdbc driver to use for vendor name [" + backend.getVendor() + "]. Try setting jdbcDriverClassName in your backend meta data.")); }; } @@ -170,11 +173,17 @@ public class ConnectionManager return switch(backend.getVendor()) { - // TODO aws-mysql-jdbc driver not working when running on AWS + //////////////////////////////////////////////////////////////// + // TODO aws-mysql-jdbc driver not working when running on AWS // + //////////////////////////////////////////////////////////////// // jdbcURL = "jdbc:mysql:aws://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=CONVERT_TO_NULL"; - case "aurora" -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=false"; - case "mysql" -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull"; - case "h2" -> "jdbc:h2:" + backend.getHostName() + ":" + backend.getDatabaseName() + ";MODE=MySQL;DB_CLOSE_DELAY=-1"; + + //////////////////////////////////////////////////////////////////////////// + // todo - remove "aurora" - it's a legacy value here for a staged rollout // + //////////////////////////////////////////////////////////////////////////// + case RDBMSBackendMetaData.VENDOR_AURORA_MYSQL, "aurora" -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=false"; + case RDBMSBackendMetaData.VENDOR_MYSQL -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull"; + case RDBMSBackendMetaData.VENDOR_H2 -> "jdbc:h2:" + backend.getHostName() + ":" + backend.getDatabaseName() + ";MODE=MySQL;DB_CLOSE_DELAY=-1"; default -> throw new IllegalArgumentException("Unsupported rdbms backend vendor: " + backend.getVendor()); }; } diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java index aa93d363..110db12d 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java @@ -49,6 +49,13 @@ public class RDBMSBackendMetaData extends QBackendMetaData private RDBMSBackendMetaData readOnlyBackendMetaData; + /////////////////////////////////////////////////////////// + // define well-known (and fully supported) vendor values // + /////////////////////////////////////////////////////////// + public static final String VENDOR_MYSQL = "mysql"; + public static final String VENDOR_H2 = "h2"; + public static final String VENDOR_AURORA_MYSQL = "aurora-mysql"; + /*******************************************************************************