nbenn opened a new issue, #4820:
URL: https://github.com/apache/arrow-adbc/issues/4820
Executed without a result stream, a statement that changes no rows reports
the row count of the previous `INSERT`, `UPDATE` or `DELETE` in the SQLite
driver. With the driver built from `main` at f1378d6 against SQLite 3.45.1:
```r
library(adbcdrivermanager)
db <- adbc_database_init(adbc_driver("adbc_driver_sqlite"), uri = ":memory:")
con <- adbc_connection_init(db)
execute <- function(sql) {
stmt <- adbc_statement_init(con)
on.exit(adbc_statement_release(stmt))
adbc_statement_set_sql_query(stmt, sql)
adbc_statement_execute_query(stmt)
}
execute("CREATE TABLE t (a INTEGER)")
#> [1] 0
execute("INSERT INTO t VALUES (1), (2), (3)")
#> [1] 3
execute("CREATE TABLE u (b INTEGER)")
#> [1] 3
execute("DROP TABLE u")
#> [1] 3
```
The update path adds `sqlite3_changes()` for every statement without result
columns
([source](https://github.com/apache/arrow-adbc/blob/f1378d664b61ce65f25a54c3b863aa62ea9d2480/c/driver/sqlite/sqlite.cc#L1127-L1129)),
and `sqlite3_changes()` returns the count of the most recent completed
`INSERT`, `UPDATE` or `DELETE`, which other statements leave unchanged
([docs](https://www.sqlite.org/c3ref/changes.html)). It came up in adbi, which
runs statements with a result stream and so gets `-1` from every one of them
(r-dbi/adbi#92); running them without a stream fixes that, but passes these
counts on for DDL.
RSQLite avoids this by taking the difference in `sqlite3_total_changes()`
across the statement
([source](https://github.com/r-dbi/RSQLite/blob/201287ef6db6dce4d5c3e13b1ae6453ea0f570f3/src/SqliteResultImpl.cpp#L123)).
Counting `sqlite3_changes()` only when that total moved does the same here:
```diff
+ const int total_changes = sqlite3_total_changes(conn_);
while (sqlite3_step(stmt_) == SQLITE_ROW) {
output_rows++;
}
- if (sqlite3_column_count(stmt_) == 0) {
+ if (sqlite3_column_count(stmt_) == 0 &&
+ sqlite3_total_changes(conn_) != total_changes) {
changed_rows += sqlite3_changes(conn_);
}
```
With that change, the `CREATE TABLE` and `DROP TABLE` above report 0, as
does a `CREATE INDEX`. The DML counts I checked stay as they were: 3 for an
`INSERT` of 3 rows whose trigger inserts 3 more, 3 for a bound `INSERT` of 3
rows, 0 for an `UPDATE` that matches no rows, and 5 for a `DELETE` of 5. I have
not run the driver's test suite with it. I can open a PR.
This report was drafted with an AI assistant; the code above was run as
shown.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]