Skip to content

Commit bac789e

Browse files
authored
Code cleanup in SourceOperations (#20874)
* Refactor SourceOperations class * More cleanup * Addressing comments * Formatting
1 parent 99905b2 commit bac789e

File tree

34 files changed

+215
-227
lines changed

34 files changed

+215
-227
lines changed

airbyte-db/db-lib/src/main/java/io/airbyte/db/JdbcCompatibleSourceOperations.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66

77
import com.fasterxml.jackson.databind.JsonNode;
88
import com.fasterxml.jackson.databind.node.ObjectNode;
9-
import java.sql.Connection;
109
import java.sql.PreparedStatement;
1110
import java.sql.ResultSet;
1211
import java.sql.SQLException;
13-
import java.util.List;
1412

1513
public interface JdbcCompatibleSourceOperations<SourceType> extends SourceOperations<ResultSet, SourceType> {
1614

@@ -20,41 +18,21 @@ public interface JdbcCompatibleSourceOperations<SourceType> extends SourceOperat
2018
*
2119
* @param colIndex 1-based column index.
2220
*/
23-
void setJsonField(final ResultSet resultSet, final int colIndex, final ObjectNode json) throws SQLException;
21+
void copyToJsonField(final ResultSet resultSet, final int colIndex, final ObjectNode json) throws SQLException;
2422

2523
/**
2624
* Set the cursor field in incremental table query.
2725
*/
28-
void setStatementField(final PreparedStatement preparedStatement,
29-
final int parameterIndex,
30-
final SourceType cursorFieldType,
31-
final String value)
26+
void setCursorField(final PreparedStatement preparedStatement,
27+
final int parameterIndex,
28+
final SourceType cursorFieldType,
29+
final String value)
3230
throws SQLException;
3331

3432
/**
3533
* Determine the database specific type of the input field based on its column metadata.
3634
*/
37-
SourceType getFieldType(final JsonNode field);
38-
39-
/**
40-
* @return the input identifiers with quotes and delimiters.
41-
*/
42-
String enquoteIdentifierList(final Connection connection, final List<String> identifiers) throws SQLException;
43-
44-
/**
45-
* @return the input identifier with quotes.
46-
*/
47-
String enquoteIdentifier(final Connection connection, final String identifier) throws SQLException;
48-
49-
/**
50-
* @return fully qualified table name with the schema (if a schema exists).
51-
*/
52-
String getFullyQualifiedTableName(final String schemaName, final String tableName);
53-
54-
/**
55-
* @return fully qualified table name with the schema (if a schema exists) in quotes.
56-
*/
57-
String getFullyQualifiedTableNameWithQuoting(final Connection connection, final String schemaName, final String tableName) throws SQLException;
35+
SourceType getDatabaseFieldType(final JsonNode field);
5836

5937
/**
6038
* This method will verify that filed could be used as cursor for incremental sync

airbyte-db/db-lib/src/main/java/io/airbyte/db/PostgresUtils.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public static Certificate getCertificate(final PostgreSQLContainer<?> container)
5151
container.execInContainer("su", "-c",
5252
"echo \"hostssl all all 127.0.0.1/32 cert clientcert=verify-full\" >> /var/lib/postgresql/data/pg_hba.conf");
5353

54-
var caCert = container.execInContainer("su", "-c", "cat ca.crt").getStdout().trim();
54+
final var caCert = container.execInContainer("su", "-c", "cat ca.crt").getStdout().trim();
5555

5656
container.execInContainer("su", "-c", "openssl ecparam -name prime256v1 -genkey -noout -out client.key");
5757
container.execInContainer("su", "-c", "openssl req -new -sha256 -key client.key -out client.csr -subj \"/CN=postgres\"");
@@ -65,8 +65,8 @@ public static Certificate getCertificate(final PostgreSQLContainer<?> container)
6565

6666
container.execInContainer("su", "-c", "psql -U test -c \"SELECT pg_reload_conf();\"");
6767

68-
var clientKey = container.execInContainer("su", "-c", "cat client.key").getStdout().trim();
69-
var clientCert = container.execInContainer("su", "-c", "cat client.crt").getStdout().trim();
68+
final var clientKey = container.execInContainer("su", "-c", "cat client.key").getStdout().trim();
69+
final var clientCert = container.execInContainer("su", "-c", "cat client.crt").getStdout().trim();
7070
return new Certificate(caCert, clientCert, clientKey);
7171
}
7272

airbyte-db/db-lib/src/main/java/io/airbyte/db/SourceOperations.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@
1010

1111
public interface SourceOperations<QueryResult, SourceType> {
1212

13+
/**
14+
* Converts a database row into it's JSON representation.
15+
*
16+
* @throws SQLException
17+
*/
1318
JsonNode rowToJson(QueryResult queryResult) throws SQLException;
1419

15-
JsonSchemaType getJsonType(SourceType sourceType);
20+
/**
21+
* Converts a database source type into an Airbyte type, which is currently represented by a
22+
* {@link JsonSchemaType}
23+
*/
24+
JsonSchemaType getAirbyteType(SourceType sourceType);
1625

17-
//
18-
// JsonSchemaType getJsonSchemaType(SourceType columnType);
1926
}

airbyte-db/db-lib/src/main/java/io/airbyte/db/bigquery/BigQueryDatabase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public BigQueryDatabase(final String projectId, final String jsonCreds, final Bi
7979
}
8080
}
8181

82-
private String getUserAgentHeader(String connectorVersion) {
82+
private String getUserAgentHeader(final String connectorVersion) {
8383
return String.format(AGENT_TEMPLATE, connectorVersion);
8484
}
8585

airbyte-db/db-lib/src/main/java/io/airbyte/db/bigquery/BigQuerySourceOperations.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public Date getDateValue(final FieldValue fieldValue, final DateFormat dateForma
116116
}
117117

118118
@Override
119-
public JsonSchemaType getJsonType(final StandardSQLTypeName bigQueryType) {
119+
public JsonSchemaType getAirbyteType(final StandardSQLTypeName bigQueryType) {
120120
return switch (bigQueryType) {
121121
case BOOL -> JsonSchemaType.BOOLEAN;
122122
case INT64 -> JsonSchemaType.INTEGER;

airbyte-db/db-lib/src/main/java/io/airbyte/db/jdbc/AbstractJdbcCompatibleSourceOperations.java

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import io.airbyte.db.DataTypeUtils;
1616
import io.airbyte.db.JdbcCompatibleSourceOperations;
1717
import java.math.BigDecimal;
18-
import java.sql.Connection;
1918
import java.sql.Date;
2019
import java.sql.PreparedStatement;
2120
import java.sql.ResultSet;
@@ -28,8 +27,6 @@
2827
import java.time.OffsetTime;
2928
import java.time.chrono.IsoEra;
3029
import java.util.Collections;
31-
import java.util.List;
32-
import java.util.StringJoiner;
3330
import javax.xml.bind.DatatypeConverter;
3431

3532
/**
@@ -58,7 +55,7 @@ public JsonNode rowToJson(final ResultSet queryContext) throws SQLException {
5855
}
5956

6057
// convert to java types that will convert into reasonable json.
61-
setJsonField(queryContext, i, jsonNode);
58+
copyToJsonField(queryContext, i, jsonNode);
6259
}
6360

6461
return jsonNode;
@@ -229,35 +226,6 @@ protected void setBinary(final PreparedStatement preparedStatement, final int pa
229226
preparedStatement.setBytes(parameterIndex, DatatypeConverter.parseHexBinary(value));
230227
}
231228

232-
@Override
233-
public String enquoteIdentifierList(final Connection connection, final List<String> identifiers) throws SQLException {
234-
final StringJoiner joiner = new StringJoiner(",");
235-
for (final String col : identifiers) {
236-
final String s = enquoteIdentifier(connection, col);
237-
joiner.add(s);
238-
}
239-
return joiner.toString();
240-
}
241-
242-
@Override
243-
public String enquoteIdentifier(final Connection connection, final String identifier) throws SQLException {
244-
final String identifierQuoteString = connection.getMetaData().getIdentifierQuoteString();
245-
246-
return identifierQuoteString + identifier + identifierQuoteString;
247-
}
248-
249-
@Override
250-
public String getFullyQualifiedTableName(final String schemaName, final String tableName) {
251-
return JdbcUtils.getFullyQualifiedTableName(schemaName, tableName);
252-
}
253-
254-
@Override
255-
public String getFullyQualifiedTableNameWithQuoting(final Connection connection, final String schemaName, final String tableName)
256-
throws SQLException {
257-
final String quotedTableName = enquoteIdentifier(connection, tableName);
258-
return schemaName != null ? enquoteIdentifier(connection, schemaName) + "." + quotedTableName : quotedTableName;
259-
}
260-
261229
protected <ObjectType> ObjectType getObject(final ResultSet resultSet, final int index, final Class<ObjectType> clazz) throws SQLException {
262230
return resultSet.getObject(index, clazz);
263231
}

airbyte-db/db-lib/src/main/java/io/airbyte/db/jdbc/JdbcSourceOperations.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protected JDBCType safeGetJdbcType(final int columnTypeInt) {
3737
}
3838

3939
@Override
40-
public void setJsonField(final ResultSet resultSet, final int colIndex, final ObjectNode json) throws SQLException {
40+
public void copyToJsonField(final ResultSet resultSet, final int colIndex, final ObjectNode json) throws SQLException {
4141
final int columnTypeInt = resultSet.getMetaData().getColumnType(colIndex);
4242
final String columnName = resultSet.getMetaData().getColumnName(colIndex);
4343
final JDBCType columnType = safeGetJdbcType(columnTypeInt);
@@ -63,10 +63,10 @@ public void setJsonField(final ResultSet resultSet, final int colIndex, final Ob
6363
}
6464

6565
@Override
66-
public void setStatementField(final PreparedStatement preparedStatement,
67-
final int parameterIndex,
68-
final JDBCType cursorFieldType,
69-
final String value)
66+
public void setCursorField(final PreparedStatement preparedStatement,
67+
final int parameterIndex,
68+
final JDBCType cursorFieldType,
69+
final String value)
7070
throws SQLException {
7171
switch (cursorFieldType) {
7272

@@ -90,7 +90,7 @@ public void setStatementField(final PreparedStatement preparedStatement,
9090
}
9191

9292
@Override
93-
public JDBCType getFieldType(final JsonNode field) {
93+
public JDBCType getDatabaseFieldType(final JsonNode field) {
9494
try {
9595
return JDBCType.valueOf(field.get(INTERNAL_COLUMN_TYPE).asInt());
9696
} catch (final IllegalArgumentException ex) {
@@ -109,7 +109,7 @@ public boolean isCursorType(final JDBCType type) {
109109
}
110110

111111
@Override
112-
public JsonSchemaType getJsonType(final JDBCType jdbcType) {
112+
public JsonSchemaType getAirbyteType(final JDBCType jdbcType) {
113113
return switch (jdbcType) {
114114
case BIT, BOOLEAN -> JsonSchemaType.BOOLEAN;
115115
case TINYINT, SMALLINT -> JsonSchemaType.INTEGER;

airbyte-db/db-lib/src/test/java/io/airbyte/db/jdbc/TestJdbcUtils.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,21 @@ void testSetStatementField() throws SQLException {
152152

153153
// insert the bit here to stay consistent even though setStatementField does not support it yet.
154154
ps.setString(1, "1");
155-
sourceOperations.setStatementField(ps, 2, JDBCType.BOOLEAN, "true");
156-
sourceOperations.setStatementField(ps, 3, JDBCType.SMALLINT, "1");
157-
sourceOperations.setStatementField(ps, 4, JDBCType.INTEGER, "1");
158-
sourceOperations.setStatementField(ps, 5, JDBCType.BIGINT, "1");
159-
sourceOperations.setStatementField(ps, 6, JDBCType.FLOAT, "1.0");
160-
sourceOperations.setStatementField(ps, 7, JDBCType.DOUBLE, "1.0");
161-
sourceOperations.setStatementField(ps, 8, JDBCType.REAL, "1.0");
162-
sourceOperations.setStatementField(ps, 9, JDBCType.NUMERIC, "1");
163-
sourceOperations.setStatementField(ps, 10, JDBCType.DECIMAL, "1");
164-
sourceOperations.setStatementField(ps, 11, JDBCType.CHAR, "a");
165-
sourceOperations.setStatementField(ps, 12, JDBCType.VARCHAR, "a");
166-
sourceOperations.setStatementField(ps, 13, JDBCType.DATE, "2020-11-01T00:00:00Z");
167-
sourceOperations.setStatementField(ps, 14, JDBCType.TIME, "1970-01-01T05:00:00.000Z");
168-
sourceOperations.setStatementField(ps, 15, JDBCType.TIMESTAMP, "2001-09-29T03:00:00.000Z");
169-
sourceOperations.setStatementField(ps, 16, JDBCType.BINARY, "61616161");
155+
sourceOperations.setCursorField(ps, 2, JDBCType.BOOLEAN, "true");
156+
sourceOperations.setCursorField(ps, 3, JDBCType.SMALLINT, "1");
157+
sourceOperations.setCursorField(ps, 4, JDBCType.INTEGER, "1");
158+
sourceOperations.setCursorField(ps, 5, JDBCType.BIGINT, "1");
159+
sourceOperations.setCursorField(ps, 6, JDBCType.FLOAT, "1.0");
160+
sourceOperations.setCursorField(ps, 7, JDBCType.DOUBLE, "1.0");
161+
sourceOperations.setCursorField(ps, 8, JDBCType.REAL, "1.0");
162+
sourceOperations.setCursorField(ps, 9, JDBCType.NUMERIC, "1");
163+
sourceOperations.setCursorField(ps, 10, JDBCType.DECIMAL, "1");
164+
sourceOperations.setCursorField(ps, 11, JDBCType.CHAR, "a");
165+
sourceOperations.setCursorField(ps, 12, JDBCType.VARCHAR, "a");
166+
sourceOperations.setCursorField(ps, 13, JDBCType.DATE, "2020-11-01T00:00:00Z");
167+
sourceOperations.setCursorField(ps, 14, JDBCType.TIME, "1970-01-01T05:00:00.000Z");
168+
sourceOperations.setCursorField(ps, 15, JDBCType.TIMESTAMP, "2001-09-29T03:00:00.000Z");
169+
sourceOperations.setCursorField(ps, 16, JDBCType.BINARY, "61616161");
170170

171171
ps.execute();
172172

@@ -332,7 +332,8 @@ private static void assertExpectedOutputTypes(final Connection connection) throw
332332
final int columnCount = resultSet.getMetaData().getColumnCount();
333333
final Map<String, JsonSchemaType> actual = new HashMap<>(columnCount);
334334
for (int i = 1; i <= columnCount; i++) {
335-
actual.put(resultSet.getMetaData().getColumnName(i), sourceOperations.getJsonType(JDBCType.valueOf(resultSet.getMetaData().getColumnType(i))));
335+
actual.put(resultSet.getMetaData().getColumnName(i),
336+
sourceOperations.getAirbyteType(JDBCType.valueOf(resultSet.getMetaData().getColumnType(i))));
336337
}
337338

338339
final Map<String, JsonSchemaType> expected = ImmutableMap.<String, JsonSchemaType>builder()

airbyte-integrations/connectors/destination-bigquery-denormalized/src/test-integration/java/io/airbyte/integrations/destination/bigquery/BigQueryDenormalizedDestinationAcceptanceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ private List<JsonNode> retrieveRecordsFromTable(final String tableName, final St
169169

170170
final TableResult queryResults = executeQuery(bigquery, queryConfig).getLeft().getQueryResults();
171171
final FieldList fields = queryResults.getSchema().getFields();
172-
BigQuerySourceOperations sourceOperations = new BigQuerySourceOperations();
172+
final BigQuerySourceOperations sourceOperations = new BigQuerySourceOperations();
173173

174174
return Streams.stream(queryResults.iterateAll())
175175
.map(fieldValues -> sourceOperations.rowToJson(new BigQueryResultSet(fieldValues, fields))).collect(Collectors.toList());

airbyte-integrations/connectors/destination-bigquery/src/test-integration/java/io/airbyte/integrations/destination/bigquery/AbstractBigQueryDestinationAcceptanceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ protected List<JsonNode> retrieveRecordsFromTable(final String tableName, final
163163

164164
final TableResult queryResults = BigQueryUtils.executeQuery(bigquery, queryConfig).getLeft().getQueryResults();
165165
final FieldList fields = queryResults.getSchema().getFields();
166-
BigQuerySourceOperations sourceOperations = new BigQuerySourceOperations();
166+
final BigQuerySourceOperations sourceOperations = new BigQuerySourceOperations();
167167

168168
return Streams.stream(queryResults.iterateAll())
169169
.map(fieldValues -> sourceOperations.rowToJson(new BigQueryResultSet(fieldValues, fields))).collect(Collectors.toList());

airbyte-integrations/connectors/source-bigquery/src/main/java/io/airbyte/integrations/source/bigquery/BigQuerySource.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
package io.airbyte.integrations.source.bigquery;
66

77
import static io.airbyte.integrations.source.relationaldb.RelationalDbQueryUtils.enquoteIdentifierList;
8-
import static io.airbyte.integrations.source.relationaldb.RelationalDbQueryUtils.getFullTableName;
8+
import static io.airbyte.integrations.source.relationaldb.RelationalDbQueryUtils.getFullyQualifiedTableNameWithQuoting;
99
import static io.airbyte.integrations.source.relationaldb.RelationalDbQueryUtils.queryTable;
1010

1111
import com.fasterxml.jackson.databind.JsonNode;
@@ -81,7 +81,7 @@ public List<CheckedConsumer<BigQueryDatabase, Exception>> getCheckOperations(fin
8181
checkList.add(database -> {
8282
if (isDatasetConfigured(database)) {
8383
database.query(String.format("select 1 from %s where 1=0",
84-
getFullTableName(getConfigDatasetId(database), "INFORMATION_SCHEMA.TABLES", getQuoteString())));
84+
getFullyQualifiedTableNameWithQuoting(getConfigDatasetId(database), "INFORMATION_SCHEMA.TABLES", getQuoteString())));
8585
LOGGER.info("The source passed the Dataset query test!");
8686
} else {
8787
LOGGER.info("The Dataset query test is skipped due to not configured datasetId!");
@@ -92,8 +92,8 @@ public List<CheckedConsumer<BigQueryDatabase, Exception>> getCheckOperations(fin
9292
}
9393

9494
@Override
95-
protected JsonSchemaType getType(final StandardSQLTypeName columnType) {
96-
return sourceOperations.getJsonType(columnType);
95+
protected JsonSchemaType getAirbyteType(final StandardSQLTypeName columnType) {
96+
return sourceOperations.getAirbyteType(columnType);
9797
}
9898

9999
@Override
@@ -146,7 +146,7 @@ public AutoCloseableIterator<JsonNode> queryTableIncremental(final BigQueryDatab
146146
final StandardSQLTypeName cursorFieldType) {
147147
return queryTableWithParams(database, String.format("SELECT %s FROM %s WHERE %s > ?",
148148
RelationalDbQueryUtils.enquoteIdentifierList(columnNames, getQuoteString()),
149-
getFullTableName(schemaName, tableName, getQuoteString()),
149+
getFullyQualifiedTableNameWithQuoting(schemaName, tableName, getQuoteString()),
150150
cursorInfo.getCursorField()),
151151
sourceOperations.getQueryParameter(cursorFieldType, cursorInfo.getCursor()));
152152
}
@@ -159,7 +159,7 @@ protected AutoCloseableIterator<JsonNode> queryTableFullRefresh(final BigQueryDa
159159
LOGGER.info("Queueing query for table: {}", tableName);
160160
return queryTable(database, String.format("SELECT %s FROM %s",
161161
enquoteIdentifierList(columnNames, getQuoteString()),
162-
getFullTableName(schemaName, tableName, getQuoteString())));
162+
getFullyQualifiedTableNameWithQuoting(schemaName, tableName, getQuoteString())));
163163
}
164164

165165
@Override

airbyte-integrations/connectors/source-cockroachdb/src/main/java/io/airbyte/integrations/source/cockroachdb/CockroachJdbcSourceOperations.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public JsonNode rowToJson(final ResultSet queryContext) throws SQLException {
4545
try {
4646
queryContext.getObject(i);
4747
if (!queryContext.wasNull()) {
48-
setJsonField(queryContext, i, jsonNode);
48+
copyToJsonField(queryContext, i, jsonNode);
4949
}
5050
} catch (final SQLException e) {
5151
putCockroachSpecialDataType(queryContext, i, jsonNode);

airbyte-integrations/connectors/source-db2-strict-encrypt/src/test/java/io/airbyte/integrations/source/db2_strict_encrypt/Db2JdbcSourceAcceptanceTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.airbyte.integrations.source.db2.Db2Source;
1616
import io.airbyte.integrations.source.jdbc.AbstractJdbcSource;
1717
import io.airbyte.integrations.source.jdbc.test.JdbcSourceAcceptanceTest;
18+
import io.airbyte.integrations.source.relationaldb.RelationalDbQueryUtils;
1819
import io.airbyte.protocol.models.v0.ConnectorSpecification;
1920
import java.io.File;
2021
import java.io.IOException;
@@ -118,19 +119,19 @@ public void clean() throws Exception {
118119
}
119120
super.database.execute(connection -> connection.createStatement().execute(String
120121
.format("DROP TABLE IF EXISTS %s.%s", SCHEMA_NAME,
121-
sourceOperations.enquoteIdentifier(connection, TABLE_NAME_WITH_SPACES))));
122+
RelationalDbQueryUtils.enquoteIdentifier(TABLE_NAME_WITH_SPACES, connection.getMetaData().getIdentifierQuoteString()))));
122123
super.database.execute(connection -> connection.createStatement().execute(String
123124
.format("DROP TABLE IF EXISTS %s.%s", SCHEMA_NAME,
124-
sourceOperations.enquoteIdentifier(connection, TABLE_NAME_WITH_SPACES + 2))));
125+
RelationalDbQueryUtils.enquoteIdentifier(TABLE_NAME_WITH_SPACES + 2, connection.getMetaData().getIdentifierQuoteString()))));
125126
super.database.execute(connection -> connection.createStatement().execute(String
126127
.format("DROP TABLE IF EXISTS %s.%s", SCHEMA_NAME2,
127-
sourceOperations.enquoteIdentifier(connection, TABLE_NAME))));
128+
RelationalDbQueryUtils.enquoteIdentifier(TABLE_NAME, connection.getMetaData().getIdentifierQuoteString()))));
128129
super.database.execute(connection -> connection.createStatement().execute(String
129130
.format("DROP TABLE IF EXISTS %s.%s", SCHEMA_NAME,
130-
sourceOperations.enquoteIdentifier(connection, TABLE_NAME_WITHOUT_CURSOR_TYPE))));
131+
RelationalDbQueryUtils.enquoteIdentifier(TABLE_NAME_WITHOUT_CURSOR_TYPE, connection.getMetaData().getIdentifierQuoteString()))));
131132
super.database.execute(connection -> connection.createStatement().execute(String
132133
.format("DROP TABLE IF EXISTS %s.%s", SCHEMA_NAME,
133-
sourceOperations.enquoteIdentifier(connection, TABLE_NAME_WITH_NULLABLE_CURSOR_TYPE))));
134+
RelationalDbQueryUtils.enquoteIdentifier(TABLE_NAME_WITH_NULLABLE_CURSOR_TYPE, connection.getMetaData().getIdentifierQuoteString()))));
134135
super.tearDown();
135136
}
136137

0 commit comments

Comments
 (0)