On Tue, Sep 22, 2015 at 6:22 AM, Richard Hipp <drh at sqlite.org> wrote:
> On 9/22/15, Hugues Bruant <hugues at aerofs.com> wrote:
> >>
> >> If you can capture a malfunctioning trace, and send in the database
> >> file and the SQL statement that is running, that should allow us to
> >> localize the problem.
> >>
> >
> > Trace for the failing UPDATE:
> >
> > cv_s=1
>
> The trace shows that you have this value set to 0, not 1. And
> apparently there is no row with cv_s=0 and cv_o=b8b9f4...
>
That is rather curious.
The method where the UPDATE fails is as follows:
public void setVersion_(SIndex sidx, OID oid, long version, Trans t) throws
SQLException
{
try (Statement s = c().createStatement()) {
s.execute("pragma vdbe_debug=ON");
}
int n = exec(_pswSetVersion, ps -> {
ps.setLong(1, version);
ps.setInt(2, sidx.getInt());
ps.setBytes(3, oid.getBytes());
return ps.executeUpdate();
});
try (Statement s = c().createStatement()) {
s.execute("pragma vdbe_debug=OFF");
}
if (n == 1) return;
if (version > 1) {
l.warn("{}{} {} {} {}", sidx, oid, version, getVersion_(sidx, oid),
n);
}
exec(_pswInsertVersion, ps -> {
ps.setInt(1, sidx.getInt());
ps.setBytes(2, oid.getBytes());
ps.setLong(3, version);
checkState(ps.executeUpdate() == 1);
return null;
});
}
SIndex sidx is just a boxed immutable integer. Its value is bound to the
UPDATE and the trace shows it to be 0
But the log line printed when the number of rows updated is zero clearly
shows the value to be 1 and this is further
confirmed by the fact that when bound to the INSERT, the value turns out to
be 1 (or there would be no constraint
violation).
This leaves essentially two places for the error to arise:
- sqlite3_bind_int
- somewhere in the JVM
I will add more logging and see if I can pinpoint the location where the
(incorrect) 0 value appears.