Skip to content

Commit

Permalink
feat: Provide proper schema and catalog names from within `ResultSetM…
Browse files Browse the repository at this point in the history
…etaData`.

Signed-off-by: Michael Simons <michael.simons@neo4j.com>
  • Loading branch information
michael-simons committed Feb 6, 2025
1 parent f39448b commit d42f893
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 28 deletions.
29 changes: 16 additions & 13 deletions neo4j-jdbc/src/main/java/org/neo4j/jdbc/DatabaseMetadataImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,8 @@ public ResultSet getTableTypes() {
var response = createRunResponseForStaticKeys(keys);
var pull = staticPullResponseFor(keys,
List.of(new Value[] { Values.value("TABLE") }, new Value[] { Values.value("RELATIONSHIP") }));
return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), response, pull, -1, -1, -1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), response, pull,
-1, -1, -1);
}

static Value getMaxPrecision(int type) {
Expand Down Expand Up @@ -967,7 +968,7 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
var runResponse = createRunResponseForStaticKeys(keys);
var staticPullResponse = staticPullResponseFor(keys, rows);

return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), runResponse,
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), runResponse,
staticPullResponse, -1, -1, -1);
}

Expand Down Expand Up @@ -1158,8 +1159,8 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) thr

var pull = staticPullResponseFor(keys, resultRows);
var runResponse = createRunResponseForStaticKeys(keys);
return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), runResponse, pull, -1, -1,
-1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), runResponse,
pull, -1, -1, -1);
}

private List<Value[]> makeUniqueKeyValues(String catalog, String schema, String table,
Expand Down Expand Up @@ -1212,7 +1213,7 @@ private ResultSet createKeysResultSet(ArrayList<String> keys) {
var emptyPullResponse = createEmptyPullResponse();
var runResponse = createRunResponseForStaticKeys(keys);

return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), runResponse,
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), runResponse,
emptyPullResponse, -1, -1, -1);
}

Expand Down Expand Up @@ -1248,7 +1249,8 @@ public ResultSet getTypeInfo() {

var response = createRunResponseForStaticKeys(keys);
var pull = staticPullResponseFor(keys, values);
return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), response, pull, -1, -1, -1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), response, pull,
-1, -1, -1);

}

Expand Down Expand Up @@ -1446,8 +1448,8 @@ public ResultSet getSchemas() throws SQLException {
var response = createRunResponseForStaticKeys(keys);
var staticPulLResponse = staticPullResponseFor(keys,
Collections.singletonList(new Value[] { Values.value("public"), Values.value(getSingleCatalog()) }));
return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), response, staticPulLResponse,
-1, -1, -1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), response,
staticPulLResponse, -1, -1, -1);
}

@Override
Expand All @@ -1468,8 +1470,8 @@ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLExce

var runResponse = createRunResponseForStaticKeys(keys);

return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), runResponse, pull, -1, -1,
-1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), runResponse,
pull, -1, -1, -1);
}

@Override
Expand All @@ -1494,7 +1496,8 @@ public ResultSet getClientInfoProperties() {
var response = createRunResponseForStaticKeys(keys);
var pull = staticPullResponseFor(keys, values);

return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), response, pull, -1, -1, -1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(), response, pull,
-1, -1, -1);
}

static boolean isSupportedClientInfoProperty(String name) {
Expand Down Expand Up @@ -1636,8 +1639,8 @@ private PullResponse doQueryForPullResponse(Request request) throws SQLException
private ResultSet doQueryForResultSet(Request request) throws SQLException {
var response = doQuery(request);

return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), response.runFuture.join(),
response.pullResponse, -1, -1, -1);
return new ResultSetImpl(new LocalStatementImpl(this.connection), new ThrowingTransactionImpl(),
response.runFuture.join(), response.pullResponse, -1, -1, -1);
}

private QueryAndRunResponse doQuery(Request request) throws SQLException {
Expand Down
12 changes: 7 additions & 5 deletions neo4j-jdbc/src/main/java/org/neo4j/jdbc/LocalStatementImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@
*/
final class LocalStatementImpl extends StatementImpl {

LocalStatementImpl() {
super();
}
private final Connection connection;

private boolean closeOnCompletion;

private boolean closed;

LocalStatementImpl(Connection connection) {
this.connection = connection;
}

@Override
public ResultSet executeQuery(String sql) throws SQLException {
throw new SQLFeatureNotSupportedException();
Expand Down Expand Up @@ -95,8 +97,8 @@ public int[] executeBatch() throws SQLException {
}

@Override
public Connection getConnection() throws SQLException {
throw new SQLFeatureNotSupportedException();
public Connection getConnection() {
return this.connection;
}

@Override
Expand Down
5 changes: 3 additions & 2 deletions neo4j-jdbc/src/main/java/org/neo4j/jdbc/ResultSetImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,9 @@ public String getCursorName() throws SQLException {
}

@Override
public ResultSetMetaData getMetaData() {
return new ResultSetMetaDataImpl(this.keys, this.firstRecord);
public ResultSetMetaData getMetaData() throws SQLException {
var connection = this.statement.getConnection();
return new ResultSetMetaDataImpl(connection.getSchema(), connection.getCatalog(), this.keys, this.firstRecord);
}

@Override
Expand Down
22 changes: 17 additions & 5 deletions neo4j-jdbc/src/main/java/org/neo4j/jdbc/ResultSetMetaDataImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Types;
import java.util.List;
import java.util.Objects;

import org.neo4j.jdbc.values.BooleanValue;
import org.neo4j.jdbc.values.BytesValue;
Expand All @@ -48,11 +49,22 @@

final class ResultSetMetaDataImpl implements ResultSetMetaData {

private final String schemaName;

private final String catalogName;

private final String tableName;

private final List<String> keys;

private final Record firstRecord;

ResultSetMetaDataImpl(List<String> keys, Record firstRecord) {
ResultSetMetaDataImpl(String schemaName, String catalogName, List<String> keys, Record firstRecord) {
// JDBC spec defines the empty string as "not applicable"
this.schemaName = Objects.requireNonNullElse(schemaName, "").trim();
this.catalogName = Objects.requireNonNullElse(catalogName, "").trim();
// right now we have no way of tracking where a specific column comes from.
this.tableName = "";
this.keys = keys;
this.firstRecord = firstRecord;
}
Expand Down Expand Up @@ -112,7 +124,7 @@ public String getColumnName(int column) {

@Override
public String getSchemaName(int column) {
return "public"; // every schema is public.
return this.schemaName;
}

@Override
Expand All @@ -127,16 +139,16 @@ public int getScale(int column) {

@Override
public String getTableName(int column) {
return "Unknown?"; // can we get this? or does it need another query?
return this.tableName;
}

@Override
public String getCatalogName(int column) {
return ""; // No Catalog ever for neo4j.
return this.catalogName;
}

@Override
public int getColumnType(int column) throws SQLException {
public int getColumnType(int column) {
if (this.firstRecord == null) {
return Types.NULL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.neo4j.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
Expand Down Expand Up @@ -55,15 +56,23 @@ void testResultSetMetadataColumnCount() throws SQLException {
void testResultSetMetadataGetSchema() throws SQLException {
try (var resultSet = setupWithValues(Collections.singletonList(Values.value(2)))) {
var rsMetadata = resultSet.getMetaData();
Assertions.assertThat(rsMetadata.getSchemaName(1)).isEqualTo("public");
Assertions.assertThat(rsMetadata.getSchemaName(1)).isEqualTo("private");
}
}

@Test
void testResultSetMetadataGetCatalog() throws SQLException {
try (var resultSet = setupWithValues(Collections.singletonList(Values.value(2)))) {
var rsMetadata = resultSet.getMetaData();
Assertions.assertThat(rsMetadata.getCatalogName(1)).isEqualTo("");
Assertions.assertThat(rsMetadata.getCatalogName(1)).isEqualTo("Otto");
}
}

@Test
void testResultSetMetadataGetTable() throws SQLException {
try (var resultSet = setupWithValues(Collections.singletonList(Values.value(2)))) {
var rsMetadata = resultSet.getMetaData();
Assertions.assertThat(rsMetadata.getTableName(1)).isEqualTo("");
}
}

Expand Down Expand Up @@ -139,10 +148,15 @@ void testResultSetMetadataReturnsTheTypeOfTheFirstRecordIfTheFirstRecordTypeIsDi
}
}

private ResultSet setupWithValues(List<Value> expectedValue) {
private ResultSet setupWithValues(List<Value> expectedValue) throws SQLException {
var statement = mock(StatementImpl.class);
var connection = mock(Connection.class);
given(connection.getSchema()).willReturn("private");
given(connection.getCatalog()).willReturn("Otto");
var runResponse = mock(RunResponse.class);

given(statement.getConnection()).willReturn(connection);

List<Record> boltRecords = new ArrayList<>();

for (Value value : expectedValue) {
Expand Down

0 comments on commit d42f893

Please sign in to comment.