Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
mvn --batch-mode --update-snapshots -q -DskipTests install
cd clickhouse-benchmark
mvn --batch-mode --update-snapshots install
java -jar target/benchmarks.jar -rf text -p client=clickhouse-jdbc Basic
java -DclickhouseVersion="21.3" -jar target/benchmarks.jar -rf text -p client=clickhouse-jdbc Basic
echo "BENCHMARK_REPORT<<EOF" >> $GITHUB_ENV
cat jmh-result.text >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
Expand Down Expand Up @@ -110,7 +110,7 @@ jobs:
run: |
mvn --batch-mode --update-snapshots -DskipTests -pl clickhouse-benchmark -am package
cd clickhouse-benchmark
java -jar target/benchmarks.jar -rf json ${{ github.event.inputs.options }} > output.txt
java -DclickhouseVersion="21.3" -jar target/benchmarks.jar -rf json ${{ github.event.inputs.options }} > output.txt
echo "BENCHMARK_REPORT<<EOF" >> $GITHUB_ENV
tail -n +$(grep -n '^REMEMBER:' output.txt | tail -1 | awk -F: '{print $1+6}') output.txt | head -n -2 | grep -v ':·' >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ target/
**/parser/ClickHouseSqlParserTokenManager.java
**/parser/Token*.java
**/parser/ParseException.java
jmh-result.*

# Shell scripts
*.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ public void doSetup(ServerState serverState) throws Exception {
serverState.getUser(), serverState.getPassword()), new Properties());

try (Statement s = conn.createStatement()) {
s.execute(
"create table if not exists test_insert(i Nullable(UInt64), s Nullable(String), t Nullable(DateTime))engine=Memory");
s.execute("create table if not exists system.test_insert(i Nullable(UInt64), s Nullable(String), t Nullable(DateTime))engine=Memory");
}
} catch (SQLException e) {
e.printStackTrace();
Expand All @@ -43,9 +42,9 @@ public void doSetup(ServerState serverState) throws Exception {
}

@TearDown(Level.Trial)
public void doTearDown() throws SQLException {
public void doTearDown(ServerState serverState) throws SQLException {
try (Statement s = conn.createStatement()) {
s.execute("drop table if exists test_insert");
s.execute("drop table if exists system.test_insert");
}
conn.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public int insert10kUInt64Rows(ClientState state) throws Throwable {
final int rows = 10000;
final int num = new Random().nextInt(rows);

return executeInsert(state, "insert into test_insert(i) values(?)", new Enumeration<Object[]>() {
return executeInsert(state, "insert into system.test_insert(i) values(?)", new Enumeration<Object[]>() {
int counter = 0;

@Override
Expand All @@ -39,7 +39,7 @@ public int insert10kStringRows(ClientState state) throws Throwable {
final int rows = 10000;
final int num = new Random().nextInt(rows);

return executeInsert(state, "insert into test_insert(s) values(?)", new Enumeration<Object[]>() {
return executeInsert(state, "insert into system.test_insert(s) values(?)", new Enumeration<Object[]>() {
int counter = 0;

@Override
Expand All @@ -59,7 +59,7 @@ public int insert10kTimestampRows(ClientState state) throws Throwable {
final int rows = 10000;
final int num = new Random().nextInt(rows);

return executeInsert(state, "insert into test_insert(t) values(?)", new Enumeration<Object[]>() {
return executeInsert(state, "insert into system.test_insert(t) values(?)", new Enumeration<Object[]>() {
int counter = 0;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLSyntaxErrorException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
Expand All @@ -31,22 +30,22 @@
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.clickhouse.jdbc.parser.ClickHouseSqlStatement;
import ru.yandex.clickhouse.jdbc.parser.StatementType;

import ru.yandex.clickhouse.response.ClickHouseResponse;
import ru.yandex.clickhouse.settings.ClickHouseProperties;
import ru.yandex.clickhouse.settings.ClickHouseQueryParam;
import ru.yandex.clickhouse.util.ClickHouseArrayUtil;
import ru.yandex.clickhouse.util.ClickHouseValueFormatter;

public class ClickHousePreparedStatementImpl extends ClickHouseStatementImpl implements ClickHousePreparedStatement {
private static final Logger log = LoggerFactory.getLogger(ClickHousePreparedStatementImpl.class);

static final String PARAM_MARKER = "?";
static final String NULL_MARKER = "\\N";
Expand Down Expand Up @@ -95,18 +94,19 @@ public void clearParameters() {

@Override
public ClickHouseResponse executeQueryClickhouseResponse() throws SQLException {
return super.executeQueryClickhouseResponse(buildSql());
return executeQueryClickhouseResponse(buildSql(), null, null);
}

@Override
public ClickHouseResponse executeQueryClickhouseResponse(Map<ClickHouseQueryParam, String> additionalDBParams) throws SQLException {
return super.executeQueryClickhouseResponse(buildSql(), additionalDBParams);
return executeQueryClickhouseResponse(buildSql(), additionalDBParams, null);
}

private String buildSql() throws SQLException {
private ClickHouseSqlStatement buildSql() throws SQLException {
if (sqlParts.size() == 1) {
return sqlParts.get(0);
return new ClickHouseSqlStatement(sqlParts.get(0), parsedStmt.getStatementType());
}

checkBinded();
StringBuilder sb = new StringBuilder(sqlParts.get(0));
for (int i = 1, p = 0; i < sqlParts.size(); i++) {
Expand All @@ -120,7 +120,7 @@ private String buildSql() throws SQLException {
}
sb.append(sqlParts.get(i));
}
return sb.toString();
return new ClickHouseSqlStatement(sb.toString(), parsedStmt.getStatementType());
}

private void checkBinded() throws SQLException {
Expand All @@ -135,32 +135,34 @@ private void checkBinded() throws SQLException {

@Override
public boolean execute() throws SQLException {
return super.execute(buildSql());
return executeQueryStatement(buildSql(), null, null, null) != null;
}

@Override
public ResultSet executeQuery() throws SQLException {
return super.executeQuery(buildSql());
return executeQueryStatement(buildSql(), null, null, null);
}

@Override
public void clearBatch() throws SQLException {
batchRows.clear();
super.clearBatch();

batchRows = new ArrayList<>();
}

@Override
public ResultSet executeQuery(Map<ClickHouseQueryParam, String> additionalDBParams) throws SQLException {
return super.executeQuery(buildSql(), additionalDBParams);
return executeQuery(additionalDBParams, null);
}

@Override
public ResultSet executeQuery(Map<ClickHouseQueryParam, String> additionalDBParams, List<ClickHouseExternalData> externalData) throws SQLException {
return super.executeQuery(buildSql(), additionalDBParams, externalData);
return executeQueryStatement(buildSql(), additionalDBParams, externalData, null);
}

@Override
public int executeUpdate() throws SQLException {
return super.executeUpdate(buildSql());
return executeStatement(buildSql(), null, null, null);
}

private void setBind(int parameterIndex, String bind, boolean quote) {
Expand Down Expand Up @@ -318,9 +320,18 @@ public void setObject(int parameterIndex, Object x) throws SQLException {
}
}

@Override
public void addBatch(String sql) throws SQLException {
throw new SQLException("addBatch(String) cannot be called in PreparedStatement or CallableStatement!");
}

@Override
public void addBatch() throws SQLException {
batchRows.addAll(buildBatch());
if (parsedStmt.getStatementType() == StatementType.INSERT) {
batchRows.addAll(buildBatch());
} else {
batchStmts.add(buildSql());
}
}

private List<byte[]> buildBatch() throws SQLException {
Expand Down Expand Up @@ -357,22 +368,27 @@ public int[] executeBatch() throws SQLException {
public int[] executeBatch(Map<ClickHouseQueryParam, String> additionalDBParams) throws SQLException {
int valuePosition = -1;
String sql = parsedStmt.getSQL();
if (parsedStmt.getStatementType() == StatementType.INSERT && parsedStmt.hasValues()) {
StatementType type = parsedStmt.getStatementType();
if (type == StatementType.INSERT && parsedStmt.hasValues()) {
valuePosition = parsedStmt.getStartPosition(ClickHouseSqlStatement.KEYWORD_VALUES);
}

if (valuePosition < 0) {
throw new SQLSyntaxErrorException(
"Query must be like 'INSERT INTO [db.]table [(c1, c2, c3)] VALUES (?, ?, ?)'. " +
"Got: " + sql
);
}
String insertSql = sql.substring(0, valuePosition);
BatchHttpEntity entity = new BatchHttpEntity(batchRows);
sendStream(entity, insertSql, additionalDBParams);
int[] result = new int[batchRows.size()];
Arrays.fill(result, 1);
batchRows = new ArrayList<>();
if (valuePosition > 0) { // insert
String insertSql = sql.substring(0, valuePosition);
BatchHttpEntity entity = new BatchHttpEntity(batchRows);
sendStream(entity, insertSql, additionalDBParams);
} else { // others
if (type == StatementType.ALTER_DELETE || type == StatementType.ALTER_UPDATE) {
log.warn("UPDATE and DELETE should be used with caution, as they are expensive operations and not supposed to be used frequently.");
} else {
log.warn("PreparedStatement will slow down non-INSERT queries, so please consider to use Statement instead.");
}
result = super.executeBatch();
}

clearBatch();
return result;
}

Expand Down Expand Up @@ -623,7 +639,7 @@ private String getParameter(int paramIndex) {
@Override
public String asSql() {
try {
return buildSql();
return buildSql().getSQL();
} catch (SQLException e) {
return parsedStmt.getSQL();
}
Expand Down
Loading