-
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
Changes from 5 commits
990cbcb
056d52c
4c16d66
d3791a3
94d85e0
986ef75
42446b1
4b90b10
321048a
07238bb
a7216d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 84499 | ||
summary: Forward warning headers to JDBC driver | ||
area: SQL | ||
type: enhancement | ||
issues: [] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,4 +28,6 @@ default int columnSize() { | |
int batchSize(); | ||
|
||
void close() throws SQLException; | ||
|
||
List<String> warnings(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.security.AccessController; | ||
import java.security.PrivilegedAction; | ||
import java.sql.SQLClientInfoException; | ||
|
@@ -31,6 +32,8 @@ | |
import java.sql.SQLSyntaxErrorException; | ||
import java.sql.SQLTimeoutException; | ||
import java.util.Base64; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.function.Function; | ||
import java.util.zip.GZIPInputStream; | ||
|
||
|
@@ -150,15 +153,15 @@ public boolean head() throws ClientException { | |
|
||
public <R> ResponseOrException<R> request( | ||
CheckedConsumer<OutputStream, IOException> doc, | ||
CheckedBiFunction<InputStream, Function<String, String>, R, IOException> parser, | ||
CheckedBiFunction<InputStream, Function<String, List<String>>, R, IOException> parser, | ||
String requestMethod | ||
) throws ClientException { | ||
return request(doc, parser, requestMethod, "application/json"); | ||
} | ||
|
||
public <R> ResponseOrException<R> request( | ||
CheckedConsumer<OutputStream, IOException> doc, | ||
CheckedBiFunction<InputStream, Function<String, String>, R, IOException> parser, | ||
CheckedBiFunction<InputStream, Function<String, List<String>>, R, IOException> parser, | ||
String requestMethod, | ||
String contentTypeHeader | ||
) throws ClientException { | ||
|
@@ -174,7 +177,7 @@ public <R> ResponseOrException<R> request( | |
} | ||
if (shouldParseBody(con.getResponseCode())) { | ||
try (InputStream stream = getStream(con, con.getInputStream())) { | ||
return new ResponseOrException<>(parser.apply(new BufferedInputStream(stream), con::getHeaderField)); | ||
return new ResponseOrException<>(parser.apply(new BufferedInputStream(stream), getHeaderFields(con))); | ||
} | ||
} | ||
return parserError(); | ||
|
@@ -183,6 +186,23 @@ public <R> ResponseOrException<R> request( | |
} | ||
} | ||
|
||
private Function<String, List<String>> getHeaderFields(URLConnection con) { | ||
return header -> { | ||
// HTTP headers are case-insensitive but the map returned by `URLConnection.getHeaderFields` is case-sensitive. | ||
// The linear scan below replicates the linear case-insensitive lookup of `URLConnection.getHeaderField(String)`. | ||
List<String> values = new LinkedList<>(); | ||
int i = 0; | ||
String value = con.getHeaderField(i); | ||
while (value != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 |
||
if (header.equalsIgnoreCase(con.getHeaderFieldKey(i))) { | ||
values.add(value); | ||
} | ||
value = con.getHeaderField(++i); | ||
} | ||
return values; | ||
}; | ||
} | ||
|
||
private boolean shouldParseBody(int responseCode) { | ||
return responseCode == 200 || responseCode == 201 || responseCode == 202; | ||
} | ||
|
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.