Skip to content
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

Fix result of get_affected_rows() after bulk operations #1199

Merged
merged 4 commits into from
Jan 29, 2025

Conversation

vadz
Copy link
Member

@vadz vadz commented Jan 28, 2025

Make ODBC and SQLite3 backends behaviour consistent with the other ones (and more useful).

vadz added 2 commits January 28, 2025 16:06
This replaces the code originally added in 5254f96 (ODBC support for
get_affected_rows() during bulk operations., 2013-03-11) and amended
later in ed37399 (Fix ODBC backend get_affected_rows() when using
FreeTDS driver., 2015-03-17) and e7e7fb7 (Return -1 from
get_affected_rows() in ODBC backend if unknown, 2017-07-21) with a
simpler and more correct version using per-row status array that is
filled in by the driver if we set SQL_ATTR_PARAM_STATUS_PTR.

It also makes the ODBC backend behaviour more compatible with the other
backends when using current versions of FreeTDS drivers, which didn't
return SQL_ERROR correctly when _not_ using status array in case of
partial failure (see FreeTDS/freetds#626) and
this will allow to make the get_affected_rows() unit test more precise,
once all the problems related to it are fixed in the other backends too.

In the meanwhile, already remove the note about this function sometimes
not returning the correct value when using ODBC as this shouldn't be the
case any longer.
This function always returned 0 even if some rows were updated because
rowsAffectedBulkTemp was never copied into rowsAffectedBulk_ in this
case, i.e. when load_one() threw an exception.

Fix this by just getting rid of this temporary variable and updating
rowsAffectedBulk_ directly, this seems to be much simpler than this
code, added back in c97a666 (SQLite3 support for get_affected_rows() in
bulk operations., 2013-03-11), and is more correct.
@vadz vadz force-pushed the fix-rows-affected-bulk branch 2 times, most recently from e4b8a7d to 1759546 Compare January 28, 2025 17:33
vadz added 2 commits January 29, 2025 00:28
The unit test relies on failing to insert "a" into an integer column but
SQLite is perfectly fine with doing this by default, so use an explicit
CHECK constraint to prevent this from succeeding and to make it behave
in the same way as the other databases.
Check that a partial update does throw an exception instead of checking
that it may throw it and check that get_affected_rows() returns the
actual number of affected rows instead of returning something non zero.

The only remaining exclusion is the PostgreSQL ODBC driver which just
seems to be buggy, notably in its versions < 13.02 when it inserted
valid rows into the database but still returned fatal error (with later
versions it doesn't insert anything, which is inconsistent with the
other drivers and unhelpful, but not quite as bad).
@vadz vadz force-pushed the fix-rows-affected-bulk branch from 1759546 to 37535c2 Compare January 28, 2025 23:28
@vadz vadz merged commit 082b618 into SOCI:master Jan 29, 2025
16 checks passed
@vadz vadz deleted the fix-rows-affected-bulk branch January 29, 2025 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant