Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL: forward warning headers to JDBC driver #84499

Merged
merged 11 commits into from
Mar 15, 2022

Conversation

Luegg
Copy link
Contributor

@Luegg Luegg commented Mar 1, 2022

Follow up on #83943 to ensure that users of the JDBC drivers also can act on the warnings.

The change ensures that warnings in the response headers from the _sql API are available in JdbcResultSet.getWarnings().

@elasticsearchmachine
Copy link
Collaborator

Hi @Luegg, I've created a changelog YAML for you.

}

public SqlQueryResponse query(SqlQueryRequest sqlRequest) throws SQLException {
public Tuple<SqlQueryResponse, List<String>> query(SqlQueryRequest sqlRequest) throws SQLException {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too fond of working with tuples everywhere I have to pass the warnings but this was the least intrusive way to get the warnings from the response headers. Since it's an internal client it probably doesn't matter too much but suggestions for solving this differently are welcome.

@Luegg Luegg marked this pull request as ready for review March 2, 2022 09:14
@elasticmachine elasticmachine added the Team:QL (Deprecated) Meta label for query languages team label Mar 2, 2022
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-ql (Team:QL)

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Left two comments.

assertNull(rs.getWarnings());
}
}

private static Version WARNING_HANDLING_ADDED_VERSION = Version.V_8_2_0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, move this line at the top of the class.


}

private <Response> Response fromContent(
ContentType contentType,
Function<String, List<String>> headers,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I would keep the initial intention of the method (getting the contentType and not the whole list of headers).

Copy link
Contributor

@bpintea bpintea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines 195 to 196
String value = con.getHeaderField(i);
while (value != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that the function would stop iterating on an empty header value? This seems to be legal, though very corner case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that's never the case but the API does not forbid null headers. Changing the implementation to use URLConnection.getHeaderFields() 👍

Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!
The pairing ResultSet#clearWarnings needs to be implemented as well - hence the request for changes.
An alternative to Tuple in 8.x could be a dedicated response class (maybe even a record in 8.x) to avoid the .v1() call or the large Tuple<SqlQueryResponse, List> signature to public ConnectionResponse ... or something along those lines.

@Luegg
Copy link
Contributor Author

Luegg commented Mar 14, 2022

@costin good catch regarding ResultSet#clearWarnings. I've added the implementation and also replaced the tuple with a generic wrapper class (records are not available because we're stuck with Java 8 here).

@Luegg Luegg requested a review from costin March 14, 2022 16:58
Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments around styling, LGTM.


List<String> warnings();

Cursor withoutWarnings();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to remove the warnings instead of creating a new cursor instance.


@Override
public Cursor withoutWarnings() {
return new DefaultCursor(client, cursor, columnInfos, rows, meta, Collections.emptyList());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clearWarnings method is easy to map the actual functionality and can simply clear the list with a check to be emptyList-friendly:

if (list.isEmpty() == false) { 
   list.clear()
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List#clear() is not implemented in the list instance used here (it's unmodifiable).

@@ -54,7 +54,7 @@
private final Calendar defaultCalendar;

private final JdbcStatement statement;
private final Cursor cursor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By using clearWarnings the Cursor is preserved as final.

}

@Override
public void clearWarnings() throws SQLException {
checkOpen();
cursor = cursor.withoutWarnings();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cursor.clearWarnings()

@@ -183,6 +187,17 @@ public boolean head() throws ClientException {
}
}

private Function<String, List<String>> getHeaderFields(URLConnection con) {
return header -> {
for (Map.Entry<String, List<String>> entry : con.getHeaderFields().entrySet()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method returns the first match - does headerFields normalizes keys? For example Content-Type and ConteNT-TYPE have their values under the same key or separate ones?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. Looking at the URLConnection implementation it indeed looks like Content-Type and ConteNT-TYPE header values would end up in two different buckets. While it's unlikely that a server would use two different casing rules I'll have a look at a more stable approach anyway.

@Luegg Luegg added auto-merge Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) auto-backport-and-merge Automatically create backport pull requests and merge when ready labels Mar 15, 2022
@elasticsearchmachine elasticsearchmachine merged commit 7c98c46 into elastic:master Mar 15, 2022
@Luegg Luegg deleted the enhance/warningsInJdbc branch March 15, 2022 16:59
Luegg pushed a commit to Luegg/elasticsearch that referenced this pull request Mar 15, 2022
Follow up on elastic#83943 to
ensure that users of the JDBC drivers also can act on the warnings.

The change ensures that warnings in the response headers from the `_sql`
API are available in `JdbcResultSet.getWarnings()`.
@elasticsearchmachine
Copy link
Collaborator

💚 Backport successful

Status Branch Result
8.1

elasticsearchmachine pushed a commit that referenced this pull request Mar 15, 2022
* SQL: forward warning headers to JDBC driver (#84499)

Follow up on #83943 to
ensure that users of the JDBC drivers also can act on the warnings.

The change ensures that warnings in the response headers from the `_sql`
API are available in `JdbcResultSet.getWarnings()`.

* fix version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Analytics/SQL SQL querying auto-backport-and-merge Automatically create backport pull requests and merge when ready auto-merge Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) >enhancement Team:QL (Deprecated) Meta label for query languages team v8.1.1 v8.2.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants