-
Notifications
You must be signed in to change notification settings - Fork 24.7k
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
SQL: forward warning headers to JDBC driver #84499
Conversation
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 { |
There was a problem hiding this comment.
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.
ba95737
to
990cbcb
Compare
Pinging @elastic/es-ql (Team:QL) |
There was a problem hiding this 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; |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
String value = con.getHeaderField(i); | ||
while (value != null) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()
👍
There was a problem hiding this 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.
@costin good catch regarding |
b55673d
to
321048a
Compare
There was a problem hiding this 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(); |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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()
}
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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()) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
7cb982b
to
07238bb
Compare
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()`.
💚 Backport successful
|
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 inJdbcResultSet.getWarnings()
.