Skip to content

Commit

Permalink
Enhance exception handling along with largeMaxRows and largeUpdateCou…
Browse files Browse the repository at this point in the history
…nt support
  • Loading branch information
zhicwu committed Feb 21, 2022
1 parent 8ff5cdf commit ab09d64
Show file tree
Hide file tree
Showing 10 changed files with 921 additions and 212 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,6 @@ default void setObject(int parameterIndex, Object x, int targetSqlType) throws S
setObject(parameterIndex, x, targetSqlType, 0);
}

@Override
default boolean execute() throws SQLException {
return executeQuery() != null;
}

@Override
default void addBatch(String sql) throws SQLException {
throw SqlExceptionUtils
.unsupportedError("addBatch(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
default void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
String s = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.clickhouse.jdbc;

import java.net.ConnectException;
import java.sql.BatchUpdateException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;

Expand Down Expand Up @@ -76,6 +77,53 @@ public static SQLException handle(Throwable e) {
return new SQLException(cause);
}

public static BatchUpdateException batchUpdateError(Throwable e, long[] updateCounts) {
if (e == null) {
return new BatchUpdateException("Something went wrong when performing batch update", SQL_STATE_CLIENT_ERROR,
0, updateCounts, null);
} else if (e instanceof BatchUpdateException) {
return (BatchUpdateException) e;
} else if (e instanceof ClickHouseException) {
return batchUpdateError(e, updateCounts);
} else if (e instanceof SQLException) {
SQLException sqlExp = (SQLException) e;
return new BatchUpdateException(sqlExp.getMessage(), sqlExp.getSQLState(), sqlExp.getErrorCode(),
updateCounts, null);
}

Throwable cause = e.getCause();
if (e instanceof BatchUpdateException) {
return (BatchUpdateException) e;
} else if (cause instanceof ClickHouseException) {
return batchUpdateError(cause, updateCounts);
} else if (e instanceof SQLException) {
SQLException sqlExp = (SQLException) e;
return new BatchUpdateException(sqlExp.getMessage(), sqlExp.getSQLState(), sqlExp.getErrorCode(),
updateCounts, null);
} else if (cause == null) {
cause = e;
}

return new BatchUpdateException("Unexpected error", SQL_STATE_SQL_ERROR, 0, updateCounts, cause);
}

public static SQLException emptyBatchError() {
return clientError("Please call addBatch method at least once before batch execution");
}

public static BatchUpdateException queryInBatchError(int[] updateCounts) {
return new BatchUpdateException("Query is not allow in batch update", SQL_STATE_CLIENT_ERROR, updateCounts);
}

public static BatchUpdateException queryInBatchError(long[] updateCounts) {
return new BatchUpdateException("Query is not allow in batch update", SQL_STATE_CLIENT_ERROR, 0, updateCounts,
null);
}

public static SQLException undeterminedExecutionError() {
return clientError("Please either call clearBatch() to clean up context first, or use executeBatch() instead");
}

public static SQLException forCancellation(Exception e) {
Throwable cause = e.getCause();
if (cause == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package com.clickhouse.jdbc.internal;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.clickhouse.client.ClickHouseRequest;
import com.clickhouse.jdbc.SqlExceptionUtils;

public abstract class AbstractPreparedStatement extends ClickHouseStatementImpl implements PreparedStatement {
protected AbstractPreparedStatement(ClickHouseConnectionImpl connection, ClickHouseRequest<?> request,
int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
super(connection, request, resultSetType, resultSetConcurrency, resultSetHoldability);
}

protected abstract long[] executeAny(boolean asBatch) throws SQLException;

@Override
public final void addBatch(String sql) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"addBatch(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final boolean execute(String sql) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"execute(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"execute(String, int) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final boolean execute(String sql, int[] columnIndexes) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"execute(String, int[]) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final boolean execute(String sql, String[] columnNames) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"execute(String, String[]) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public long[] executeLargeBatch() throws SQLException {
return executeAny(true);
}

@Override
public final long executeLargeUpdate(String sql) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeLargeUpdate(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeLargeUpdate(String, int) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeLargeUpdate(String, int[]) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeLargeUpdate(String, String[]) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final ResultSet executeQuery(String sql) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeQuery(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final int executeUpdate() throws SQLException {
return (int) executeLargeUpdate();
}

@Override
public final int executeUpdate(String sql) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeUpate(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeUpdate(String, int) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeUpdate(String, int[]) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public final int executeUpdate(String sql, String[] columnNames) throws SQLException {
ensureOpen();

throw SqlExceptionUtils
.unsupportedError(
"executeUpdate(String, String[]) cannot be called in PreparedStatement or CallableStatement!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, int res
clientRequest.write().query(parsedStmt.getSQL(), newQueryId()),
ClickHouseColumn.parse(parsedStmt.getInput()), resultSetType,
resultSetConcurrency, resultSetHoldability);
} else if (!parsedStmt.containsKeyword("SELECT") &&
} else if (!parsedStmt.containsKeyword("SELECT") && !parsedStmt.hasValues() &&
(!parsedStmt.hasFormat() || clientRequest.getFormat().name().equals(parsedStmt.getFormat()))) {
ps = new InputBasedPreparedStatement(this,
clientRequest.write().query(parsedStmt.getSQL(), newQueryId()),
Expand Down
Loading

0 comments on commit ab09d64

Please sign in to comment.