aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <>2021-10-01 02:16:52 +0000
committerdrh <>2021-10-01 02:16:52 +0000
commit817424fe377dd4980f23a37125da8f39abdaba1c (patch)
tree7d52741b38a254d143147778a12e4fc6863e4fa1
parentf06db3e8929e36f7686ccc8f9f138359c6b12e80 (diff)
parentafaa660aef3d596fabbbcf6e99746294f77dbafa (diff)
downloadsqlite-817424fe377dd4980f23a37125da8f39abdaba1c.tar.gz
sqlite-817424fe377dd4980f23a37125da8f39abdaba1c.zip
Merge updates from trunk
FossilOrigin-Name: 35351371c5e9602dec210ad0926ff8a1a269556ce1a166e81eb0543938e0c57e
-rw-r--r--ext/fts5/fts5_index.c5
-rw-r--r--ext/fts5/test/fts5corrupt5.test244
-rw-r--r--ext/rtree/rtreedoc.test22
-rw-r--r--ext/rtree/rtreedoc3.test292
-rw-r--r--ext/rtree/test_rtreedoc.c129
-rw-r--r--manifest31
-rw-r--r--manifest.uuid2
-rw-r--r--src/alter.c6
-rw-r--r--src/dbstat.c14
-rw-r--r--src/expr.c14
-rw-r--r--src/select.c4
-rw-r--r--test/altertab3.test16
12 files changed, 733 insertions, 46 deletions
diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c
index 0291704f4..40658a871 100644
--- a/ext/fts5/fts5_index.c
+++ b/ext/fts5/fts5_index.c
@@ -2213,6 +2213,10 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
pIter->pLeaf = pLast;
pIter->iLeafPgno = pgnoLast;
iOff = fts5LeafFirstRowidOff(pLast);
+ if( iOff>pLast->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
@@ -2221,7 +2225,6 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
}else{
pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
}
-
}
fts5SegIterReverseInitPage(p, pIter);
diff --git a/ext/fts5/test/fts5corrupt5.test b/ext/fts5/test/fts5corrupt5.test
new file mode 100644
index 000000000..062e826f5
--- /dev/null
+++ b/ext/fts5/test/fts5corrupt5.test
@@ -0,0 +1,244 @@
+# 2015 Apr 24
+#
+# 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.
+#
+#***********************************************************************
+#
+# This file tests that FTS5 handles corrupt databases (i.e. internal
+# inconsistencies in the backing tables) correctly. In this case
+# "correctly" means without crashing.
+#
+
+source [file join [file dirname [info script]] fts5_common.tcl]
+set testprefix fts5corrupt3
+
+# If SQLITE_ENABLE_FTS5 is defined, omit this file.
+ifcapable !fts5 {
+ finish_test
+ return
+}
+sqlite3_fts5_may_be_corrupt 1
+database_may_be_corrupt
+
+#-------------------------------------------------------------------------
+# dbsqlfuzz crash-0f47112aa7520cf08c6a835a88fdff8c2a32a188
+#
+reset_db
+do_test 1.0 {
+ sqlite3 db {}
+ db deserialize [decode_hexdb {
+.open --hexdb
+| size 24576 pagesize 4096 filename crash-0f47112aa7520c.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 00 .....@ ........
+| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
+| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
+| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
+| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
+| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
+| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
+| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
+| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
+| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
+| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
+| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
+| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
+| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
+| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
+| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
+| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
+| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
+| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
+| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
+| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
+| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
+| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
+| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
+| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
+| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
+| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
+| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
+| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
+| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
+| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
+| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
+| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
+| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
+| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
+| page 2 offset 4096
+| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
+| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
+| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
+| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
+| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
+| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00 ...~.H..........
+| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
+| 2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12 0......5........
+| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
+| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
+| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
+| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
+| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
+| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
+| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
+| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
+| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
+| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
+| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
+| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
+| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
+| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
+| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
+| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
+| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
+| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
+| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
+| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
+| 2720: 01 02 05 01 00 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
+| 2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03 ......6......1f.
+| 2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80 ....i...........
+| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
+| 2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
+| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
+| 2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80 .0table.B.......
+| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
+| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
+| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
+| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
+| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
+| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
+| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
+| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
+| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
+| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
+| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
+| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
+| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
+| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
+| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
+| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
+| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32 .........<.....2
+| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
+| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
+| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
+| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
+| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
+| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 9e 00 ............<...
+| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
+| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
+| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
+| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
+| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
+| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
+| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
+| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
+| 3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02 ..0there.....11.
+| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
+| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
+| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
+| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
+| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
+| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
+| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
+| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
+| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
+| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
+| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
+| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
+| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
+| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
+| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p
+| 3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03 res.............
+| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
+| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
+| 3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01 ..<.....3.re....
+| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
+| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
+| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
+| 3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06 .....<.....2th..
+| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
+| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
+| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
+| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
+| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
+| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
+| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
+| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
+| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
+| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
+| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
+| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
+| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
+| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
+| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
+| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62 ............0dab
+| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
+| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
+| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
+| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
+| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
+| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66 .....0each.....f
+| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
+| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
+| page 3 offset 8192
+| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
+| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
+| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
+| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
+| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
+| 80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00 ................
+| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
+| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
+| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
+| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
+| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
+| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
+| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
+| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
+| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
+| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
+| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
+| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
+| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
+| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
+| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
+| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
+| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
+| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
+| 3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
+| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
+| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
+| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
+| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
+| 4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66 ..d...2i......2f
+| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
+| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
+| 4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
+| 4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00 ................
+| page 4 offset 12288
+| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
+| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
+| page 5 offset 16384
+| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
+| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
+| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
+| page 6 offset 20480
+| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+| 4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00 ................
+| end crash-0f47112aa7520c.db
+ }]
+} {}
+
+do_catchsql_test 1.1 {
+ SELECT * FROM t1('R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
+} {1 {database disk image is malformed}}
+
+sqlite3_fts5_may_be_corrupt 0
+finish_test
+
diff --git a/ext/rtree/rtreedoc.test b/ext/rtree/rtreedoc.test
index f22349628..d2b37428a 100644
--- a/ext/rtree/rtreedoc.test
+++ b/ext/rtree/rtreedoc.test
@@ -325,13 +325,13 @@ do_execsql_test 2.0 {
#
# Ordinary tables. With ordinary sqlite_schema entries.
do_execsql_test 2.1 {
- SELECT * FROM sqlite_schema WHERE sql NOT LIKE '%virtual%'
+ SELECT type, name, sql FROM sqlite_schema WHERE sql NOT LIKE '%virtual%'
} {
- table demo_index_rowid demo_index_rowid 2
+ table demo_index_rowid
{CREATE TABLE "demo_index_rowid"(rowid INTEGER PRIMARY KEY,nodeno)}
- table demo_index_node demo_index_node 3
+ table demo_index_node
{CREATE TABLE "demo_index_node"(nodeno INTEGER PRIMARY KEY,data)}
- table demo_index_parent demo_index_parent 4
+ table demo_index_parent
{CREATE TABLE "demo_index_parent"(nodeno INTEGER PRIMARY KEY,parentnode)}
}
@@ -925,7 +925,7 @@ set ::contained_in 0
do_vmstep_test 1.3 {
SELECT objname FROM demo_data
WHERE contained_in(demo_data.boundary, 35.37785, -80.77470);
-} {$step>4000}
+} {$step>3200}
# EVIDENCE-OF: R-40261-32799 The problem with this latter query is that
# it must apply the contained_in() function to all entries in the
@@ -1313,10 +1313,14 @@ foreach {tn nm} {
CREATE VIRTUAL TABLE $nm USING rtree(a,b,c,d,e);
"
- # EVIDENCE-OF: R-37699-54000 This is their schema: CREATE TABLE
- # %_node(nodeno INTEGER PRIMARY KEY, data BLOB) CREATE TABLE
- # %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) CREATE TABLE
- # %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
+ # EVIDENCE-OF: R-33789-46762 The content of an R*Tree index is actually
+ # stored in three ordinary SQLite tables with names derived from the
+ # name of the R*Tree.
+ #
+ # EVIDENCE-OF: R-39849-06566 This is their schema: CREATE TABLE
+ # %_node(nodeno INTEGER PRIMARY KEY, data) CREATE TABLE %_parent(nodeno
+ # INTEGER PRIMARY KEY, parentnode) CREATE TABLE %_rowid(rowid INTEGER
+ # PRIMARY KEY, nodeno)
#
# EVIDENCE-OF: R-07489-10051 The "%" in the name of each shadow table is
# replaced by the name of the R*Tree virtual table. So, if the name of
diff --git a/ext/rtree/rtreedoc3.test b/ext/rtree/rtreedoc3.test
new file mode 100644
index 000000000..0403409fa
--- /dev/null
+++ b/ext/rtree/rtreedoc3.test
@@ -0,0 +1,292 @@
+# 2021 September 13
+#
+# 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 r-tree extension.
+#
+
+if {![info exists testdir]} {
+ set testdir [file join [file dirname [info script]] .. .. test]
+}
+source [file join [file dirname [info script]] rtree_util.tcl]
+source $testdir/tester.tcl
+set testprefix rtreedoc3
+
+ifcapable !rtree {
+ finish_test
+ return
+}
+
+
+# This command assumes that the argument is a node blob for a 2 dimensional
+# i32 r-tree table. It decodes and returns a list of cells from the node
+# as a list. Each cell is itself a list of the following form:
+#
+# {$rowid $minX $maxX $minY $maxY}
+#
+# For internal (non-leaf) nodes, the rowid is replaced by the child node
+# number.
+#
+proc rnode_cells {aData} {
+ set nDim 2
+
+ set nData [string length $aData]
+ set nBytePerCell [expr (8 + 2*$nDim*4)]
+ binary scan [string range $aData 2 3] S nCell
+
+ set res [list]
+ for {set i 0} {$i < $nCell} {incr i} {
+ set iOff [expr $i*$nBytePerCell+4]
+ set cell [string range $aData $iOff [expr $iOff+$nBytePerCell-1]]
+ binary scan $cell WIIII rowid x1 x2 y1 y2
+ lappend res [list $rowid $x1 $x2 $y1 $y2]
+ }
+
+ return $res
+}
+
+# Interpret the first two bytes of the blob passed as the only parameter
+# as a 16-bit big-endian integer and return the value. If this blob is
+# the root node of an r-tree, this value is the height of the tree.
+#
+proc rnode_height {aData} {
+ binary scan [string range $aData 0 1] S nHeight
+ return $nHeight
+}
+
+# Return a blob containing node iNode of r-tree "rt".
+#
+proc rt_node_get {iNode} {
+ db one { SELECT data FROM rt_node WHERE nodeno=$iNode }
+}
+
+
+#--------------------------------------------------------------
+# API:
+#
+# pq_init
+# Initialize a new test.
+#
+# pq_test_callback
+# Invoked each time the xQueryCallback function is called. This Tcl
+# command checks that the arguments that SQLite passed to xQueryCallback
+# are as expected.
+#
+# pq_test_row
+# Invoked each time a row is returned. Checks that the row returned
+# was predicted by the documentation.
+#
+# DATA STRUCTURE:
+# The priority queue is stored as a Tcl list. The order of elements in
+# the list is unimportant - it is just used as a set here. Each element
+# in the priority queue is itself a list. The first element is the
+# priority value for the entry (a real). Following this is a list of
+# key-value pairs that make up the entries fields.
+#
+proc pq_init {} {
+ global Q
+ set Q(pri_queue) [list]
+
+ set nHeight [rnode_height [rt_node_get 1]]
+ set nCell [llength [rnode_cells [rt_node_get 1]]]
+
+ # EVIDENCE-OF: R-54708-13595 An R*Tree query is initialized by making
+ # the root node the only entry in a priority queue sorted by rScore.
+ lappend Q(pri_queue) [list 0.0 [list \
+ iLevel [expr $nHeight+1] \
+ iChild 1 \
+ iCurrent 0 \
+ ]]
+}
+
+proc pq_extract {} {
+ global Q
+ if {[llength $Q(pri_queue)]==0} {
+ error "priority queue is empty!"
+ }
+
+ # Find the priority queue entry with the lowest score.
+ #
+ # EVIDENCE-OF: R-47257-47871 Smaller scores are processed first.
+ set iBest 0
+ set rBestScore [lindex $Q(pri_queue) 0 0]
+ for {set ii 1} {$ii < [llength $Q(pri_queue)]} {incr ii} {
+ set rScore [expr [lindex $Q(pri_queue) $ii 0]]
+ if {$rScore<$rBestScore} {
+ set rBestScore $rScore
+ set iBest $ii
+ }
+ }
+
+ # Extract the entry with the lowest score from the queue and return it.
+ #
+ # EVIDENCE-OF: R-60002-49798 The query proceeds by extracting the entry
+ # from the priority queue that has the lowest score.
+ set ret [lindex $Q(pri_queue) $iBest]
+ set Q(pri_queue) [lreplace $Q(pri_queue) $iBest $iBest]
+
+ return $ret
+}
+
+proc pq_new_entry {rScore iLevel cell} {
+ global Q
+
+ set rowid_name "iChild"
+ if {$iLevel==0} { set rowid_name "iRowid" }
+
+ set kv [list]
+ lappend kv aCoord [lrange $cell 1 end]
+ lappend kv iLevel $iLevel
+
+ if {$iLevel==0} {
+ lappend kv iRowid [lindex $cell 0]
+ } else {
+ lappend kv iChild [lindex $cell 0]
+ lappend kv iCurrent 0
+ }
+
+ lappend Q(pri_queue) [list $rScore $kv]
+}
+
+proc pq_test_callback {L res} {
+ #pq_debug "pq_test_callback $L -> $res"
+ global Q
+
+ array set G $L ;# "Got" - as in stuff passed to xQuery
+
+ # EVIDENCE-OF: R-65127-42665 If the extracted priority queue entry is a
+ # node (a subtree), then the next child of that node is passed to the
+ # xQueryFunc callback.
+ #
+ # If it had been a leaf, the row should have been returned, instead of
+ # xQueryCallback being called on a child - as is happening here.
+ foreach {rParentScore parent} [pq_extract] {}
+ array set P $parent ;# "Parent" - as in parent of expected cell
+ if {$P(iLevel)==0} { error "query callback mismatch (1)" }
+ set child_node [rnode_cells [rt_node_get $P(iChild)]]
+ set expected_cell [lindex $child_node $P(iCurrent)]
+ set expected_coords [lrange $expected_cell 1 end]
+ if {[llength $expected_coords] != [llength $G(aCoord)]} {
+ puts [array get P]
+ puts "E: $expected_coords G: $G(aCoord)"
+ error "coordinate mismatch in query callback (1)"
+ }
+ foreach a [lrange $expected_cell 1 end] b $G(aCoord) {
+ if {$a!=$b} { error "coordinate mismatch in query callback (2)" }
+ }
+
+ # Check level is as expected
+ #
+ if {$G(iLevel) != $P(iLevel)-1} {
+ error "iLevel mismatch in query callback (1)"
+ }
+
+ # Unless the callback returned NOT_WITHIN, add the entry to the priority
+ # queue.
+ #
+ # EVIDENCE-OF: R-28754-35153 Those subelements for which the xQueryFunc
+ # callback sets eWithin to PARTLY_WITHIN or FULLY_WITHIN are added to
+ # the priority queue using the score supplied by the callback.
+ #
+ # EVIDENCE-OF: R-08681-45277 Subelements that return NOT_WITHIN are
+ # discarded.
+ set r [lindex $res 0]
+ set rScore [lindex $res 1]
+ if {$r!="fully" && $r!="partly" && $r!="not"} {
+ error "unknown result: $r - expected \"fully\", \"partly\" or \"not\""
+ }
+ if {$r!="not"} {
+ pq_new_entry $rScore [expr $P(iLevel)-1] $expected_cell
+ }
+
+ # EVIDENCE-OF: R-07194-63805 If the node has more children then it is
+ # returned to the priority queue. Otherwise it is discarded.
+ incr P(iCurrent)
+ if {$P(iCurrent)<[llength $child_node]} {
+ lappend Q(pri_queue) [list $rParentScore [array get P]]
+ }
+}
+
+proc pq_test_result {id x1 x2 y1 y2} {
+ #pq_debug "pq_test_result $id $x1 $x2 $y1 $y2"
+ foreach {rScore next} [pq_extract] {}
+
+ # The extracted entry must be a leaf (otherwise, xQueryCallback would
+ # have been called on the extracted entries children instead of just
+ # returning the data).
+ #
+ # EVIDENCE-OF: R-13214-54017 If that entry is a leaf (meaning that it is
+ # an actual R*Tree entry and not a subtree) then that entry is returned
+ # as one row of the query result.
+ array set N $next
+ if {$N(iLevel)!=0} { error "result row mismatch (1)" }
+
+ if {$x1!=[lindex $N(aCoord) 0] || $x2!=[lindex $N(aCoord) 1]
+ || $y1!=[lindex $N(aCoord) 2] || $y2!=[lindex $N(aCoord) 3]
+ } {
+ if {$N(iLevel)!=0} { error "result row mismatch (2)" }
+ }
+
+ if {$id!=$N(iRowid)} { error "result row mismatch (3)" }
+}
+
+proc pq_done {} {
+ global Q
+ # EVIDENCE-OF: R-57438-45968 The query runs until the priority queue is
+ # empty.
+ if {[llength $Q(pri_queue)]>0} {
+ error "priority queue is not empty!"
+ }
+}
+
+proc pq_debug {caption} {
+ global Q
+
+ puts "**** $caption ****"
+ set i 0
+ foreach q [lsort -real -index 0 $Q(pri_queue)] {
+ puts "PQ $i: $q"
+ incr i
+ }
+}
+
+#--------------------------------------------------------------
+
+proc box_query {a} {
+ set res [list fully [expr rand()]]
+ pq_test_callback $a $res
+ return $res
+}
+
+register_box_query db box_query
+
+do_execsql_test 1.0 {
+ CREATE VIRTUAL TABLE rt USING rtree_i32(id, x1,x2, y1,y2);
+ WITH s(i) AS (
+ SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<64
+ )
+ INSERT INTO rt SELECT NULL, a.i, a.i+1, b.i, b.i+1 FROM s a, s b;
+}
+
+proc box_query {a} {
+ set res [list fully [expr rand()]]
+ pq_test_callback $a $res
+ return $res
+}
+
+pq_init
+db eval { SELECT id, x1,x2, y1,y2 FROM rt WHERE id MATCH qbox() } {
+ pq_test_result $id $x1 $x2 $y1 $y2
+}
+pq_done
+
+finish_test
+
+
diff --git a/ext/rtree/test_rtreedoc.c b/ext/rtree/test_rtreedoc.c
index 6eafef806..752a7ac12 100644
--- a/ext/rtree/test_rtreedoc.c
+++ b/ext/rtree/test_rtreedoc.c
@@ -31,6 +31,12 @@ struct BoxGeomCtx {
Tcl_Obj *pScript;
};
+typedef struct BoxQueryCtx BoxQueryCtx;
+struct BoxQueryCtx {
+ Tcl_Interp *interp;
+ Tcl_Obj *pScript;
+};
+
static void testDelUser(void *pCtx){
BoxGeomCtx *p = (BoxGeomCtx*)pCtx;
Tcl_EvalObjEx(p->interp, p->pScript, 0);
@@ -129,10 +135,6 @@ static int invokeTclGeomCb(
# sqlite3_rtree_geometry structure which provides information about how
# the SQL function was invoked.
-# EVIDENCE-OF: R-40260-16838 The number of coordinates is 2 for a
-# 1-dimensional R*Tree, 4 for a 2-dimensional R*Tree, 6 for a
-# 3-dimensional R*Tree, and so forth.
-
# EVIDENCE-OF: R-00090-24248 The third argument, aCoord[], is an array
# of nCoord coordinates that defines a bounding box to be tested.
@@ -198,6 +200,113 @@ static int SQLITE_TCLAPI register_box_geom(
return TCL_OK;
}
+static int box_query(sqlite3_rtree_query_info *pInfo){
+ const char *azParentWithin[] = {"not", "partly", "fully", 0};
+ BoxQueryCtx *pCtx = (BoxQueryCtx*)pInfo->pContext;
+ Tcl_Interp *interp = pCtx->interp;
+ Tcl_Obj *pEval;
+ Tcl_Obj *pArg;
+ Tcl_Obj *pTmp = 0;
+ int rc;
+ int ii;
+
+ pEval = Tcl_DuplicateObj(pCtx->pScript);
+ Tcl_IncrRefCount(pEval);
+ pArg = Tcl_NewObj();
+ Tcl_IncrRefCount(pArg);
+
+ /* aParam[] */
+ pTmp = Tcl_NewObj();
+ Tcl_IncrRefCount(pTmp);
+ for(ii=0; ii<pInfo->nParam; ii++){
+ Tcl_Obj *p = Tcl_NewDoubleObj(pInfo->aParam[ii]);
+ Tcl_ListObjAppendElement(interp, pTmp, p);
+ }
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("aParam", -1));
+ Tcl_ListObjAppendElement(interp, pArg, pTmp);
+ Tcl_DecrRefCount(pTmp);
+
+ /* aCoord[] */
+ pTmp = Tcl_NewObj();
+ Tcl_IncrRefCount(pTmp);
+ for(ii=0; ii<pInfo->nCoord; ii++){
+ Tcl_Obj *p = Tcl_NewDoubleObj(pInfo->aCoord[ii]);
+ Tcl_ListObjAppendElement(interp, pTmp, p);
+ }
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("aCoord", -1));
+ Tcl_ListObjAppendElement(interp, pArg, pTmp);
+ Tcl_DecrRefCount(pTmp);
+
+ /* anQueue[] */
+ pTmp = Tcl_NewObj();
+ Tcl_IncrRefCount(pTmp);
+ for(ii=0; ii<=pInfo->mxLevel; ii++){
+ Tcl_Obj *p = Tcl_NewIntObj((int)pInfo->anQueue[ii]);
+ Tcl_ListObjAppendElement(interp, pTmp, p);
+ }
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("anQueue", -1));
+ Tcl_ListObjAppendElement(interp, pArg, pTmp);
+ Tcl_DecrRefCount(pTmp);
+
+ /* iLevel */
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("iLevel", -1));
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewIntObj(pInfo->iLevel));
+
+ /* mxLevel */
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("mxLevel", -1));
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewIntObj(pInfo->mxLevel));
+
+ /* iRowid */
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("iRowid", -1));
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewWideIntObj(pInfo->iRowid));
+
+ /* rParentScore */
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("rParentScore", -1));
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewDoubleObj(pInfo->rParentScore));
+
+ /* eParentWithin */
+ assert( pInfo->eParentWithin==0
+ || pInfo->eParentWithin==1
+ || pInfo->eParentWithin==2
+ );
+ Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("eParentWithin", -1));
+ Tcl_ListObjAppendElement(interp, pArg,
+ Tcl_NewStringObj(azParentWithin[pInfo->eParentWithin], -1)
+ );
+
+ Tcl_ListObjAppendElement(interp, pEval, pArg);
+ rc = Tcl_EvalObjEx(interp, pEval, 0) ? SQLITE_ERROR : SQLITE_OK;
+
+ if( rc==SQLITE_OK ){
+ double rScore = 0.0;
+ int nObj = 0;
+ int eP = 0;
+ Tcl_Obj **aObj = 0;
+ Tcl_Obj *pRes = Tcl_GetObjResult(interp);
+
+ if( Tcl_ListObjGetElements(interp, pRes, &nObj, &aObj)
+ || nObj!=2
+ || Tcl_GetDoubleFromObj(interp, aObj[1], &rScore)
+ || Tcl_GetIndexFromObj(interp, aObj[0], azParentWithin, "value", 0, &eP)
+ ){
+ rc = SQLITE_ERROR;
+ }else{
+ pInfo->rScore = rScore;
+ pInfo->eParentWithin = eP;
+ }
+ }
+
+ Tcl_DecrRefCount(pArg);
+ Tcl_DecrRefCount(pEval);
+ return rc;
+}
+
+static void box_query_destroy(void *p){
+ BoxQueryCtx *pCtx = (BoxQueryCtx*)p;
+ Tcl_DecrRefCount(pCtx->pScript);
+ ckfree(pCtx);
+}
+
static int SQLITE_TCLAPI register_box_query(
void * clientData,
Tcl_Interp *interp,
@@ -207,6 +316,7 @@ static int SQLITE_TCLAPI register_box_query(
extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
extern const char *sqlite3ErrName(int);
sqlite3 *db;
+ BoxQueryCtx *pCtx;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB SCRIPT");
@@ -214,6 +324,16 @@ static int SQLITE_TCLAPI register_box_query(
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+ pCtx = (BoxQueryCtx*)ckalloc(sizeof(BoxQueryCtx*));
+ pCtx->interp = interp;
+ pCtx->pScript = Tcl_DuplicateObj(objv[2]);
+ Tcl_IncrRefCount(pCtx->pScript);
+
+ sqlite3_rtree_query_callback(
+ db, "qbox", box_query, (void*)pCtx, box_query_destroy
+ );
+
+ Tcl_ResetResult(interp);
return TCL_OK;
}
#endif /* SQLITE_ENABLE_RTREE */
@@ -226,3 +346,4 @@ int Sqlitetestrtreedoc_Init(Tcl_Interp *interp){
#endif /* SQLITE_ENABLE_RTREE */
return TCL_OK;
}
+
diff --git a/manifest b/manifest
index 4057ec873..dbfc97538 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fixes\sto\sthe\sversion\sof\s"varsep"\sgroup_concat\sso\sthat\s(1)\sit\sbuilds\sunder\nseparate\scompilation\sand\s(2)\somits\stabs\sin\ssource\scode\sand\s(3)\sruns\sfaster\nthan\strunk.\s\sThis\svariant\sof\sthe\sgroup_concat_varsep\sbranch\smight\sbe\spreferred\nover\sthe\stip\sbecause\sit\spreserves\s(undocumented)\slegacy\sbehavior\sabout\sthe\nposition\sof\sseparators\srelative\sto\sterms.
-D 2021-10-01T00:25:06.629
+C Merge\supdates\sfrom\strunk
+D 2021-10-01T02:16:52.236
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 89a51b37c4aa1c02c1ec24c18c55196c0693b29a752fedfd036938d
F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7fa1842ff3
F ext/fts5/fts5_expr.c 6ea447b0cb1888110087a8c04133817b0ccf964fe22414371b0e32189a556533
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
-F ext/fts5/fts5_index.c 3cdcb62ef0ead4420cd9a5da32d6586e628a4da7adba9fffbfa54626b63ff77c
+F ext/fts5/fts5_index.c 48ab70b8d646f8b50d36664005682e7b5d1639bc8aaf60268e11d783afd5b203
F ext/fts5/fts5_main.c 35ebbcae681a4a40027c47bc2e94d7e7c81e331dc406bb9b23c546454ee8f98a
F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
@@ -162,6 +162,7 @@ F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519d
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
F ext/fts5/test/fts5corrupt3.test 0e473620582a53ac61f468f364db8a151c1e18d2a879b16439d172c12c4c9828
F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3
+F ext/fts5/test/fts5corrupt5.test 2765589a88645ed09bb73ce9e522e9b219166ad943e551f39b7ce13789b31499
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
@@ -418,11 +419,12 @@ F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b5879
F ext/rtree/rtreecheck.test d67d5b3e9e45bfa8cd90734e8e9302144ac415b8e9176c6f02d4f92892ee8a35
F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e
F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d
-F ext/rtree/rtreedoc.test 243cd3fdee1cb89e290e908ddde0cc0cfda0ccb85473c6d1b3c43e6260b14cac
+F ext/rtree/rtreedoc.test 903c5229758bcef1d5590892bf973d9f91dcd1d96b1c09b6761e2c0e398e78e1
F ext/rtree/rtreedoc2.test 194ebb7d561452dcdc10bf03f44e30c082c2f0c14efeb07f5e02c7daf8284d93
+F ext/rtree/rtreedoc3.test 555a878c4d79c4e37fa439a1c3b02ee65d3ebaf75d9e8d96a9c55d66db3efbf8
F ext/rtree/rtreefuzz001.test 0fc793f67897c250c5fde96cefee455a5e2fb92f4feeabde5b85ea02040790ee
F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373
-F ext/rtree/test_rtreedoc.c 216f988e0b56474a3d42905653777772d3bdd413a7fe09a79e466b19296853b0
+F ext/rtree/test_rtreedoc.c e81d9bf69f7cbc8ba536458bbd8fc06a6f9ca93165f7d68832f588461e6a53cb
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
@@ -481,7 +483,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c ad192981c345625621048ae1145ac7fc94b39912c44940e458f439627aa18137
+F src/alter.c a6afe961ef3544104fa635a0c3161bfe1a34382f32e2a28706993abadedbffed
F src/analyze.c 989eb1146f4a2c320623e190f8913bf1829fd8954a52dbfd0f792efc69db0e66
F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
@@ -497,9 +499,9 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1
F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
-F src/dbstat.c bea044cfe99eab6c527837e196a5335c128989bdb354cf1b4973b85ea561d66b
+F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c 3ce6af6b64c8b476de51ccc32da0cb3142d42e65754e1d8118addf65b8bcba15
-F src/expr.c f2e0f5dd07d1b202f700f26b0851f2ea485e36ec8f335b05aec2cd91cd08853f
+F src/expr.c 82797e5d82422d34ede9a95ba459f40c317b2daadb21109a21abfd42f84e3ed8
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 1905af1821b88321e1bb9d6a69e704495b6844a9b6c29398d40117cc251e893c
F src/func.c 35e0beafdbd8e9d7050577668ab3f515b86d8aff18bb81603d961d9152955b16
@@ -547,7 +549,7 @@ F src/printf.c 1ce574bf02b503b0e031a70d3453324a9f4a0eb1ad379f3324ced73b918ed20b
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c b9e60afa56d0484ee573aba54d9e73603736236df33d2ae3421b4cd0367d907d
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 030c3d07326708343208418c84da607752aebc13c92df929b7c68c7c08e7df54
+F src/select.c 47a6e97bb04caeb71cc0b748b69d635eaa0aa765915d177949d21c386eb0cc97
F src/shell.c.in 9df263dc0949698a8728ecc5bb826666ca8ced75201d5440a161b629455cd462
F src/sqlite.h.in 4e977a5e2ed1a9e8987ff65a2cab5f99a4298ebf040ea5ff636e1753339ff45a
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -663,7 +665,7 @@ F test/altermalloc3.test 4660ac6240a8c82ba3947b927612dcc7c05a8eec3fe3c9f38e047ca
F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2
F test/altertab.test a13e11cb1933575002367613b1094f0eeb31f493e4bd9ebeca73279fe00c85e7
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
-F test/altertab3.test 9a8aad735c48440c05787b4ab5ac821340a72c6febd1ff8bf74e065fb75882b2
+F test/altertab3.test 5929f522fd6fd708396ad9f317d4af9ff1a93e460df85bb1d54d4499eeb94960
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
F test/analyze3.test 4440c4932247adb2b4e0c838f657c19dc7af4f56859255436dc4e855f39b9324
@@ -1927,10 +1929,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a4c18b2f0ce4a0f4d0c4f4c25dc69fbed4cb4876d2b69e3e5e0e756410892d74
-R 247138f3b5e489fa491f98b9cd97dbe7
-T *branch * group_concat-fix-legacy
-T *sym-group_concat-fix-legacy *
-T -sym-group_concat_varsep *
+P 04399cf9645e04b171090ff8a3c27752929c10d2cd8778e26f8f3337aa902ab6 6e791a24ce259ff6cc46a7c2188aea094a5021e154368f57019a0653c8a81217
+R d3b716f0cf9b6ef6a1679ee563e22ef8
U drh
-Z 89839e6f88669e9a8e94fe2639f687c4
+Z f141141cc66d39890f48912f4e8ef81f
diff --git a/manifest.uuid b/manifest.uuid
index fede5e072..1c635395f 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-04399cf9645e04b171090ff8a3c27752929c10d2cd8778e26f8f3337aa902ab6 \ No newline at end of file
+35351371c5e9602dec210ad0926ff8a1a269556ce1a166e81eb0543938e0c57e \ No newline at end of file
diff --git a/src/alter.c b/src/alter.c
index 9cdc342ee..81f6cf69d 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -864,9 +864,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
if( pParse->nErr ) return WRC_Abort;
- if( p->selFlags & (SF_View|SF_CopyCte) ){
- testcase( p->selFlags & SF_View );
- testcase( p->selFlags & SF_CopyCte );
+ if( NEVER(p->selFlags & (SF_View|SF_CopyCte)) ){
return WRC_Prune;
}
if( ALWAYS(p->pEList) ){
@@ -881,7 +879,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
SrcList *pSrc = p->pSrc;
for(i=0; i<pSrc->nSrc; i++){
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
- if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
+ sqlite3WalkExpr(pWalker, pSrc->a[i].pOn);
unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
}
}
diff --git a/src/dbstat.c b/src/dbstat.c
index 33f9ea8f7..bb88a76f4 100644
--- a/src/dbstat.c
+++ b/src/dbstat.c
@@ -26,6 +26,15 @@
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
+** The pager and btree modules arrange objects in memory so that there are
+** always approximately 200 bytes of addressable memory following each page
+** buffer. This way small buffer overreads caused by corrupt database pages
+** do not cause undefined behaviour. This module pads each page buffer
+** by the following number of bytes for the same purpose.
+*/
+#define DBSTAT_PAGE_PADDING_BYTES 256
+
+/*
** Page paths:
**
** The value of the 'path' column describes the path taken from the
@@ -459,7 +468,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
if( nPayload>(u32)nLocal ){
int j;
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
- if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){
+ if( iOff+nLocal+4>nUsable || nPayload>0x7fffffff ){
goto statPageIsCorrupt;
}
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
@@ -533,10 +542,11 @@ static int statGetPage(
int rc;
if( pPg->aPg==0 ){
- pPg->aPg = (u8*)sqlite3_malloc(pgsz);
+ pPg->aPg = (u8*)sqlite3_malloc(pgsz + DBSTAT_PAGE_PADDING_BYTES);
if( pPg->aPg==0 ){
return SQLITE_NOMEM_BKPT;
}
+ memset(&pPg->aPg[pgsz], 0, DBSTAT_PAGE_PADDING_BYTES);
}
rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPg, &pDbPage, 0);
diff --git a/src/expr.c b/src/expr.c
index 5b7a58fb5..d121fbfd2 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -516,12 +516,16 @@ Expr *sqlite3ExprForVectorField(
pRet->pLeft = pVector;
}
}else{
- if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
- pRet = sqlite3ExprDup(pParse->db, pVector, 0);
- if( IN_RENAME_OBJECT && pRet ){
- SWAP(Expr, *pRet, *pVector);
- sqlite3RenameTokenRemap(pParse, pRet, pVector);
+ if( pVector->op==TK_VECTOR ){
+ Expr **ppVector = &pVector->x.pList->a[iField].pExpr;
+ pVector = *ppVector;
+ if( IN_RENAME_OBJECT ){
+ /* This must be a vector UPDATE inside a trigger */
+ *ppVector = 0;
+ return pVector;
+ }
}
+ pRet = sqlite3ExprDup(pParse->db, pVector, 0);
}
return pRet;
}
diff --git a/src/select.c b/src/select.c
index ba82d624d..6af8b85bc 100644
--- a/src/select.c
+++ b/src/select.c
@@ -5499,9 +5499,9 @@ static int selectExpander(Walker *pWalker, Select *p){
pTab->zName);
}
pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0);
- }else
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( ALWAYS(IsVirtual(pTab))
+ else if( ALWAYS(IsVirtual(pTab))
&& pFrom->fg.fromDDL
&& ALWAYS(pTab->u.vtab.p!=0)
&& pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
diff --git a/test/altertab3.test b/test/altertab3.test
index db38d76dd..2b9aac3ef 100644
--- a/test/altertab3.test
+++ b/test/altertab3.test
@@ -670,8 +670,20 @@ do_execsql_test 27.4 {
ALTER TABLE t0 DROP COLUMN c60;
} {}
-finish_test
-
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 28.1 {
+ CREATE TABLE t1(a,b,c,d);
+ CREATE TRIGGER AFTER INSERT ON t1 BEGIN
+ UPDATE t1 SET (c,d)=(a,b);
+ END;
+ ALTER TABLE t1 RENAME TO t2;
+}
+do_execsql_test 28.2 {
+ SELECT sql FROM sqlite_schema WHERE type='trigger'
+} {{CREATE TRIGGER AFTER INSERT ON "t2" BEGIN
+ UPDATE "t2" SET (c,d)=(a,b);
+ END}}
finish_test