ClickHouse / ClickHouse/clickhouse-java
InputStream `reset()` can fail on retries for BufferedInputStreams
- Dominant language
- Java
- Stars
- 1.6k
- Forks
- 636
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 28
Description
## 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
```java
Failed to reset stream before next attempt
Caused by: Exception java.io.IOException: Resetting to invalid mark
```
### Expected Behaviour
### Code Example
```java
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
```java
```
#### Environment
* Client version: v0.9.4
* Language version: Java
Contributor guide
Assessment
This issue has not been assessed yet.