So I tracked down the commit which introduced the "truncated page is fine"
behaviour:

$ fossil info 647e3b156e
uuid:         647e3b156e32e37debd60b0079fc5a52bdc9b8c8 2009-03-28 06:59:41
UTC
parent:       1c6521e53b846eec2e046b1e9c04c60658b8e0e8 2009-03-27 15:26:03
UTC
child:        c9fa329f54736de517cddaf747595c9eca931f32 2009-03-28 07:03:42
UTC
tags:         trunk
comment:      Fix readDbPage() so that if an SQLITE_IOERR_SHORT_READ is
              encountered, the page content is zeroed. Ticket #3756. (CVS
6395)
              (user: danielk1977)



Based on (CVS 6395) I'm guessing this was pre-fossil. I can't find any
reference to ticket #3756 in the current system - is that still around or
lost forever?

-Rowan

On 14 January 2017 at 11:38, Rowan Worth <row...@dug.com> wrote:

> On 13 January 2017 at 22:59, David Raymond <david.raym...@tomtom.com>
> wrote:
>
>> My view is that the general thinking of the program here is simply: "just
>> don't make things worse." It can't help what pragmas (ie
>> ignore_check_constraints, writable_schema etc) others may have turned on
>> for their connections, or what sort of junk was there when it arrived.
>
>
> ignore_check_constraints doesn't seem to affect NOT NULL constraints:
>
>   sqlite> create table a(b INTEGER NOT NULL);
>   sqlite> insert into a values(NULL);
>   Error: NOT NULL constraint failed: a.b
>   sqlite> pragma ignore_check_constraints = 1;
>   sqlite> insert into a values(NULL);
>   Error: NOT NULL constraint failed: a.b
>
> I can't see any pragmas that do? writable_schema is fair, but the
> advertised procedure[1] _does_ come with the warning that a mistake using
> it will corrupt your database. It's not entirely unreasonable to classify
> "using writable_schema to add a NOT NULL constraint to a column without
> ensuring all rows are NOT NULL" as a mistake. I also agree that calling the
> result corrupted is not an ideal result, but it provides benefits in the
> form of sanity checks elsewhere.
>
> [1] https://www.sqlite.org/lang_altertable.html#otheralter
>
> I haven't figured out any other way to get a NULL value into a NOT NULL
> column. The regular ALTER TABLE command refuses:
>
>   sqlite> alter table a add column c INTEGER NOT NULL;
>   Error: Cannot add a NOT NULL column with default value NULL
>
> Nor does sqlite allow them to propagate from tables affected by truncation
> as in my original post:
>
>   sqlite> create table table2 (C INTEGER NOT NULL);
>   sqlite> insert into table2 select a from test_table;
>   Error: NOT NULL constraint failed: table2.C
>
> As to the truncated page it would be kind of bad for it to say "hey,
>> someone else corrupted 28 bytes, so I won't give you info on the other 99%
>> that I can read just fine." All that being said though it might be nice to
>> know there was a noticed issue.
>>
>
> I don't buy this one at all. Especially as sqlite fills pages backwards
> (starting from the end), so a truncated page almost certainly represents
> lost user data. I can't see anything in the hardware assumptions[2] to
> suggest a truncated page is ever a valid configuration.
>
> [2] https://www.sqlite.org/atomiccommit.html#hardware
>
> It does clarify that sqlite goes to no effort to detect bit errors and the
> like, but again I'm not asking for checksums or error correction codes. It
> also says "SQLite assumes that the data it reads is exactly the same data
> that it previously wrote". I'm pretty sure it never does any write that is
> not a multiple of the page size, so a short read due to EOF is a pretty
> good indication that this assumption has been violated!
>
>
>> Also, quietly dealing with a different number of fields found in the file
>> compared to what it parsed from the schema is how it handles "alter table
>> add column" without needing to rewrite the entire table when you do that.
>> That might also explain why you can see nulls for fields that got
>> truncated.
>
>
> Nope, see above. If you can provide me a legitimate way to violate a NOT
> NULL constraint then I'll happily concede that the presence of a NULL cell
> cannot be trusted as an indicator of corruption, but so far all my attempts
> have failed. And at this stage no I don't consider shooting yourself in the
> foot with writable_schema a legitimate way :P
>
> I've been testing with 3.14.2 - if it was possible/easier in previous
> versions to violate NOT NULL then backwards compatibility may also rule
> this out.
>
> -Rowan
>
>
>
>   sqlite3 test.db "CREATE TABLE test_table (A INT4 NOT NULL, B INT4 NOT
>> NULL);"
>>  for N in `seq 1 10`
>>  do
>>      sqlite3 test.db "INSERT INTO test_table (A, B) VALUES ($N, $N);"
>>  done
>>
>>  dd if=test.db of=cropped.db bs=2020 count=1
>>  sqlite3 cropped.db "SELECT * FROM test_table;"
>>
>
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to