|Title:||Debug assertion sqlite3VdbeMemAboutToChange: Assertion `(mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z)' failed (2)|
|Last Modified:||2019-12-23 02:30:51|
|Version Found In:||3.30.0|
mrigger added on 2019-12-22 23:05:59:
Consider the following test case:
PRAGMA encoding = 'UTF16'; CREATE TABLE t0(c0 TEXT); CREATE INDEX i0 ON t0(0 LIKE COALESCE(c0, 0)); INSERT INTO t0(c0) VALUES (0), (0); -- sqlite3.c:75871: sqlite3VdbeMemAboutToChange: Assertion `(mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z)' failed.
When compiling with -DSQLITE_DEBUG, the INSERT triggers an assertion error. The assert triggered seems to be the same as in [5ad2aa6921].
drh added on 2019-12-23 02:30:51:
This is a deficiency in testing and verification logic only. Release builds that omit the testing and verification logic appear to work correctly.
The sqlite3VdbeMemAboutToChange() subsystem attempts to verify that after a shallow copy (an OP_SCopy) from one register to another, the source register does not change before the last access of the destination register. A "shallow copy" means that large strings or BLOBs are copied by reference instead of by value. Shallow copies are a performance optimization.
No actual defects were discovered. In other words, no examples of doing the following illegal operation were found:
To put it another way, this ticket describes a false-positive in the mechanism used to detect problems in shallow copies such as the above.
A previous ticket [5ad2aa6921faa1ee] also described a similar false-positive. The initial fix to that prior ticket was to change the shallow-copy into a deep-copy (change a copy-by-reference into a copy-by-value), thus avoiding the false-positive. With the enhancements to sqlite3VdbeMemAboutToChange() logic to reduce the number of false-positives, the fix for [5ad2aa6921faa1ee] could be backed out since the enhancements to the sqlite3VdbeMemAboutToChange() mechanism in check-in [5ad2aa6921faa1ee] fix both false-positives.