InputStream `reset()` can fail on retries for BufferedInputStreams
Description
The ClickHouse Java Client provides an insert method that takes an InputStream.
On failure, this method calls data.reset() https://github.com/ClickHouse/clickhouse-java/blob/f9f588d9d1b8abd8e7e8ab0eafc84b070377a68d/client-v2/src/main/java/com/clickhouse/client/api/Client.java#L1387-L1390
However, as far as I can tell, the code never sets a mark.
This works well on ByteArrayInputStreams (as is used in the unit tests), where reset will move the stream back to the beginning, but not one something like BufferedInputStream. In that case, even though markSupported is true, the mark needs to be defined.
This will also obviously fail on InputStreams like GZIPInputStream where markSupported is false, but that's to be expected.
I'm not sure if the client should set a mark, but I think it should at least mention that in the documentation.
Steps to reproduce
Send an insert request that fails from a BufferedInputStream.
Note that this can simply be a BufferedInputStream wrapping a ByteInputStream.
Error Log or Exception StackTrace
Failed to reset stream before next attempt
Caused by: Exception java.io.IOException: Resetting to invalid mark
Expected Behaviour
Code Example
jshell> var bais = new java.io.ByteArrayInputStream("1,2,3".getBytes())
bais ==> java.io.ByteArrayInputStream@3159c4b8
jshell> var buffered = new java.io.BufferedInputStream(bais)
buffered ==> java.io.BufferedInputStream@29ca901e
jshell> // both support marks
jshell> bais.markSupported()
$3 ==> true
jshell> buffered.markSupported()
$4 ==> true
jshell> // reset works on byte array input streams
jshell> bais.reset()
jshell> // but fails on the buffered version
jshell> buffered.reset()
| Exception java.io.IOException: Resetting to invalid mark
| at BufferedInputStream.implReset (BufferedInputStream.java:583)
| at BufferedInputStream.reset (BufferedInputStream.java:569)
| at (#6:1)
jshell> // it works as expected after setting the first mark
jshell> buffered.mark(1024)
jshell> buffered.reset()
Configuration
Client Configuration
Environment
- Client version: v0.9.4
- Language version: Java
Good day, @JD557!
It protects from sending request from a middle of input stream. Retries happen only in small number of cases - when data should not be sent but it may be read from input stream.