diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnection.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnection.java index 7454d1a09..78a9cb12f 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnection.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnection.java @@ -6,10 +6,6 @@ public interface ClickHouseConnection extends Connection { - - @Deprecated - ClickHouseStatement createClickHouseStatement() throws SQLException; - TimeZone getServerTimeZone(); TimeZone getTimeZone(); diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java index 4c557511a..6ec960ca4 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java @@ -122,12 +122,6 @@ public ClickHouseStatement createStatement(int resultSetType) throws SQLExceptio resultSetType)); } - @Deprecated - @Override - public ClickHouseStatement createClickHouseStatement() throws SQLException { - return createStatement(); - } - @Override public TimeZone getTimeZone() { return timezone; diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java index 27d4e37ec..9a384d5dc 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java @@ -51,11 +51,9 @@ public class ClickHousePreparedStatementImpl extends ClickHouseStatementImpl imp static final String PARAM_MARKER = "?"; static final String NULL_MARKER = "\\N"; - private static final Pattern VALUES = Pattern.compile("(?i)VALUES[\\s]*\\("); - private final TimeZone dateTimeZone; private final TimeZone dateTimeTimeZone; - private final String sql; + private final ClickHouseSqlStatement parsedStmt; private final List sqlParts; private final ClickHousePreparedStatementParameter[] binds; private final List> parameterList; @@ -67,9 +65,14 @@ public ClickHousePreparedStatementImpl(CloseableHttpClient client, TimeZone serverTimeZone, int resultSetType) throws SQLException { super(client, connection, properties, resultSetType); - parseSingleStatement(sql); + parseSqlStatements(sql); + + if (parsedStmts.length != 1) { + throw new IllegalArgumentException("Only single statement is supported"); + } + + parsedStmt = parsedStmts[0]; - this.sql = sql; PreparedStatementParser parser = PreparedStatementParser.parse(sql, parsedStmt.getEndPosition(ClickHouseSqlStatement.KEYWORD_VALUES)); this.parameterList = parser.getParameters(); @@ -353,13 +356,9 @@ public int[] executeBatch() throws SQLException { @Override public int[] executeBatch(Map additionalDBParams) throws SQLException { int valuePosition = -1; + String sql = parsedStmt.getSQL(); if (parsedStmt.getStatementType() == StatementType.INSERT && parsedStmt.hasValues()) { valuePosition = parsedStmt.getStartPosition(ClickHouseSqlStatement.KEYWORD_VALUES); - } else { - Matcher matcher = VALUES.matcher(sql); - if (matcher.find()) { - valuePosition = matcher.start(); - } } if (valuePosition < 0) { @@ -443,7 +442,7 @@ public ResultSetMetaData getMetaData() throws SQLException { return currentResult.getMetaData(); } - if (!parsedStmt.isQuery() || (!parsedStmt.isRecognized() && !isSelect(sql))) { + if (!parsedStmt.isQuery()) { return null; } ResultSet myRs = executeQuery(Collections.singletonMap( @@ -626,7 +625,7 @@ public String asSql() { try { return buildSql(); } catch (SQLException e) { - return sql; + return parsedStmt.getSQL(); } } } diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatement.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatement.java index 80dc0971c..695d9378c 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatement.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatement.java @@ -74,7 +74,7 @@ ResultSet executeQuery(String sql, /** * Returns extended write-API, which simplifies uploading larger files or - * data streams + * data streams. * * @return a new {@link Writer} builder object which can be used to * construct a request to the server diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java index dcc59b7f6..c182e4075 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java @@ -14,8 +14,8 @@ import java.util.EnumMap; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.TimeZone; import java.util.UUID; import org.apache.http.Header; @@ -40,7 +40,6 @@ import ru.yandex.clickhouse.except.ClickHouseExceptionSpecifier; import ru.yandex.clickhouse.jdbc.parser.ClickHouseSqlParser; import ru.yandex.clickhouse.jdbc.parser.ClickHouseSqlStatement; -import ru.yandex.clickhouse.jdbc.parser.StatementType; import ru.yandex.clickhouse.response.ClickHouseLZ4Stream; import ru.yandex.clickhouse.response.ClickHouseResponse; import ru.yandex.clickhouse.response.ClickHouseResponseSummary; @@ -86,7 +85,7 @@ public class ClickHouseStatementImpl extends ConfigurableApi 0) { + stmt = parsedStmts[parsedStmts.length - 1]; } - if (this.parsedStmt.isIdemponent()) { - httpContext.setAttribute("is_idempotent", Boolean.TRUE); - } else { - httpContext.removeAttribute("is_idempotent"); + return Objects.requireNonNull(stmt); + } + + protected void setLastStatement(ClickHouseSqlStatement stmt) { + if (parsedStmts != null && parsedStmts.length > 0) { + parsedStmts[parsedStmts.length - 1] = Objects.requireNonNull(stmt); } } - @Deprecated - private void parseSingleStatement(String sql, ClickHouseFormat preferredFormat) throws SQLException { - parseSingleStatement(sql); + protected ClickHouseSqlStatement[] parseSqlStatements(String sql) throws SQLException { + parsedStmts = ClickHouseSqlParser.parse(sql, properties); + + if (parsedStmts == null || parsedStmts.length == 0) { + // should never happen + throw new IllegalArgumentException("Failed to parse given SQL: " + sql); + } + + return parsedStmts; + } + + protected ClickHouseSqlStatement parseSqlStatements( + String sql, ClickHouseFormat preferredFormat, Map additionalDBParams) + throws SQLException { + parseSqlStatements(sql); + + // enable session when we have more than one statement + if (additionalDBParams != null && parsedStmts.length > 1 && properties.getSessionId() == null) { + additionalDBParams.put(ClickHouseQueryParam.SESSION_ID, UUID.randomUUID().toString()); + } + + ClickHouseSqlStatement lastStmt = getLastStatement(); - if (parsedStmt.isQuery() && !parsedStmt.hasFormat()) { + if (lastStmt.isQuery() && !lastStmt.hasFormat()) { String format = preferredFormat.name(); Map positions = new HashMap<>(); - positions.putAll(parsedStmt.getPositions()); + positions.putAll(lastStmt.getPositions()); positions.put(ClickHouseSqlStatement.KEYWORD_FORMAT, sql.length()); - sql = new StringBuilder(parsedStmt.getSQL()).append("\nFORMAT ").append(format).append(';') - .toString(); - parsedStmt = new ClickHouseSqlStatement(sql, parsedStmt.getStatementType(), - parsedStmt.getCluster(), parsedStmt.getDatabase(), parsedStmt.getTable(), - format, parsedStmt.getOutfile(), parsedStmt.getParameters(), positions); + sql = new StringBuilder(lastStmt.getSQL()).append("\nFORMAT ").append(format).toString(); + lastStmt = new ClickHouseSqlStatement(sql, lastStmt.getStatementType(), + lastStmt.getCluster(), lastStmt.getDatabase(), lastStmt.getTable(), + format, lastStmt.getOutfile(), lastStmt.getParameters(), positions); + setLastStatement(lastStmt); } + + return lastStmt; } public ClickHouseStatementImpl(CloseableHttpClient client, ClickHouseConnection connection, @@ -175,22 +187,13 @@ public ResultSet executeQuery(String sql, } else { additionalDBParams = new EnumMap<>(additionalDBParams); } + // FIXME respect the value set in additionalDBParams? additionalDBParams.put(ClickHouseQueryParam.EXTREMES, "0"); - parseSingleStatement(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes); - if (!parsedStmt.isRecognized() && isSelect(sql)) { - Map positions = new HashMap<>(); - String dbName = extractDBName(sql); - String tableName = extractTableName(sql); - if (extractWithTotals(sql)) { - positions.put(ClickHouseSqlStatement.KEYWORD_TOTALS, 1); - } - parsedStmt = new ClickHouseSqlStatement(clickhousifySql(sql), StatementType.SELECT, - null, dbName, tableName, null, null, null, positions); - // httpContext.setAttribute("is_idempotent", Boolean.TRUE); - } + parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, additionalDBParams); - InputStream is = getInputStream(sql, additionalDBParams, externalData, additionalRequestParams); + InputStream is = getLastInputStream(additionalDBParams, externalData, additionalRequestParams); + ClickHouseSqlStatement parsedStmt = getLastStatement(); try { if (parsedStmt.isQuery()) { @@ -239,17 +242,16 @@ public ClickHouseResponse executeQueryClickhouseResponse(String sql, Map additionalDBParams, Map additionalRequestParams) throws SQLException { - parseSingleStatement(sql, ClickHouseFormat.JSONCompact); - if (parsedStmt.isRecognized()) { - sql = parsedStmt.getSQL(); + if (additionalDBParams == null || additionalDBParams.isEmpty()) { + additionalDBParams = new EnumMap<>(ClickHouseQueryParam.class); } else { - sql = addFormatIfAbsent(sql, ClickHouseFormat.JSONCompact); + additionalDBParams = new EnumMap<>(additionalDBParams); } - - try (InputStream is = properties.isCompress() - ? new ClickHouseLZ4Stream(getInputStream(sql, additionalDBParams, null, additionalRequestParams)) - : getInputStream(sql, additionalDBParams, null, additionalRequestParams)) { - return Jackson.getObjectMapper().readValue(is, ClickHouseResponse.class); + parseSqlStatements(sql, ClickHouseFormat.JSONCompact, additionalDBParams); + + try (InputStream is = getLastInputStream(additionalDBParams, null, additionalRequestParams)) { + return Jackson.getObjectMapper().readValue( + properties.isCompress() ? new ClickHouseLZ4Stream(is) : is, ClickHouseResponse.class); } catch (IOException e) { throw new RuntimeException(e); } @@ -267,28 +269,24 @@ public ClickHouseRowBinaryInputStream executeQueryClickhouseRowBinaryStream(Stri @Override public ClickHouseRowBinaryInputStream executeQueryClickhouseRowBinaryStream(String sql, Map additionalDBParams, Map additionalRequestParams) throws SQLException { - parseSingleStatement(sql, ClickHouseFormat.RowBinary); - if (parsedStmt.isRecognized()) { - sql = parsedStmt.getSQL(); + if (additionalDBParams == null || additionalDBParams.isEmpty()) { + additionalDBParams = new EnumMap<>(ClickHouseQueryParam.class); } else { - sql = addFormatIfAbsent(sql, ClickHouseFormat.RowBinary); - if (isSelect(sql)) { - parsedStmt = new ClickHouseSqlStatement(sql, StatementType.SELECT); - // httpContext.setAttribute("is_idempotent", Boolean.TRUE); - } else { - parsedStmt = new ClickHouseSqlStatement(sql, StatementType.UNKNOWN); - } + additionalDBParams = new EnumMap<>(additionalDBParams); } + parseSqlStatements(sql, ClickHouseFormat.RowBinary, additionalDBParams); - InputStream is = getInputStream( - sql, + InputStream is = getLastInputStream( additionalDBParams, null, additionalRequestParams ); + ClickHouseSqlStatement parsedStmt = getLastStatement(); + try { if (parsedStmt.isQuery()) { currentUpdateCount = -1; + // FIXME get server timezone? currentRowBinaryResult = new ClickHouseRowBinaryInputStream(properties.isCompress() ? new ClickHouseLZ4Stream(is) : is, getConnection().getTimeZone(), properties); return currentRowBinaryResult; @@ -313,9 +311,10 @@ public ClickHouseRowBinaryInputStream executeQueryClickhouseRowBinaryStream(Stri @Override public int executeUpdate(String sql) throws SQLException { - parseSingleStatement(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes); + Map additionalDBParams = new EnumMap<>(ClickHouseQueryParam.class); + parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, additionalDBParams); - try (InputStream is = getInputStream(sql, null, null, null)) { + try (InputStream is = getLastInputStream(additionalDBParams, null, null)) { //noinspection StatementWithEmptyBody } catch (IOException e) { log.error("can not close stream: {}", e.getMessage()); @@ -556,124 +555,34 @@ public ClickHouseResponseSummary getResponseSummary() { return currentSummary; } - @Deprecated - static String clickhousifySql(String sql) { - return addFormatIfAbsent(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes); - } - - /** - * Adding FORMAT TabSeparatedWithNamesAndTypes if not added - * adds format only to select queries - */ - @Deprecated - private static String addFormatIfAbsent(final String sql, ClickHouseFormat format) { - String cleanSQL = sql.trim(); - if (!isSelect(cleanSQL)) { - return cleanSQL; - } - if (ClickHouseFormat.containsFormat(cleanSQL)) { - return cleanSQL; - } - StringBuilder sb = new StringBuilder(); - int idx = cleanSQL.endsWith(";") - ? cleanSQL.length() - 1 - : cleanSQL.length(); - sb.append(cleanSQL, 0, idx) - .append("\nFORMAT ") - .append(format.name()) - .append(';'); - return sb.toString(); - } - - @Deprecated - static boolean isSelect(String sql) { - for (int i = 0; i < sql.length(); i++) { - String nextTwo = sql.substring(i, Math.min(i + 2, sql.length())); - if ("--".equals(nextTwo)) { - i = Math.max(i, sql.indexOf("\n", i)); - } else if ("/*".equals(nextTwo)) { - i = Math.max(i, sql.indexOf("*/", i)); - } else if (Character.isLetter(sql.charAt(i))) { - String trimmed = sql.substring(i, Math.min(sql.length(), Math.max(i, sql.indexOf(" ", i)))); - for (String keyword : selectKeywords){ - if (trimmed.regionMatches(true, 0, keyword, 0, keyword.length())) { - return true; - } + private InputStream getLastInputStream(Map additionalDBParams, + List externalData, Map additionalRequestParams) throws ClickHouseException { + InputStream is = null; + for (int i = 0, len = parsedStmts.length; i < len; i++) { + // TODO skip useless queries to reduce network calls and server load + is = getInputStream(parsedStmts[i], additionalDBParams, externalData, additionalRequestParams); + // TODO multi-resultset + if (i + 1 < len) { + try { + is.close(); + } catch (IOException ioe) { + log.warn("Failed to close stream: {}", ioe.getMessage()); } - return false; } } - return false; - } - - @Deprecated - private String extractTableName(String sql) { - String s = extractDBAndTableName(sql); - if (s.contains(".")) { - return s.substring(s.indexOf(".") + 1); - } else { - return s; - } - } - @Deprecated - private String extractDBName(String sql) { - String s = extractDBAndTableName(sql); - if (s.contains(".")) { - return s.substring(0, s.indexOf(".")); - } else { - return properties.getDatabase(); - } - } - - @Deprecated - private String extractDBAndTableName(String sql) { - if (Utils.startsWithIgnoreCase(sql, "select")) { - String withoutStrings = Utils.retainUnquoted(sql, '\''); - int fromIndex = withoutStrings.indexOf("from"); - if (fromIndex == -1) { - fromIndex = withoutStrings.indexOf("FROM"); - } - if (fromIndex != -1) { - String fromFrom = withoutStrings.substring(fromIndex); - String fromTable = fromFrom.substring("from".length()).trim(); - return fromTable.split(" ")[0]; - } - } - if (Utils.startsWithIgnoreCase(sql, "desc")) { - return "system.columns"; - } - if (Utils.startsWithIgnoreCase(sql, "show")) { - return "system.tables"; - } - return "system.unknown"; - } - - @Deprecated - private boolean extractWithTotals(String sql) { - if (Utils.startsWithIgnoreCase(sql, "select")) { - String withoutStrings = Utils.retainUnquoted(sql, '\''); - return withoutStrings.toLowerCase(Locale.ROOT).contains(" with totals"); - } - return false; + return is; } private InputStream getInputStream( - String sql, + ClickHouseSqlStatement parsedStmt, Map additionalClickHouseDBParams, List externalData, Map additionalRequestParams ) throws ClickHouseException { - boolean ignoreDatabase = false; - if (parsedStmt.isRecognized()) { - sql = parsedStmt.getSQL(); - // TODO consider more scenarios like drop, show etc. - ignoreDatabase = parsedStmt.getStatementType() == StatementType.CREATE - && parsedStmt.containsKeyword(ClickHouseSqlStatement.KEYWORD_DATABASE); - } else { - sql = clickhousifySql(sql); - ignoreDatabase = sql.trim().regionMatches(true, 0, databaseKeyword, 0, databaseKeyword.length()); - } + String sql = parsedStmt.getSQL(); + boolean ignoreDatabase = parsedStmt.isRecognized() && !parsedStmt.isDML(); + log.debug("Executing SQL: {}", sql); additionalClickHouseDBParams = addQueryIdTo( @@ -738,6 +647,12 @@ private InputStream getInputStream( HttpPost post = new HttpPost(uri); post.setEntity(requestEntity); + if (parsedStmt.isIdemponent()) { + httpContext.setAttribute("is_idempotent", Boolean.TRUE); + } else { + httpContext.removeAttribute("is_idempotent"); + } + HttpResponse response = client.execute(post, httpContext); entity = response.getEntity(); checkForErrorAndThrow(entity, response); @@ -784,6 +699,11 @@ URI buildRequestUri( ignoreDatabase ); + // avoid to reuse query id + if (additionalClickHouseDBParams != null) { + additionalClickHouseDBParams.remove(ClickHouseQueryParam.QUERY_ID); + } + return new URIBuilder() .setScheme(properties.getSsl() ? "https" : "http") .setHost(properties.getHost()) @@ -1004,8 +924,8 @@ public void sendStreamSQL(InputStream content, String sql) throws SQLException { void sendStream(Writer writer, HttpEntity content) throws ClickHouseException { HttpEntity entity = null; + // TODO no parser involved so user can execute arbitray statement here try { - URI uri = buildRequestUri(writer.getSql(), null, writer.getAdditionalDBParams(), writer.getRequestParams(), false); uri = followRedirects(uri); @@ -1086,6 +1006,7 @@ private Map addQueryIdTo(Map - * Tries to extract query parameters in a way that is usable for (batched) + * Parser for JDBC SQL Strings. + * + *

Tries to extract query parameters in a way that is usable for (batched) * prepared statements. */ final class PreparedStatementParser { @@ -88,7 +88,7 @@ private void parseSQL(String sql, int valuesEndPosition) { int quotedStart = 0; int partStart = 0; int sqlLength = sql.length(); - for (int i = valuesMode ? endPosition : 0, idxStart = i, idxEnd = i ; i < sqlLength; i++) { + for (int i = valuesMode ? endPosition : 0, idxStart = i, idxEnd = i; i < sqlLength; i++) { char c = sql.charAt(i); if (inSingleLineComment) { if (c == '\n') { diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/response/ClickHouseResultSet.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/response/ClickHouseResultSet.java index 944d06be6..07cac08de 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/response/ClickHouseResultSet.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/response/ClickHouseResultSet.java @@ -137,22 +137,20 @@ private static String[] toStringArray(ByteFragment headerFragment) { } /** - * Check if there is another row + * Check if there is another row. * * @return {@code true} if this result set has another row after the current * cursor position, {@code false} else - * @throws SQLException - * if something goes wrong - * @deprecated prefer to use JDBC API methods, for example {@link #isLast()} - * or simply looping using {@code while (rs.next())} + * @throws SQLException if something goes wrong */ - @Deprecated - public boolean hasNext() throws SQLException { + protected boolean hasNext() throws SQLException { if (nextLine == null && !lastReached) { try { nextLine = bis.next(); - if (nextLine == null || (maxRows != 0 && rowNumber >= maxRows) || (usesWithTotals && nextLine.length() == 0)) { + if (nextLine == null + || (maxRows != 0 && rowNumber >= maxRows) + || (usesWithTotals && nextLine.length() == 0)) { if (usesWithTotals) { if (onTheSeparatorRow()) { totalLine = bis.next(); diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseConnectionSettings.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseConnectionSettings.java index 05028647d..2f9b53568 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseConnectionSettings.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseConnectionSettings.java @@ -27,9 +27,6 @@ public enum ClickHouseConnectionSettings implements DriverPropertyCreator { + " ClickHouse rejects request execution if its time exceeds max_execution_time"), - @Deprecated - KEEP_ALIVE_TIMEOUT("keepAliveTimeout", 30 * 1000, ""), - /** * for ConnectionManager */ @@ -52,8 +49,6 @@ public enum ClickHouseConnectionSettings implements DriverPropertyCreator { "If false, Date returned is a wrapper of a timestamp at start of the day in client timezone. " + "If true - at start of the day in server or use_timezone timezone."), CLIENT_NAME("client_name", "", "client_name or http_user_agent show up in system.query_log table, depending on the protocol you're using."), - @Deprecated - USE_NEW_PARSER("use_new_parser", true, "Whether to use JavaCC based SQL parser or not.") ; private final String key; diff --git a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java index 435a4366f..10da23b81 100644 --- a/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java +++ b/clickhouse-jdbc/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java @@ -17,8 +17,6 @@ public class ClickHouseProperties { private int socketTimeout; private int connectionTimeout; private int dataTransferTimeout; - @Deprecated - private int keepAliveTimeout; private int timeToLiveMillis; private int defaultMaxPerRoute; private int maxTotal; @@ -100,8 +98,6 @@ public class ClickHouseProperties { private Boolean sendProgressInHttpHeaders; private Boolean waitEndOfQuery; private String clientName; - @Deprecated - private boolean useNewParser; public ClickHouseProperties() { this(new Properties()); @@ -115,7 +111,6 @@ public ClickHouseProperties(Properties info) { this.socketTimeout = (Integer)getSetting(info, ClickHouseConnectionSettings.SOCKET_TIMEOUT); this.connectionTimeout = (Integer)getSetting(info, ClickHouseConnectionSettings.CONNECTION_TIMEOUT); this.dataTransferTimeout = (Integer)getSetting(info, ClickHouseConnectionSettings.DATA_TRANSFER_TIMEOUT); - this.keepAliveTimeout = (Integer)getSetting(info, ClickHouseConnectionSettings.KEEP_ALIVE_TIMEOUT); this.timeToLiveMillis = (Integer)getSetting(info, ClickHouseConnectionSettings.TIME_TO_LIVE_MILLIS); this.defaultMaxPerRoute = (Integer)getSetting(info, ClickHouseConnectionSettings.DEFAULT_MAX_PER_ROUTE); this.maxTotal = (Integer)getSetting(info, ClickHouseConnectionSettings.MAX_TOTAL); @@ -134,7 +129,6 @@ public ClickHouseProperties(Properties info) { this.useObjectsInArrays = (Boolean)getSetting(info, ClickHouseConnectionSettings.USE_OBJECTS_IN_ARRAYS); this.useSharedCookieStore = (Boolean)getSetting(info, ClickHouseConnectionSettings.USE_SHARED_COOKIE_STORE); this.clientName = (String)getSetting(info, ClickHouseConnectionSettings.CLIENT_NAME); - this.useNewParser = (Boolean)getSetting(info, ClickHouseConnectionSettings.USE_NEW_PARSER); this.maxParallelReplicas = getSetting(info, ClickHouseQueryParam.MAX_PARALLEL_REPLICAS); this.maxPartitionsPerInsertBlock = getSetting(info, ClickHouseQueryParam.MAX_PARTITIONS_PER_INSERT_BLOCK); @@ -185,7 +179,6 @@ public Properties asProperties() { ret.put(ClickHouseConnectionSettings.SOCKET_TIMEOUT.getKey(), String.valueOf(socketTimeout)); ret.put(ClickHouseConnectionSettings.CONNECTION_TIMEOUT.getKey(), String.valueOf(connectionTimeout)); ret.put(ClickHouseConnectionSettings.DATA_TRANSFER_TIMEOUT.getKey(), String.valueOf(dataTransferTimeout)); - ret.put(ClickHouseConnectionSettings.KEEP_ALIVE_TIMEOUT.getKey(), String.valueOf(keepAliveTimeout)); ret.put(ClickHouseConnectionSettings.TIME_TO_LIVE_MILLIS.getKey(), String.valueOf(timeToLiveMillis)); ret.put(ClickHouseConnectionSettings.DEFAULT_MAX_PER_ROUTE.getKey(), String.valueOf(defaultMaxPerRoute)); ret.put(ClickHouseConnectionSettings.MAX_TOTAL.getKey(), String.valueOf(maxTotal)); @@ -204,8 +197,7 @@ public Properties asProperties() { ret.put(ClickHouseConnectionSettings.USE_OBJECTS_IN_ARRAYS.getKey(), String.valueOf(useObjectsInArrays)); ret.put(ClickHouseConnectionSettings.USE_SHARED_COOKIE_STORE.getKey(), String.valueOf(useSharedCookieStore)); ret.put(ClickHouseConnectionSettings.CLIENT_NAME.getKey(), String.valueOf(clientName)); - ret.put(ClickHouseConnectionSettings.USE_NEW_PARSER.getKey(), String.valueOf(useNewParser)); - + ret.put(ClickHouseQueryParam.MAX_PARALLEL_REPLICAS.getKey(), maxParallelReplicas); ret.put(ClickHouseQueryParam.MAX_PARTITIONS_PER_INSERT_BLOCK.getKey(), maxPartitionsPerInsertBlock); ret.put(ClickHouseQueryParam.TOTALS_MODE.getKey(), totalsMode); @@ -258,7 +250,6 @@ public ClickHouseProperties(ClickHouseProperties properties) { setSocketTimeout(properties.socketTimeout); setConnectionTimeout(properties.connectionTimeout); setDataTransferTimeout(properties.dataTransferTimeout); - setKeepAliveTimeout(properties.keepAliveTimeout); setTimeToLiveMillis(properties.timeToLiveMillis); setDefaultMaxPerRoute(properties.defaultMaxPerRoute); setMaxTotal(properties.maxTotal); @@ -277,7 +268,6 @@ public ClickHouseProperties(ClickHouseProperties properties) { setUseObjectsInArrays(properties.useObjectsInArrays); setUseSharedCookieStore(properties.useSharedCookieStore); setClientName(properties.clientName); - setUseNewParser(properties.useNewParser); setMaxParallelReplicas(properties.maxParallelReplicas); setMaxPartitionsPerInsertBlock(properties.maxPartitionsPerInsertBlock); setTotalsMode(properties.totalsMode); @@ -572,16 +562,6 @@ public void setDataTransferTimeout(int dataTransferTimeout) { this.dataTransferTimeout = dataTransferTimeout; } - @Deprecated - public int getKeepAliveTimeout() { - return keepAliveTimeout; - } - - @Deprecated - public void setKeepAliveTimeout(int keepAliveTimeout) { - this.keepAliveTimeout = keepAliveTimeout; - } - public String getUser() { return user; } @@ -709,16 +689,6 @@ public void setClientName(String clientName) { this.clientName = clientName; } - @Deprecated - public boolean isUseNewParser() { - return useNewParser; - } - - @Deprecated - public void setUseNewParser(boolean useNewParser) { - this.useNewParser = useNewParser; - } - public boolean isUseServerTimeZoneForDates() { return useServerTimeZoneForDates; } diff --git a/clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj b/clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj index 1f03193f7..9c13c8a02 100644 --- a/clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj +++ b/clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj @@ -70,40 +70,6 @@ public class ClickHouseSqlParser { return !(getToken(1).kind == AND && token_source.parentToken == BETWEEN); } - /** - * Parse given SQL. - * - * @deprecated This method will be removed in the near future. - *

- * Use {@link #parse(String, ClickHouseProperties)} instead. - * - * @param sql SQL query - * @param properties properties - * @return parsed SQL statement - */ - public static ClickHouseSqlStatement parseSingleStatement(String sql, ClickHouseProperties properties) { - return parseSingleStatement(sql, properties, null); - } - - /** - * Parse given SQL. - * - * @deprecated This method will be removed in the near future. - *

- * Use {@link #parse(String, ClickHouseProperties, ParseHandler)} instead. - * - * @param sql SQL query - * @param properties properties - * @param handler parse handler - * @return parsed SQL statement - */ - public static ClickHouseSqlStatement parseSingleStatement( - String sql, ClickHouseProperties properties, ParseHandler handler) { - ClickHouseSqlStatement[] stmts = parse(sql, properties, handler); - - return stmts.length == 1 ? stmts[0] : new ClickHouseSqlStatement(sql, StatementType.UNKNOWN); - } - public static ClickHouseSqlStatement[] parse(String sql, ClickHouseProperties properties) { return parse(sql, properties, null); } @@ -116,7 +82,7 @@ public class ClickHouseSqlParser { ClickHouseSqlStatement[] stmts = new ClickHouseSqlStatement[] { new ClickHouseSqlStatement(sql, StatementType.UNKNOWN) }; - if (!properties.isUseNewParser() || sql == null || sql.isEmpty()) { + if (sql == null || sql.isEmpty()) { return stmts; } diff --git a/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/ClickHouseStatementTest.java b/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/ClickHouseStatementTest.java index c5fadca00..bc9058fde 100644 --- a/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/ClickHouseStatementTest.java +++ b/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/ClickHouseStatementTest.java @@ -11,6 +11,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.testng.annotations.Test; +import ru.yandex.clickhouse.domain.ClickHouseFormat; import ru.yandex.clickhouse.settings.ClickHouseProperties; import ru.yandex.clickhouse.settings.ClickHouseQueryParam; @@ -22,41 +23,54 @@ public class ClickHouseStatementTest { @Test public void testClickhousify() throws Exception { + ClickHouseStatementImpl s = new ClickHouseStatementImpl(null, null, null, ResultSet.TYPE_FORWARD_ONLY); String sql = "SELECT ololo FROM ololoed;"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql), "SELECT ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes;"); + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql2 = "SELECT ololo FROM ololoed"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql2), "SELECT ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SELECT ololo FROM ololoed"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql3 = "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql3), "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes"); + sql = "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes"); - String sql4 = "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes;"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql4), "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes;"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed FORMAT TabSeparatedWithNamesAndTypes"); - String sql5 = "SHOW ololo FROM ololoed;"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql5), "SHOW ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SHOW ololo FROM ololoed;"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SHOW ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql6 = " show ololo FROM ololoed;"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql6), "show ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = " show ololo FROM ololoed;"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + " show ololo FROM ololoed\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql7 = "SELECT ololo FROM ololoed \nFORMAT TabSeparatedWithNamesAndTypes"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql7), "SELECT ololo FROM ololoed \nFORMAT TabSeparatedWithNamesAndTypes"); + sql = "SELECT ololo FROM ololoed \nFORMAT TabSeparatedWithNamesAndTypes"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed \nFORMAT TabSeparatedWithNamesAndTypes"); - String sql8 = "SELECT ololo FROM ololoed \n\n FORMAT TabSeparatedWithNamesAndTypes"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql8), "SELECT ololo FROM ololoed \n\n FORMAT TabSeparatedWithNamesAndTypes"); + sql = "SELECT ololo FROM ololoed \n\n FORMAT TabSeparatedWithNamesAndTypes"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed \n\n FORMAT TabSeparatedWithNamesAndTypes"); - String sql9 = "SELECT ololo FROM ololoed\n-- some comments one line"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql9), "SELECT ololo FROM ololoed\n-- some comments one line\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SELECT ololo FROM ololoed\n-- some comments one line"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed\n-- some comments one line\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql10 = "SELECT ololo FROM ololoed\n-- some comments\ntwo line"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql10), "SELECT ololo FROM ololoed\n-- some comments\ntwo line\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SELECT ololo FROM ololoed\n-- some comments\ntwo line"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed\n-- some comments\ntwo line\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql11 = "SELECT ololo FROM ololoed/*\nsome comments\ntwo line*/"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql11), "SELECT ololo FROM ololoed/*\nsome comments\ntwo line*/\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SELECT ololo FROM ololoed/*\nsome comments\ntwo line*/"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed/*\nsome comments\ntwo line*/\nFORMAT TabSeparatedWithNamesAndTypes"); - String sql12 = "SELECT ololo FROM ololoed\n// c style some comments one line"; - assertEquals(ClickHouseStatementImpl.clickhousifySql(sql12), "SELECT ololo FROM ololoed\n// c style some comments one line\nFORMAT TabSeparatedWithNamesAndTypes;"); + sql = "SELECT ololo FROM ololoed\n// c style some comments one line"; + assertEquals(s.parseSqlStatements(sql, ClickHouseFormat.TabSeparatedWithNamesAndTypes, null).getSQL(), + "SELECT ololo FROM ololoed\n// c style some comments one line\nFORMAT TabSeparatedWithNamesAndTypes"); } @@ -174,32 +188,33 @@ public void testAdditionalDBParams() { } @Test - public void testIsSelect() { - assertTrue(ClickHouseStatementImpl.isSelect("SELECT 42")); - assertTrue(ClickHouseStatementImpl.isSelect("select 42")); - assertFalse(ClickHouseStatementImpl.isSelect("selectfoo")); - assertTrue(ClickHouseStatementImpl.isSelect(" SELECT foo")); - assertTrue(ClickHouseStatementImpl.isSelect("WITH foo")); - assertTrue(ClickHouseStatementImpl.isSelect("DESC foo")); - assertTrue(ClickHouseStatementImpl.isSelect("EXISTS foo")); - assertTrue(ClickHouseStatementImpl.isSelect("SHOW foo")); - assertTrue(ClickHouseStatementImpl.isSelect("-- foo\n SELECT 42")); - assertTrue(ClickHouseStatementImpl.isSelect("--foo\n SELECT 42")); - assertFalse(ClickHouseStatementImpl.isSelect("- foo\n SELECT 42")); - assertTrue(ClickHouseStatementImpl.isSelect("/* foo */ SELECT 42")); - assertTrue(ClickHouseStatementImpl.isSelect("/*\n * foo\n*/\n SELECT 42")); - assertFalse(ClickHouseStatementImpl.isSelect("/ foo */ SELECT 42")); - assertFalse(ClickHouseStatementImpl.isSelect("-- SELECT baz\n UPDATE foo")); - assertFalse(ClickHouseStatementImpl.isSelect("/* SELECT baz */\n UPDATE foo")); - assertFalse(ClickHouseStatementImpl.isSelect("/*\n UPDATE foo")); - assertFalse(ClickHouseStatementImpl.isSelect("/*")); - assertFalse(ClickHouseStatementImpl.isSelect("/**/")); - assertFalse(ClickHouseStatementImpl.isSelect(" --")); - assertTrue(ClickHouseStatementImpl.isSelect("explain select 42")); - assertTrue(ClickHouseStatementImpl.isSelect("EXPLAIN select 42")); - assertFalse(ClickHouseStatementImpl.isSelect("--EXPLAIN select 42\n alter")); - assertTrue(ClickHouseStatementImpl.isSelect("--\nEXPLAIN select 42")); - assertTrue(ClickHouseStatementImpl.isSelect("/*test*/ EXPLAIN select 42")); + public void testIsSelect() throws SQLException { + ClickHouseStatementImpl s = new ClickHouseStatementImpl(null, null, null, ResultSet.TYPE_FORWARD_ONLY); + assertTrue(s.parseSqlStatements("SELECT 42")[0].isQuery()); + assertTrue(s.parseSqlStatements("select 42")[0].isQuery()); + assertFalse(s.parseSqlStatements("selectfoo")[0].isQuery()); + assertTrue(s.parseSqlStatements(" SELECT foo")[0].isQuery()); + assertFalse(s.parseSqlStatements("WITH foo")[0].isQuery()); + assertTrue(s.parseSqlStatements("DESC foo")[0].isQuery()); + assertTrue(s.parseSqlStatements("EXISTS foo")[0].isQuery()); + assertTrue(s.parseSqlStatements("SHOW foo")[0].isQuery()); + assertTrue(s.parseSqlStatements("-- foo\n SELECT 42")[0].isQuery()); + assertTrue(s.parseSqlStatements("--foo\n SELECT 42")[0].isQuery()); + assertFalse(s.parseSqlStatements("- foo\n SELECT 42")[0].isQuery()); + assertTrue(s.parseSqlStatements("/* foo */ SELECT 42")[0].isQuery()); + assertTrue(s.parseSqlStatements("/*\n * foo\n*/\n SELECT 42")[0].isQuery()); + assertFalse(s.parseSqlStatements("/ foo */ SELECT 42")[0].isQuery()); + assertFalse(s.parseSqlStatements("-- SELECT baz\n UPDATE foo")[0].isQuery()); + assertFalse(s.parseSqlStatements("/* SELECT baz */\n UPDATE foo")[0].isQuery()); + assertFalse(s.parseSqlStatements("/*\n UPDATE foo")[0].isQuery()); + assertFalse(s.parseSqlStatements("/*")[0].isQuery()); + assertFalse(s.parseSqlStatements("/**/")[0].isQuery()); + assertFalse(s.parseSqlStatements(" --")[0].isQuery()); + assertTrue(s.parseSqlStatements("explain select 42")[0].isQuery()); + assertTrue(s.parseSqlStatements("EXPLAIN select 42")[0].isQuery()); + assertFalse(s.parseSqlStatements("--EXPLAIN select 42\n alter")[0].isQuery()); + assertTrue(s.parseSqlStatements("--\nEXPLAIN select 42")[0].isQuery()); + assertTrue(s.parseSqlStatements("/*test*/ EXPLAIN select 42")[0].isQuery()); } } diff --git a/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseConnectionImplTest.java b/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseConnectionImplTest.java index 07b353c2e..99a7340c8 100644 --- a/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseConnectionImplTest.java +++ b/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseConnectionImplTest.java @@ -75,20 +75,6 @@ public void testOofWrongPassword() throws Exception { assertFailure(createDataSource("oof", "baz")); } - @Test - public void testNewParserOption() throws Exception { - ClickHouseProperties props = new ClickHouseProperties(); - props.setUseNewParser(false); - ClickHouseDataSource ds = ClickHouseContainerForTest.newDataSource(props); - try (Connection conn = ds.getConnection(); Statement s = conn.createStatement(); - ResultSet rs = s.executeQuery("select timezone(), version()");) { - assertTrue(rs.next()); - assertNotNull(rs.getString(1)); - assertNotNull(rs.getString(2)); - assertFalse(rs.next()); - } - } - private static void assertSuccess(DataSource dataSource) throws Exception { Connection connection = dataSource.getConnection(); assertTrue(connection.createStatement().execute("SELECT 1")); diff --git a/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseStatementImplTest.java b/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseStatementImplTest.java index e8203e1a2..9987d7fb9 100644 --- a/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseStatementImplTest.java +++ b/clickhouse-jdbc/src/test/java/ru/yandex/clickhouse/integration/ClickHouseStatementImplTest.java @@ -1,9 +1,10 @@ package ru.yandex.clickhouse.integration; import static org.testng.Assert.assertEquals; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; -import static org.testng.AssertJUnit.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -326,12 +327,12 @@ public void run() { assertNotNull( String.format("it's actually very strange. It seems the query hasn't been executed in %s seconds", timeout), queryId); - assertNull("An exception happened while the query was being executed", exceptionAtomicReference.get()); + assertNull(exceptionAtomicReference.get(), "An exception happened while the query was being executed"); - assertTrue("The query isn't being executed. It seems very strange", checkQuery(queryId, true,10)); + assertTrue(checkQuery(queryId, true, 10), "The query isn't being executed. It seems very strange"); firstStatement.cancel(); - assertTrue("The query is still being executed", checkQuery(queryId, false, 10)); + assertTrue(checkQuery(queryId, false, 10), "The query is still being executed"); firstStatement.close(); thread.interrupt(); @@ -362,14 +363,14 @@ public void run() { thread.setDaemon(true); thread.start(); final long timeout = 10; - assertTrue( - String.format("it's actually very strange. It seems the query hasn't been executed in %s seconds", timeout), - countDownLatch.await(timeout, TimeUnit.SECONDS)); - assertNull("An exception happened while the query was being executed", exceptionAtomicReference.get()); + assertTrue(countDownLatch.await(timeout, TimeUnit.SECONDS), + String.format( + "it's actually very strange. It seems the query hasn't been executed in %s seconds", timeout)); + assertNull(exceptionAtomicReference.get(), "An exception happened while the query was being executed"); - assertTrue("The query isn't being executed. It seems very strange", checkQuery(queryId, true,10)); + assertTrue(checkQuery(queryId, true, 10), "The query isn't being executed. It seems very strange"); firstStatement.cancel(); - assertTrue("The query is still being executed", checkQuery(queryId, false, 10)); + assertTrue(checkQuery(queryId, false, 10), "The query is still being executed"); firstStatement.close(); thread.interrupt(); @@ -409,6 +410,28 @@ public void testInsertQueryUUIDArray() throws SQLException { new UUID[] {UUID.fromString("5ff22319-793d-4e6c-bdc1-916095a5a496")}); } + @Test + public void testMultiStatements() throws SQLException { + try (Statement s = connection.createStatement()) { + String sql = "select 1; select 2"; + try (ResultSet rs = s.executeQuery(sql)) { + assertTrue(rs.next()); + assertEquals(rs.getString(1), "2"); + assertFalse(rs.next()); + } + + assertTrue(s.execute(sql)); + try (ResultSet rs = s.getResultSet()) { + assertNotNull(rs); + assertTrue(rs.next()); + assertEquals(rs.getString(1), "2"); + assertFalse(rs.next()); + } + + assertEquals(s.executeUpdate(sql), 1); + } + } + private static Object readField(Object object, String fieldName, long timeoutSecs) { long start = System.currentTimeMillis(); Object value;