diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/intck/intck1.test | 2 | ||||
-rw-r--r-- | ext/intck/intck_common.tcl | 4 | ||||
-rw-r--r-- | ext/intck/intckcorrupt.test | 235 | ||||
-rw-r--r-- | ext/intck/sqlite3intck.c | 53 | ||||
-rw-r--r-- | ext/intck/sqlite3intck.h | 3 | ||||
-rw-r--r-- | ext/intck/test_intck.c | 11 |
6 files changed, 285 insertions, 23 deletions
diff --git a/ext/intck/intck1.test b/ext/intck/intck1.test index 7f60f1fdc..4110ece04 100644 --- a/ext/intck/intck1.test +++ b/ext/intck/intck1.test @@ -106,7 +106,7 @@ do_eqp_test 1.6.2 { reset_db do_test 2.0 { - set ic [sqlite3_intck db main ""] + set ic [sqlite3_intck db main] $ic close } {} diff --git a/ext/intck/intck_common.tcl b/ext/intck/intck_common.tcl index 757ca82b3..f00a465b3 100644 --- a/ext/intck/intck_common.tcl +++ b/ext/intck/intck_common.tcl @@ -16,7 +16,7 @@ if {![info exists testdir]} { source $testdir/tester.tcl proc do_intck {db {bSuspend 0}} { - set ic [sqlite3_intck $db main ""] + set ic [sqlite3_intck $db main] set ret [list] while {"SQLITE_OK"==[$ic step]} { @@ -37,7 +37,7 @@ proc do_intck {db {bSuspend 0}} { } proc intck_sql {db tbl} { - set ic [sqlite3_intck $db main ""] + set ic [sqlite3_intck $db main] set sql [$ic test_sql $tbl] $ic close return $sql diff --git a/ext/intck/intckcorrupt.test b/ext/intck/intckcorrupt.test new file mode 100644 index 000000000..40f009f9c --- /dev/null +++ b/ext/intck/intckcorrupt.test @@ -0,0 +1,235 @@ +# 2024 Feb 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the intck extensions response +# to corruption at the b-tree level. +# + +source [file join [file dirname [info script]] intck_common.tcl] +set testprefix intckcorrupt + +#------------------------------------------------------------------------- +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 356352 pagesize 4096 filename crash-acaae0347204ae.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 d0 00 00 00 .....@ ........ +| 32: 40 00 ea 00 00 00 00 00 00 40 00 00 00 40 00 00 @........@...@.. +| 96: 00 00 00 00 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f ...............O +| 112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17 ............^... +| 3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72 .....tablet1_par +| 3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45 entt1_parent.CRE +| 3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61 ATE TABLE .t1_pa +| 3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54 rent.(nodeno INT +| 3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17 ,parentnode)Q... +| 3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65 ....tablet1_node +| 3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54 t1_node.CREATE T +| 3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e ABLE .t1_node.(n +| 3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52 odeno INTEGER PR +| 3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c IMARY KEY,data). +| 3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f ........tablet1_ +| 3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52 rowidt1_rowid.CR +| 3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72 EATE TABLE .t1_r +| 3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45 owid.(rowid INTE +| 3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c GER PRIMARY KEY, +| 4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07 nodeno,a0,a1)Q.. +| 4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43 ......tablet1t1C +| 4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 REATE VIRTUAL TA +| 4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72 BLE t1 USING rtr +| 4064: 65 65 28 69 64 2c 78 30 20 50 52 49 4d 41 52 59 ee(id,x0 PRIMARY +| 4080: 20 4b 45 59 2c 70 61 72 65 6e 74 6e 6f 64 65 29 KEY,parentnode) +| page 2 offset 4096 +| 0: 51 03 06 17 1b 1b 01 7b 74 61 62 6c 65 74 31 5f Q.......tablet1_ +| 16: 6e 6f 64 65 74 31 5f 6e 6f 64 65 03 43 52 45 41 nodet1_node.CREA +| 32: 54 45 20 54 41 42 4c 45 20 22 74 31 5f 6e 6f 64 TE TABLE .t1_nod +| 48: 65 22 28 6e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 e.(nodeno INTEGE +| 64: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 R PRIMARY KEY,da +| 80: 74 61 29 5c 02 07 17 1d 1d 01 81 0b 74 61 62 6c ta).........tabl +| 96: 65 74 31 5f 72 6f 77 69 64 74 31 5f 72 6f 77 69 et1_rowidt1_rowi +| 112: 64 02 43 52 45 41 54 45 20 54 41 42 4c 45 00 00 d.CREATE TABLE.. +| 128: 01 0a 02 00 00 00 01 0e 0d 00 00 00 00 24 0e 0d .............$.. +| 144: 0c 1a 06 85 50 46 60 27 70 08 00 00 00 00 00 00 ....PF`'p....... +| 3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f ..............to +| 3840: 79 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74 y half.....#.bot +| 3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72 tom half.....!.r +| 3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00 ight half....... +| 3888: 6c 65 66 74 20 43 15 f6 e6 f6 46 50 34 35 24 54 left C....FP45$T +| 3904: 15 44 52 05 44 14 24 c4 52 02 27 43 15 f6 e6 f6 .DR.D.$.R.'C.... +| 3920: 46 52 22 8e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 FR..odeno INTEGE +| 3936: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 R PRIMARY KEY,da +| 3952: 74 61 29 5c 02 07 17 1d 1d 01 81 0b 74 61 62 6c ta).........tabl +| 3968: 65 74 31 5f 72 6f 74 74 6f 6d 20 65 64 67 65 0f et1_rottom edge. +| 3984: 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67 65 ....!.right edge +| 4000: 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67 65 .......left edge +| 4016: 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04 05 .......center... +| 4032: 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74 20 ..1.upper-right +| 4048: 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f 77 corner.....1.low +| 4064: 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72 16 er-right corner. +| 4080: 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66 74 ..../.upper-left +| page 3 offset 8192 +| 0: 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 01 8c 6f corner...../..o +| 16: 77 65 72 2d 6c 53 51 4c 69 74 65 20 66 6f 72 6d wer-lSQLite form +| 32: 61 74 20 33 00 10 00 01 01 00 40 20 20 00 00 00 at 3......@ ... +| 48: 00 00 00 00 2f 00 00 0d eb 13 00 00 00 03 00 00 ..../........... +| 64: 00 04 00 00 00 00 00 00 00 06 00 00 00 01 00 00 ................ +| 80: 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................ +| page 6 offset 20480 +| 128: 00 00 00 00 00 00 00 00 97 3d 04 ae 7c 01 00 00 .........=..|... +| 624: 00 00 00 00 00 00 21 97 3d 04 ae 7c 01 00 00 00 ......!.=..|.... +| 1120: 00 00 00 00 00 20 97 3d 04 ae 7c 01 00 00 00 00 ..... .=..|..... +| 1616: 00 00 00 00 1f 97 3d 04 ae 7c 01 00 00 00 00 00 ......=..|...... +| 2112: 00 00 00 1e 97 3d 04 ae 7c 01 00 00 00 00 00 00 .....=..|....... +| 2608: 00 00 1d 97 d3 d0 4a e7 c0 00 00 00 00 00 00 00 ......J......... +| 3088: 00 00 00 00 00 00 00 00 00 00 00 00 01 f3 00 00 ................ +| 3600: 23 97 3d 04 ae 7c 01 00 00 00 00 00 00 00 00 00 #.=..|.......... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 26 ...............& +| page 8 offset 28672 +| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| 1072: 97 4d 1e 14 00 ae 7c 00 00 00 00 00 00 00 00 00 .M....|......... +| 1088: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ +| page 10 offset 36864 +| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| 1072: 9a ee c1 80 fd 78 1f ce 1b ae eb b4 00 00 00 00 .....x.......... +| 1088: 13 20 ff 20 00 70 00 00 00 60 50 00 00 00 11 e0 . . .p...`P..... +| 1104: 00 00 00 70 00 00 00 60 50 05 35 14 c6 97 46 52 ...p...`P.5...FR +| 1120: 06 66 f7 26 d6 17 42 03 30 01 00 00 10 10 04 02 .f.&..B.0....... +| 1136: 02 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 .........@...... +| 1152: 00 00 00 00 00 40 00 00 00 40 00 00 00 00 00 00 .....@...@...... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 ................ +| page 12 offset 45056 +| 0: 0d 00 00 00 01 04 30 00 04 30 e1 b4 30 97 4d 46 ......0..0..0.MF +| 16: 14 00 ae 7c 00 00 00 00 00 00 00 03 00 00 43 00 ...|..........C. +| page 47 offset 188416 +| 2512: 00 00 00 00 00 00 00 00 be 00 00 00 00 00 00 00 ................ +| page 87 offset 352256 +| 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................ +| end crash-acaae0347204ae.db +}]} {} + +do_intck_test 1.1 { + {corruption found while reading database schema} +} + +#------------------------------------------------------------------------- +reset_db +do_test 2.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 28672 pagesize 4096 filename crash-3afa1ca9e9c1bd.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 96: 00 00 00 00 0d 00 00 00 06 0e 88 00 0f b8 0f 6d ...............m +| 112: 0f 3a 0f 0b 0e d5 0e 88 01 00 00 00 00 00 00 00 .:.............. +| 3712: 00 00 00 00 00 00 00 00 4b 06 06 17 25 25 01 5b ........K...%%.[ +| 3728: 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 74 61 74 tablesqlite_stat +| 3744: 31 73 71 6c 69 74 65 5f 73 74 61 74 31 07 43 52 1sqlite_stat1.CR +| 3760: 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c 69 74 EATE TABLE sqlit +| 3776: 65 5f 73 74 61 74 31 28 74 62 6c 2c 69 64 78 2c e_stat1(tbl,idx, +| 3792: 73 74 61 74 29 34 05 06 17 13 11 01 53 69 6e 64 stat)4......Sind +| 3808: 65 78 63 31 63 63 31 06 43 52 45 41 54 45 20 55 exc1cc1.CREATE U +| 3824: 4e 49 51 55 45 20 49 4e 44 45 58 20 63 31 63 20 NIQUE INDEX c1c +| 3840: 4f 4e 20 63 31 28 63 2c 20 62 29 2d 04 06 17 13 ON c1(c, b)-.... +| 3856: 11 01 45 69 6e 64 65 78 63 31 64 63 31 05 43 52 ..Eindexc1dc1.CR +| 3872: 45 41 54 45 20 49 4e 44 45 58 20 63 31 64 20 4f EATE INDEX c1d O +| 3888: 4e 20 63 31 28 64 2c 20 62 29 31 03 06 17 13 11 N c1(d, b)1..... +| 3904: 01 4d 69 6e 64 65 78 62 31 63 62 31 05 43 52 45 .Mindexb1cb1.CRE +| 3920: 41 54 45 20 55 4e 49 51 55 45 20 49 4e 44 45 58 ATE UNIQUE INDEX +| 3936: 20 62 31 63 20 4f 4e 20 62 31 28 63 29 49 02 06 b1c ON b1(c)I.. +| 3952: 17 11 11 0f 7f 74 61 62 6c 65 63 31 63 31 03 43 .....tablec1c1.C +| 3968: 52 45 41 54 45 20 54 41 42 4c 45 20 63 31 28 61 REATE TABLE c1(a +| 3984: 20 49 4e 54 20 50 52 49 4d 41 52 59 20 4b 45 59 INT PRIMARY KEY +| 4000: 2c 20 62 2c 20 63 2c 20 64 29 20 57 49 54 48 4f , b, c, d) WITHO +| 4016: 55 54 20 52 4f 57 49 44 46 01 06 17 11 11 01 79 UT ROWIDF......y +| 4032: 74 61 62 6c 65 62 31 62 31 02 43 52 45 41 54 45 tableb1b1.CREATE +| 4048: 20 54 41 42 4c 45 20 62 31 28 61 20 49 4e 54 20 TABLE b1(a INT +| 4064: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 2c 20 PRIMARY KEY, b, +| 4080: 63 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 c) WITHOUT ROWID +| page 2 offset 4096 +| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f e2 ................ +| 16: 0f da 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................ +| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 06 ................ +| 4048: 67 07 07 04 01 0f 01 06 66 06 07 04 01 0f 01 05 g.......f....... +| 4064: 65 05 07 04 01 0f 01 04 64 04 07 04 01 0f 01 03 e.......d....... +| 4080: 63 03 07 04 01 0f 01 02 62 0f 05 04 09 0f 09 61 c.......b......a +| page 3 offset 8192 +| 0: 0a 00 00 00 07 0f bd 00 0f f9 0f ef 0f e5 0f db ................ +| 16: 0f d1 0f c7 0f bd 00 00 00 00 01 00 00 00 00 00 ................ +| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 09 05 01 ................ +| 4032: 0f 01 01 07 61 07 07 09 05 01 0f 01 01 06 61 06 ....a.........a. +| 4048: 06 09 05 01 0f 01 01 05 61 05 05 09 05 01 0f 01 ........a....... +| 4064: 01 04 61 04 04 09 05 01 0f 01 01 03 61 03 03 09 ..a.........a... +| 4080: 05 01 0f 01 01 02 61 0f 02 06 05 09 0f 09 09 61 ......a........a +| page 4 offset 12288 +| 0: 0a 00 00 00 07 0f d8 00 0f fc 0f f0 0f ea 0f e4 ................ +| 16: 0f de 0f d8 0f f6 00 00 00 00 00 00 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 05 03 01 01 07 07 05 03 ................ +| 4064: 01 01 06 06 05 03 01 01 05 05 05 03 01 01 04 04 ................ +| 4080: 05 03 01 01 03 03 05 03 01 01 0f 02 03 03 09 09 ................ +| page 5 offset 16384 +| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f 00 ................ +| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07 ................ +| 4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05 a.......a....... +| 4064: 61 05 07 04 01 1f 01 04 61 04 07 04 01 0f 01 03 a.......a....... +| 4080: 61 03 07 04 01 0f 01 02 61 02 05 04 09 0f 09 61 a.......a......a +| page 6 offset 20480 +| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f ea 0f e2 00 00 ................ +| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07 ................ +| 4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05 a.......a....... +| 4064: 61 05 07 04 01 0f 01 04 61 04 07 04 01 0f 01 03 a.......a....... +| 4080: 61 03 07 04 01 0f 01 0f 61 02 05 04 09 0f 09 61 a.......a......a +| page 7 offset 24576 +| 0: 0d 00 00 00 05 0f 1c 00 0f f0 0f e0 0f d3 0f c5 ................ +| 16: 0f b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4016: 00 00 00 00 00 00 00 00 0b 05 04 11 11 13 62 31 ..............b1 +| 4032: 62 31 37 20 31 0c 04 04 11 13 13 62 31 62 31 63 b17 1......b1b1c +| 4048: 37 20 31 0b 03 04 11 11 13 63 31 63 31 37 20 31 7 1......c1c17 1 +| 4064: 0e 02 04 11 13 07 63 31 63 31 64 37 20 31 20 31 ......c1c1d7 1 1 +| 4080: 0e 01 04 11 13 17 63 31 63 31 63 37 20 31 00 00 ......c1c1c7 1.. +| end crash-3afa1ca9e9c1bd.db +}]} {} + +do_intck_test 2.1 { + {corruption found while reading database schema} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3); +} + +do_test 3.1 { + set pgno [db one {SELECT rootpage FROM sqlite_schema WHERE name='t1'}] + db close + hexio_write test.db [expr ($pgno-1)*1024] 0000 +} {2} + +sqlite3 db test.db +do_intck_test 3.2 { + {corruption found while scanning database object i1} + {corruption found while scanning database object t1} +} + +finish_test + + diff --git a/ext/intck/sqlite3intck.c b/ext/intck/sqlite3intck.c index 6d5452692..f23dbbd1d 100644 --- a/ext/intck/sqlite3intck.c +++ b/ext/intck/sqlite3intck.c @@ -35,6 +35,9 @@ struct sqlite3_intck { int nKeyVal; sqlite3_value **apKeyVal; + char *zMessage; + int bCorruptSchema; + int rc; /* Error code */ char *zErr; /* Error message */ char *zTestSql; /* Returned by sqlite3_intck_test_sql() */ @@ -67,12 +70,12 @@ static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zFmt, ...){ p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0); fflush(stdout); if( p->rc!=SQLITE_OK ){ -#if 1 +#if 0 printf("ERROR: %s\n", zSql); printf("MSG: %s\n", sqlite3_errmsg(p->db)); #endif if( sqlite3_error_offset(p->db)>=0 ){ -#if 1 +#if 0 int iOff = sqlite3_error_offset(p->db); printf("AT: %.40s\n", &zSql[iOff]); #endif @@ -208,12 +211,19 @@ static char *intckSavedKeyToText(sqlite3_intck *p){ return zRet; } +/* +** Find the next database object (table or index) to check. If successful, +** set sqlite3_intck.zObj to point to a nul-terminated buffer containing +** the object's name before returning. +*/ static void intckFindObject(sqlite3_intck *p){ sqlite3_stmt *pStmt = 0; char *zPrev = p->zObj; p->zObj = 0; assert( p->rc==SQLITE_OK ); + assert( p->pCheck==0 ); + pStmt = intckPrepare(p, "WITH tables(table_name) AS (" " SELECT name" @@ -735,7 +745,6 @@ static void intckCheckObject(sqlite3_intck *p){ int sqlite3_intck_open( sqlite3 *db, /* Database handle to operate on */ const char *zDbArg, /* "main", "temp" etc. */ - const char *zFile, /* Path to save-state db on disk (or NULL) */ sqlite3_intck **ppOut /* OUT: New integrity-check handle */ ){ sqlite3_intck *pNew = 0; @@ -760,10 +769,8 @@ int sqlite3_intck_open( return rc; } -int sqlite3_intck_close(sqlite3_intck *p){ - int rc = SQLITE_OK; +void sqlite3_intck_close(sqlite3_intck *p){ if( p ){ - rc = (p->rc==SQLITE_DONE ? SQLITE_OK : p->rc); if( p->db ){ sqlite3_create_function( p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0 @@ -775,11 +782,19 @@ int sqlite3_intck_close(sqlite3_intck *p){ sqlite3_free(p->zErr); sqlite3_free(p); } - return rc; } int sqlite3_intck_step(sqlite3_intck *p){ if( p->rc==SQLITE_OK ){ + + if( p->zMessage ){ + sqlite3_free(p->zMessage); + p->zMessage = 0; + } + + if( p->bCorruptSchema ){ + p->rc = SQLITE_DONE; + }else if( p->pCheck==0 ){ intckFindObject(p); if( p->rc==SQLITE_OK ){ @@ -788,19 +803,29 @@ int sqlite3_intck_step(sqlite3_intck *p){ }else{ p->rc = SQLITE_DONE; } + }else if( p->rc==SQLITE_CORRUPT ){ + p->rc = SQLITE_OK; + p->zMessage = intckStrdup(p, + "corruption found while reading database schema" + ); + p->bCorruptSchema = 1; } } - if( p->rc==SQLITE_OK ){ - assert( p->pCheck ); + if( p->pCheck ){ + assert( p->rc==SQLITE_OK ); if( sqlite3_step(p->pCheck)==SQLITE_ROW ){ /* Normal case, do nothing. */ }else{ - if( sqlite3_finalize(p->pCheck)!=SQLITE_OK ){ - intckSaveErrmsg(p); - } + intckFinalize(p, p->pCheck); p->pCheck = 0; p->nKeyVal = 0; + if( p->rc==SQLITE_CORRUPT ){ + p->rc = SQLITE_OK; + p->zMessage = intckMprintf(p, + "corruption found while scanning database object %s", p->zObj + ); + } } } } @@ -809,6 +834,10 @@ int sqlite3_intck_step(sqlite3_intck *p){ } const char *sqlite3_intck_message(sqlite3_intck *p){ + assert( p->pCheck==0 || p->zMessage==0 ); + if( p->zMessage ){ + return p->zMessage; + } if( p->pCheck ){ return (const char*)sqlite3_column_text(p->pCheck, 0); } diff --git a/ext/intck/sqlite3intck.h b/ext/intck/sqlite3intck.h index c7c24e42c..e39825fc7 100644 --- a/ext/intck/sqlite3intck.h +++ b/ext/intck/sqlite3intck.h @@ -25,11 +25,10 @@ typedef struct sqlite3_intck sqlite3_intck; int sqlite3_intck_open( sqlite3 *db, const char *zDb, - const char *zFile, sqlite3_intck **ppOut ); -int sqlite3_intck_close(sqlite3_intck*); +void sqlite3_intck_close(sqlite3_intck*); int sqlite3_intck_step(sqlite3_intck *pCk); diff --git a/ext/intck/test_intck.c b/ext/intck/test_intck.c index 75bcfa298..0e2aebf05 100644 --- a/ext/intck/test_intck.c +++ b/ext/intck/test_intck.c @@ -132,7 +132,7 @@ static void testIntckFree(void *clientData){ } /* -** tclcmd: sqlite3_intck DB DBNAME PATH +** tclcmd: sqlite3_intck DB DBNAME */ static int test_sqlite3_intck( void * clientData, @@ -149,8 +149,8 @@ static int test_sqlite3_intck( const char *zFile = 0; int rc = SQLITE_OK; - if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME PATH"); + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); return TCL_ERROR; } @@ -161,9 +161,8 @@ static int test_sqlite3_intck( return TCL_ERROR; } zDb = Tcl_GetString(objv[2]); - zFile = Tcl_GetString(objv[3]); - rc = sqlite3_intck_open(db, zDb, zFile, &p->intck); + rc = sqlite3_intck_open(db, zDb, &p->intck); if( rc!=SQLITE_OK ){ ckfree(p); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errstr(rc), -1)); @@ -207,7 +206,7 @@ static int test_do_intck( pRet = Tcl_NewObj(); Tcl_IncrRefCount(pRet); - rc = sqlite3_intck_open(db, zDb, 0, &pCk); + rc = sqlite3_intck_open(db, zDb, &pCk); if( rc==SQLITE_OK ){ while( sqlite3_intck_step(pCk)==SQLITE_OK ){ const char *zMsg = sqlite3_intck_message(pCk); |