ClickHouse / ClickHouse/clickhouse-java

[r2dbc] getRowsUpdated() returns 0 for successful INSERT…SELECT — needs reliable written_rows

Đang mở
#2,860 6 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Java
Star
1.6k
Fork
636
Merge trung bình
2 ngày 23 giờ
Pull request đã merge (30 ngày)
29

Mô tả

## Summary

`ClickHouseResult.getRowsUpdated()` in `clickhouse-r2dbc` returns 0 for
successful `INSERT INTO … SELECT FROM …` queries that did write rows. This
makes it impossible to reliably distinguish "INSERT…SELECT wrote 0 rows
because the SELECT produced none" from "INSERT…SELECT wrote N rows but the
driver reported 0" at the application layer.

The same row count appears correctly in `system.query_log.written_rows`
server-side, and the HTTP `X-ClickHouse-Summary` header also carries an
accurate `written_rows` once the query finishes. The information exists; the
driver just doesn't expose it via the standard R2DBC `Result.getRowsUpdated()`
contract for this query shape.

## Reproduction

- Driver: `com.clickhouse:clickhouse-r2dbc:0.9.0` (also reproduces on 0.8.x)
- Server: ClickHouse 25.3
- Query shape: `INSERT INTO target_table (...) SELECT ... FROM source_table WHERE ...`
- Connection settings: `async_insert=1, wait_for_async_insert=1`
(per docs, `async_insert` is a no-op for `INSERT…SELECT`, but we set it
globally for the `INSERT VALUES` path on the same connection)

```java
Flux.from(statement.execute())
.flatMap(Result::getRowsUpdated) // emits 0 even when N rows were inserted
.reduce(0L, Long::sum)
// observed: returns 0
```

Verifying server-side after the query finishes:

```sql
SELECT written_rows
FROM system.query_log
WHERE query_id = '...' AND type = 'QueryFinish';
-- returns N (the correct count)
```

## Root cause

Looking at `ClickHouseResult` constructor (current `main`):

```java
Mono updatedCount = Mono.just(response)
.map(ClickHouseResponse::getSummary)
.map(ClickHouseResponseSummary::getProgress)
.map(ClickHouseResponseSummary.Progress::getWrittenRows)
.map(UpdateCount::new);
```

The driver reads `written_rows` from `Summary.getProgress()`, which is the
**interim progress event** snapshot — not the final summary. For
`INSERT…SELECT` queries, a definitive post-completion written_rows is
typically reflected in `Summary.getStatistics()` (or in a final progress
event that doesn't always land before the subscriber observes completion).

`ClickHouseResponseSummary` exposes both `getProgress()` and `getStatistics()`,
and the top-level `getWrittenRows()` delegates to progress.

## Use case

Detecting at the application layer when an `INSERT…SELECT` wrote zero rows
(to surface inconsistency conditions before committing dependent state).
Since `getRowsUpdated()` can return 0 even on success, the check fires
false positives.

## Asks

Any one of the following would unblock us:

1. Source `getRowsUpdated()` from `Summary.getStatistics()` (or whichever
field is authoritative post-completion) instead of from `Summary.getProgress()`.
2. Expose the raw `ClickHouseResponseSummary` from `ClickHouseResult` (or a
similar handle), so callers can read the final fields themselves.
3. Document the current semantics so applications know not to rely on
`getRowsUpdated()` for `INSERT…SELECT`.

Happy to send a PR for (1) or (2) — please confirm which direction you'd
prefer.

## Environment

- `clickhouse-r2dbc`: 0.9.0
- `clickhouse-client` / `clickhouse-http-client`: 0.9.0
- ClickHouse server: 25.3.x
- Connection: HTTP transport

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu trong ClickHouseResult và theo dõi cách ClickHouseResponseSummary.getProgress(), getStatistics() và getWrittenRows() ở cấp cao nhất cung cấp UpdateCount. Tái hiện một truy vấn INSERT INTO … SELECT bằng HTTP transport, sau đó so sánh getRowsUpdated() với giá trị written_rows cuối cùng. Hoàn tất khi giá trị có tính xác thực được chọn sau khi hoàn thành được cung cấp một cách đáng tin cậy, cùng với kiểm thử hồi quy cho một INSERT…SELECT thành công.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
java
Lĩnh vực
databases
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
52/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.