Skip to content

Commit fea9b35

Browse files
committed
Code cleanup. Implemented dummy parameter result set. Drafted prepared stmt metadata
1 parent da90573 commit fea9b35

File tree

12 files changed

+376
-250
lines changed

12 files changed

+376
-250
lines changed

jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.clickhouse.jdbc;
22

3+
import com.clickhouse.client.api.metadata.TableSchema;
34
import com.clickhouse.data.Tuple;
45
import com.clickhouse.jdbc.internal.ExceptionUtils;
6+
import com.clickhouse.jdbc.internal.JdbcUtils;
7+
import com.clickhouse.jdbc.metadata.ParameterMetaDataImpl;
8+
import com.clickhouse.jdbc.metadata.ResultSetMetaDataImpl;
59
import org.slf4j.Logger;
610
import org.slf4j.LoggerFactory;
711

@@ -39,12 +43,7 @@
3943
import java.time.format.DateTimeFormatter;
4044
import java.time.format.DateTimeFormatterBuilder;
4145
import java.time.temporal.ChronoField;
42-
import java.util.ArrayList;
43-
import java.util.Calendar;
44-
import java.util.Collection;
45-
import java.util.GregorianCalendar;
46-
import java.util.List;
47-
import java.util.Map;
46+
import java.util.*;
4847

4948
public class PreparedStatementImpl extends StatementImpl implements PreparedStatement, JdbcV2Wrapper {
5049
private static final Logger LOG = LoggerFactory.getLogger(PreparedStatementImpl.class);
@@ -64,6 +63,11 @@ public class PreparedStatementImpl extends StatementImpl implements PreparedStat
6463
String insertIntoSQL;
6564

6665
StatementType statementType;
66+
67+
private final ParameterMetaData parameterMetaData;
68+
69+
private ResultSetMetaData resultSetMetaData = null;
70+
6771
public PreparedStatementImpl(ConnectionImpl connection, String sql) throws SQLException {
6872
super(connection);
6973
this.originalSql = sql.trim();
@@ -83,7 +87,7 @@ public PreparedStatementImpl(ConnectionImpl connection, String sql) throws SQLEx
8387
} else {
8488
this.parameters = new Object[0];
8589
}
86-
90+
this.parameterMetaData = new ParameterMetaDataImpl(this.parameters.length);
8791
this.defaultCalendar = connection.defaultCalendar;
8892
}
8993

@@ -305,7 +309,30 @@ public void setArray(int parameterIndex, Array x) throws SQLException {
305309
@Override
306310
public ResultSetMetaData getMetaData() throws SQLException {
307311
checkClosed();
308-
return null;
312+
313+
if (resultSetMetaData == null && currentResultSet == null) {
314+
// before execution
315+
if (statementType == StatementType.SELECT) {
316+
try {
317+
String sql = JdbcUtils.replaceQuestionMarks(originalSql, JdbcUtils.NULL);
318+
TableSchema tSchema = connection.getClient().getTableSchemaFromQuery(sql);
319+
resultSetMetaData = new ResultSetMetaDataImpl(tSchema.getColumns(),
320+
tSchema.getDatabaseName(), "", tSchema.getTableName(), Collections.emptyMap());
321+
} catch (Exception e) {
322+
// fallback to empty until
323+
}
324+
} else if (statementType == StatementType.SHOW) {
325+
// predefined
326+
} else if (statementType == StatementType.DESCRIBE) {
327+
// predefined
328+
} else {
329+
// fallback to empty
330+
}
331+
} else if (resultSetMetaData == null) {
332+
resultSetMetaData = currentResultSet.getMetaData();
333+
}
334+
335+
return resultSetMetaData;
309336
}
310337

311338
@Override
@@ -352,10 +379,19 @@ public void setURL(int parameterIndex, URL x) throws SQLException {
352379
parameters[parameterIndex - 1] = encodeObject(x);
353380
}
354381

382+
/**
383+
* Current JDBC driver implementation implement this functionality.
384+
* But specification doesn't expect throwing an exception what
385+
* for makes us return a "dummy" object. Returned metadata reflects only
386+
* information we can guarantee like parameter count.
387+
* @see ParameterMetaDataImpl
388+
* @return {@link ParameterMetaDataImpl}
389+
* @throws SQLException if the statement is close
390+
*/
355391
@Override
356392
public ParameterMetaData getParameterMetaData() throws SQLException {
357393
checkClosed();
358-
return null;
394+
return parameterMetaData;
359395
}
360396

361397
@Override

jdbc-v2/src/main/java/com/clickhouse/jdbc/ResultSetImpl.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
import java.net.URL;
99
import java.nio.charset.StandardCharsets;
1010
import java.sql.*;
11+
import java.sql.Date;
1112
import java.time.ZonedDateTime;
12-
import java.util.Calendar;
13-
import java.util.GregorianCalendar;
14-
import java.util.List;
15-
import java.util.Map;
13+
import java.util.*;
1614

1715
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
1816
import com.clickhouse.client.api.metadata.TableSchema;
@@ -21,6 +19,7 @@
2119
import com.clickhouse.data.ClickHouseDataType;
2220
import com.clickhouse.jdbc.internal.ExceptionUtils;
2321
import com.clickhouse.jdbc.internal.JdbcUtils;
22+
import com.clickhouse.jdbc.metadata.ResultSetMetaDataImpl;
2423
import com.clickhouse.jdbc.types.Array;
2524
import org.slf4j.Logger;
2625
import org.slf4j.LoggerFactory;
@@ -39,7 +38,10 @@ public ResultSetImpl(StatementImpl parentStatement, QueryResponse response, Clic
3938
this.parentStatement = parentStatement;
4039
this.response = response;
4140
this.reader = reader;
42-
this.metaData = new com.clickhouse.jdbc.metadata.ResultSetMetaData(this);
41+
TableSchema tableMetadata = reader.getSchema();
42+
this.metaData = new ResultSetMetaDataImpl(tableMetadata
43+
.getColumns(), tableMetadata.getDatabaseName(), "", tableMetadata.getTableName(),
44+
Collections.emptyMap());
4345
this.closed = false;
4446
this.wasNull = false;
4547
this.defaultCalendar = parentStatement.connection.defaultCalendar;
@@ -49,7 +51,10 @@ protected ResultSetImpl(ResultSetImpl resultSet) {
4951
this.parentStatement = resultSet.parentStatement;
5052
this.response = resultSet.response;
5153
this.reader = resultSet.reader;
52-
this.metaData = new com.clickhouse.jdbc.metadata.ResultSetMetaData(this);
54+
TableSchema tableMetadata = resultSet.getSchema();
55+
this.metaData = new ResultSetMetaDataImpl(tableMetadata
56+
.getColumns(), tableMetadata.getDatabaseName(), "", tableMetadata.getTableName(),
57+
Collections.emptyMap());
5358
this.closed = false;
5459
this.wasNull = false;
5560
this.defaultCalendar = parentStatement.connection.defaultCalendar;

jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class StatementImpl implements Statement, JdbcV2Wrapper {
3131
ConnectionImpl connection;
3232
private int queryTimeout;
3333
protected boolean closed;
34-
private ResultSetImpl currentResultSet;
34+
protected ResultSetImpl currentResultSet;
3535
private OperationMetrics metrics;
3636
protected List<String> batch;
3737
private String lastSql;

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.List;
2323
import java.util.Map;
2424
import java.util.TreeMap;
25+
import java.util.regex.Matcher;
26+
import java.util.regex.Pattern;
2527

2628
public class JdbcUtils {
2729
//Define a map to store the mapping between ClickHouse data types and SQL data types
@@ -271,4 +273,26 @@ public static String escapeQuotes(String str) {
271273
.replace("'", "\\'")
272274
.replace("\"", "\\\"");
273275
}
276+
277+
public static final String NULL = "NULL";
278+
279+
private static final Pattern REPLACE_Q_MARK_PATTERN = Pattern.compile("(\"[^\"]*\"|`[^`]*`)|(\\?)");
280+
281+
public static String replaceQuestionMarks(String sql, String replacement) {
282+
Matcher matcher = REPLACE_Q_MARK_PATTERN.matcher(sql);
283+
284+
StringBuilder result = new StringBuilder();
285+
286+
while (matcher.find()) {
287+
if (matcher.group(1) != null) {
288+
// Quoted string — keep as-is
289+
matcher.appendReplacement(result, Matcher.quoteReplacement(matcher.group(1)));
290+
} else if (matcher.group(2) != null) {
291+
// Question mark outside quotes — replace it
292+
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
293+
}
294+
}
295+
matcher.appendTail(result);
296+
return result.toString();
297+
}
274298
}

jdbc-v2/src/main/java/com/clickhouse/jdbc/metadata/ParameterMetaData.java

Lines changed: 0 additions & 108 deletions
This file was deleted.

0 commit comments

Comments
 (0)