Index: third_party/sqlite/patches/0005-Virtual-table-supporting-recovery-of-corrupted-datab.patch |
diff --git a/third_party/sqlite/patches/0005-Virtual-table-supporting-recovery-of-corrupted-datab.patch b/third_party/sqlite/patches/0005-Virtual-table-supporting-recovery-of-corrupted-datab.patch |
index 7d925c4291d5ca347e0f07fc8d4031f71c1438f9..6a937f96724329416bd8bf5916d0d47b2f0d7e94 100644 |
--- a/third_party/sqlite/patches/0005-Virtual-table-supporting-recovery-of-corrupted-datab.patch |
+++ b/third_party/sqlite/patches/0005-Virtual-table-supporting-recovery-of-corrupted-datab.patch |
@@ -1,4 +1,4 @@ |
-From 31dd2fd1cdeba87223f6a46cc19bcea9eb8b2f38 Mon Sep 17 00:00:00 2001 |
+From d176c774ba1a8b431400f38ca71459bf148f0c3a Mon Sep 17 00:00:00 2001 |
From: Scott Hess <shess@chromium.org> |
Date: Sat, 20 Jul 2013 11:42:21 -0700 |
Subject: [PATCH 05/13] Virtual table supporting recovery of corrupted |
@@ -15,53 +15,26 @@ listed. This patch and the top of recover.c should be considered |
authoritative. The history is mostly under |
third_party/sqlite/src/src/{recover,recover-alt}.c . |
--- |
- third_party/sqlite/src/Makefile.in | 1 + |
- third_party/sqlite/src/Makefile.linux-gcc | 4 + |
- third_party/sqlite/src/main.mk | 5 +- |
- third_party/sqlite/src/src/main.c | 8 + |
- third_party/sqlite/src/src/recover.c | 2281 ++++++++++++++++++++++++++++ |
- third_party/sqlite/src/src/sqlite.h.in | 16 + |
- third_party/sqlite/src/test/recover.test | 164 ++ |
- third_party/sqlite/src/test/recover0.test | 532 +++++++ |
- third_party/sqlite/src/test/recover1.test | 429 ++++++ |
- third_party/sqlite/src/test/recover2.test | 157 ++ |
- third_party/sqlite/src/tool/mksqlite3c.tcl | 2 + |
- 11 files changed, 3598 insertions(+), 1 deletion(-) |
+ third_party/sqlite/src/main.mk | 6 +- |
+ third_party/sqlite/src/src/main.c | 8 + |
+ third_party/sqlite/src/src/recover.c | 2270 +++++++++++++++++++++++++++ |
+ third_party/sqlite/src/src/recover.h | 23 + |
+ third_party/sqlite/src/src/recover_varint.c | 201 +++ |
+ third_party/sqlite/src/test/recover.test | 164 ++ |
+ third_party/sqlite/src/test/recover0.test | 532 +++++++ |
+ third_party/sqlite/src/test/recover1.test | 429 +++++ |
+ third_party/sqlite/src/test/recover2.test | 157 ++ |
+ 9 files changed, 3789 insertions(+), 1 deletion(-) |
create mode 100644 third_party/sqlite/src/src/recover.c |
+ create mode 100644 third_party/sqlite/src/src/recover.h |
+ create mode 100644 third_party/sqlite/src/src/recover_varint.c |
create mode 100644 third_party/sqlite/src/test/recover.test |
create mode 100644 third_party/sqlite/src/test/recover0.test |
create mode 100644 third_party/sqlite/src/test/recover1.test |
create mode 100644 third_party/sqlite/src/test/recover2.test |
-diff --git a/third_party/sqlite/src/Makefile.in b/third_party/sqlite/src/Makefile.in |
-index 1fe49d6..8b965c7 100644 |
---- a/third_party/sqlite/src/Makefile.in |
-+++ b/third_party/sqlite/src/Makefile.in |
-@@ -260,6 +260,7 @@ SRC = \ |
- $(TOP)/src/prepare.c \ |
- $(TOP)/src/printf.c \ |
- $(TOP)/src/random.c \ |
-+ $(TOP)/src/recover.c \ |
- $(TOP)/src/resolve.c \ |
- $(TOP)/src/rowset.c \ |
- $(TOP)/src/select.c \ |
-diff --git a/third_party/sqlite/src/Makefile.linux-gcc b/third_party/sqlite/src/Makefile.linux-gcc |
-index 952e8d1..f6291c0 100644 |
---- a/third_party/sqlite/src/Makefile.linux-gcc |
-+++ b/third_party/sqlite/src/Makefile.linux-gcc |
-@@ -81,6 +81,10 @@ OPTS += -DSQLITE_MEMDEBUG=1 |
- # TODO(shess) I can't see why I need this setting. |
- OPTS += -DOS_UNIX=1 |
- |
-+# The recover virtual table is not generally enabled. Enable it for testing |
-+# purposes. |
-+OPTS += -DDEFAULT_ENABLE_RECOVER=1 |
-+ |
- #### The suffix to add to executable files. ".exe" for windows. |
- # Nothing for unix. |
- # |
diff --git a/third_party/sqlite/src/main.mk b/third_party/sqlite/src/main.mk |
-index 6ff3bd4..a8629aa 100644 |
+index 6ff3bd4..26f9f15 100644 |
--- a/third_party/sqlite/src/main.mk |
+++ b/third_party/sqlite/src/main.mk |
@@ -67,7 +67,8 @@ LIBOBJ+= vdbe.o parse.o \ |
@@ -69,27 +42,28 @@ index 6ff3bd4..a8629aa 100644 |
notify.o opcodes.o os.o os_unix.o os_win.o \ |
pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ |
- random.o resolve.o rowset.o rtree.o select.o sqlite3rbu.o status.o \ |
-+ random.o recover.o resolve.o rowset.o rtree.o \ |
++ random.o recover.o recover_varint.o resolve.o rowset.o rtree.o \ |
+ select.o sqlite3rbu.o status.o \ |
table.o threads.o tokenize.o treeview.o trigger.o \ |
update.o userauth.o util.o vacuum.o \ |
vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ |
-@@ -140,6 +141,7 @@ SRC = \ |
- $(TOP)/src/prepare.c \ |
- $(TOP)/src/printf.c \ |
- $(TOP)/src/random.c \ |
-+ $(TOP)/src/recover.c \ |
- $(TOP)/src/resolve.c \ |
- $(TOP)/src/rowset.c \ |
- $(TOP)/src/select.c \ |
-@@ -360,6 +362,7 @@ TESTSRC2 = \ |
+@@ -360,6 +361,8 @@ TESTSRC2 = \ |
$(TOP)/src/prepare.c \ |
$(TOP)/src/printf.c \ |
$(TOP)/src/random.c \ |
+ $(TOP)/src/recover.c \ |
++ $(TOP)/src/recover_varint.c \ |
$(TOP)/src/pcache.c \ |
$(TOP)/src/pcache1.c \ |
$(TOP)/src/select.c \ |
+@@ -720,6 +723,7 @@ sqlite3_analyzer$(EXE): sqlite3_analyzer.c |
+ # |
+ TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 |
+ TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE |
++TESTFIXTURE_FLAGS += -DDEFAULT_ENABLE_RECOVER=1 |
+ |
+ testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c |
+ $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ |
diff --git a/third_party/sqlite/src/src/main.c b/third_party/sqlite/src/src/main.c |
index 3be7c77..301808c 100644 |
--- a/third_party/sqlite/src/src/main.c |
@@ -111,10 +85,10 @@ index 3be7c77..301808c 100644 |
rc = sqlite3IcuInit(db); |
diff --git a/third_party/sqlite/src/src/recover.c b/third_party/sqlite/src/src/recover.c |
new file mode 100644 |
-index 0000000..5ff6f78 |
+index 0000000..c22fd4d |
--- /dev/null |
+++ b/third_party/sqlite/src/src/recover.c |
-@@ -0,0 +1,2281 @@ |
+@@ -0,0 +1,2270 @@ |
+/* |
+** 2012 Jan 11 |
+** |
@@ -327,20 +301,24 @@ index 0000000..5ff6f78 |
+ |
+#include <assert.h> |
+#include <ctype.h> |
++#include <stdint.h> |
+#include <stdio.h> |
+#include <string.h> |
+ |
-+/* Internal SQLite things that are used: |
-+ * u32, u64, i64 types. |
-+ * Btree, Pager, and DbPage structs. |
-+ * DbPage.pData, .pPager, and .pgno |
-+ * sqlite3 struct. |
-+ * sqlite3BtreePager() and sqlite3BtreeGetPageSize() |
-+ * sqlite3BtreeGetOptimalReserve() |
-+ * sqlite3PagerGet() and sqlite3PagerUnref() |
-+ * getVarint(). |
-+ */ |
-+#include "sqliteInt.h" |
++#include "sqlite3.h" |
++ |
++/* Some SQLite internals use, cribbed from fts5int.h. */ |
++#ifndef SQLITE_AMALGAMATION |
++typedef uint8_t u8; |
++typedef uint32_t u32; |
++typedef sqlite3_int64 i64; |
++typedef sqlite3_uint64 u64; |
++ |
++#define ArraySize(x) (sizeof(x) / sizeof(x[0])) |
++#endif |
++ |
++/* From recover_varint.c. */ |
++u8 recoverGetVarint(const unsigned char *p, u64 *v); |
+ |
+/* For debugging. */ |
+#if 0 |
@@ -365,10 +343,10 @@ index 0000000..5ff6f78 |
+ |
+/* From section 1.5. */ |
+static const unsigned kiPageTypeOffset = 0; |
-+static const unsigned kiPageFreeBlockOffset = 1; |
++/* static const unsigned kiPageFreeBlockOffset = 1; */ |
+static const unsigned kiPageCellCountOffset = 3; |
-+static const unsigned kiPageCellContentOffset = 5; |
-+static const unsigned kiPageFragmentedBytesOffset = 7; |
++/* static const unsigned kiPageCellContentOffset = 5; */ |
++/* static const unsigned kiPageFragmentedBytesOffset = 7; */ |
+static const unsigned knPageLeafHeaderBytes = 8; |
+/* Interior pages contain an additional field. */ |
+static const unsigned kiPageRightChildOffset = 8; |
@@ -537,7 +515,7 @@ index 0000000..5ff6f78 |
+const int kExcessSpace = 128; |
+typedef struct RecoverPage RecoverPage; |
+struct RecoverPage { |
-+ Pgno pgno; /* Page number for this page */ |
++ u32 pgno; /* Page number for this page */ |
+ void *pData; /* Page data for pgno */ |
+ RecoverPager *pPager; /* The pager this page is part of */ |
+}; |
@@ -814,8 +792,6 @@ index 0000000..5ff6f78 |
+ * interiorCursorDestroy - release all resources associated with the |
+ * cursor and any parent cursors. |
+ * interiorCursorCreate - create a cursor with the given parent and page. |
-+ * interiorCursorEOF - returns true if neither the cursor nor the |
-+ * parent cursors can return any more data. |
+ * interiorCursorNextPage - fetch the next child page from the cursor. |
+ * |
+ * Logically, interiorCursorNextPage() returns the next child page |
@@ -832,11 +808,6 @@ index 0000000..5ff6f78 |
+ * Note that while interiorCursorNextPage() will refuse to follow |
+ * loops, it does not keep track of pages returned for purposes of |
+ * preventing duplication. |
-+ * |
-+ * Note that interiorCursorEOF() could return false (not at EOF), and |
-+ * interiorCursorNextPage() could still return SQLITE_DONE. This |
-+ * could happen if there are more cells to iterate in an interior |
-+ * page, but those cells refer to invalid pages. |
+ */ |
+typedef struct RecoverInteriorCursor RecoverInteriorCursor; |
+struct RecoverInteriorCursor { |
@@ -952,14 +923,6 @@ index 0000000..5ff6f78 |
+ return 0; |
+} |
+ |
-+static int interiorCursorEOF(RecoverInteriorCursor *pCursor){ |
-+ /* Find a parent with remaining children. EOF if none found. */ |
-+ while( pCursor && pCursor->iChild>=pCursor->nChildren ){ |
-+ pCursor = pCursor->pParent; |
-+ } |
-+ return pCursor==NULL; |
-+} |
-+ |
+/* Internal helper. Used to detect if iPage would cause a loop. */ |
+static int interiorCursorPageInUse(RecoverInteriorCursor *pCursor, |
+ unsigned iPage){ |
@@ -1575,11 +1538,11 @@ index 0000000..5ff6f78 |
+ return ValidateError(); |
+ } |
+ |
-+ nRead = getVarint(pCell, &nRecordBytes); |
++ nRead = recoverGetVarint(pCell, &nRecordBytes); |
+ assert( iCellOffset+nRead<=pCursor->nPageSize ); |
+ pCursor->nRecordBytes = nRecordBytes; |
+ |
-+ nRead += getVarint(pCell + nRead, &iRowid); |
++ nRead += recoverGetVarint(pCell + nRead, &iRowid); |
+ assert( iCellOffset+nRead<=pCursor->nPageSize ); |
+ pCursor->iRowid = (i64)iRowid; |
+ |
@@ -1605,7 +1568,7 @@ index 0000000..5ff6f78 |
+ } |
+ } |
+ |
-+ nRecordHeaderRead = getVarint(pCell + nRead, &nRecordHeaderBytes); |
++ nRecordHeaderRead = recoverGetVarint(pCell + nRead, &nRecordHeaderBytes); |
+ assert( nRecordHeaderBytes<=nRecordBytes ); |
+ pCursor->nRecordHeaderBytes = nRecordHeaderBytes; |
+ |
@@ -1627,8 +1590,8 @@ index 0000000..5ff6f78 |
+ nRecordHeaderBytes - nRecordHeaderRead) ){ |
+ return ValidateError(); |
+ } |
-+ nRecordHeaderRead += getVarint(pCursor->pRecordHeader + nRecordHeaderRead, |
-+ &iSerialType); |
++ nRecordHeaderRead += recoverGetVarint( |
++ pCursor->pRecordHeader + nRecordHeaderRead, &iSerialType); |
+ if( iSerialType==10 || iSerialType==11 ){ |
+ return ValidateError(); |
+ } |
@@ -1694,7 +1657,7 @@ index 0000000..5ff6f78 |
+ /* Rather than caching the header size and how many bytes it took, |
+ * decode it every time. |
+ */ |
-+ nRead = getVarint(pRecordHeader, &nRecordHeaderBytes); |
++ nRead = recoverGetVarint(pRecordHeader, &nRecordHeaderBytes); |
+ assert( nRecordHeaderBytes==pCursor->nRecordHeaderBytes ); |
+ |
+ /* Scan forward to the indicated column. Scans to _after_ column |
@@ -1713,7 +1676,7 @@ index 0000000..5ff6f78 |
+ if( !checkVarint(pRecordHeader + nRead, nRecordHeaderBytes - nRead) ){ |
+ return SQLITE_CORRUPT; |
+ } |
-+ nRead += getVarint(pRecordHeader + nRead, &iSerialType); |
++ nRead += recoverGetVarint(pRecordHeader + nRead, &iSerialType); |
+ iColEndOffset += SerialTypeLength(iSerialType); |
+ nColsSkipped++; |
+ } |
@@ -2108,7 +2071,7 @@ index 0000000..5ff6f78 |
+ 0, /* xRename - rename the table */ |
+}; |
+ |
-+CHROMIUM_SQLITE_API |
++SQLITE_API |
+int recoverVtableInit(sqlite3 *db){ |
+ return sqlite3_create_module_v2(db, "recover", &recoverModule, NULL, 0); |
+} |
@@ -2346,7 +2309,7 @@ index 0000000..5ff6f78 |
+ /* Parse out db.table, assuming main if no dot. */ |
+ zDot = strchr(argv[3], '.'); |
+ if( !zDot ){ |
-+ pRecover->zDb = sqlite3_strdup(db->aDb[0].zName); |
++ pRecover->zDb = sqlite3_strdup("main"); |
+ pRecover->zTable = sqlite3_strdup(argv[3]); |
+ }else if( zDot>argv[3] && zDot[1]!='\0' ){ |
+ pRecover->zDb = sqlite3_strndup(argv[3], zDot - argv[3]); |
@@ -2396,19 +2359,22 @@ index 0000000..5ff6f78 |
+ *ppVtab = (sqlite3_vtab *)pRecover; |
+ return SQLITE_OK; |
+} |
-diff --git a/third_party/sqlite/src/src/sqlite.h.in b/third_party/sqlite/src/src/sqlite.h.in |
-index e5673fd..6829bcb 100644 |
---- a/third_party/sqlite/src/src/sqlite.h.in |
-+++ b/third_party/sqlite/src/src/sqlite.h.in |
-@@ -7411,6 +7411,22 @@ int sqlite3_strnicmp(const char *, const char *, int); |
- */ |
- int sqlite3_strglob(const char *zGlob, const char *zStr); |
- |
-+/* Begin recover virtual table patch for Chromium */ |
-+/* Our patches don't conform to SQLite's amalgamation processing. Hack it. */ |
-+#ifndef CHROMIUM_SQLITE_API |
-+#define CHROMIUM_SQLITE_API SQLITE_API |
+diff --git a/third_party/sqlite/src/src/recover.h b/third_party/sqlite/src/src/recover.h |
+new file mode 100644 |
+index 0000000..691f2fd |
+--- /dev/null |
++++ b/third_party/sqlite/src/src/recover.h |
+@@ -0,0 +1,23 @@ |
++/* TODO(shess): sqliteicu.h is able to make this include without |
++** trouble. It doesn't work when used with Chromium's SQLite. For |
++** now the including code must include sqlite3.h first. |
++*/ |
++/* #include "sqlite3.h" */ |
++ |
++#ifdef __cplusplus |
++extern "C" { |
+#endif |
++ |
+/* |
+** Call to initialize the recover virtual-table modules (see recover.c). |
+** |
@@ -2416,13 +2382,219 @@ index e5673fd..6829bcb 100644 |
+** virtual table available to Web SQL. Breaking it out allows only |
+** selected users to enable it (currently sql/recovery.cc). |
+*/ |
-+CHROMIUM_SQLITE_API |
++SQLITE_API |
+int recoverVtableInit(sqlite3 *db); |
-+/* End recover virtual table patch for Chromium */ |
+ |
- /* Begin WebDatabase patch for Chromium */ |
- /* Expose some SQLite internals for the WebDatabase vfs. |
- ** DO NOT EXTEND THE USE OF THIS. |
++#ifdef __cplusplus |
++} /* End of the 'extern "C"' block */ |
++#endif |
+diff --git a/third_party/sqlite/src/src/recover_varint.c b/third_party/sqlite/src/src/recover_varint.c |
+new file mode 100644 |
+index 0000000..c111e2c |
+--- /dev/null |
++++ b/third_party/sqlite/src/src/recover_varint.c |
+@@ -0,0 +1,201 @@ |
++/* |
++** 2016 Feb 29 |
++** |
++** 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. |
++** |
++****************************************************************************** |
++** |
++** Copy of sqlite3Fts5GetVarint() from fts3_varint.c, which in turn is copied |
++** from SQLite core. |
++*/ |
++ |
++#include <assert.h> |
++#include "sqlite3.h" |
++ |
++/* Copied from fts3int.h. */ |
++#ifndef SQLITE_AMALGAMATION |
++typedef unsigned char u8; |
++typedef unsigned int u32; |
++typedef sqlite3_uint64 u64; |
++#endif |
++ |
++/* |
++** Bitmasks used by recoverGetVarint(). These precomputed constants |
++** are defined here rather than simply putting the constant expressions |
++** inline in order to work around bugs in the RVT compiler. |
++** |
++** SLOT_2_0 A mask for (0x7f<<14) | 0x7f |
++** |
++** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 |
++*/ |
++#define SLOT_2_0 0x001fc07f |
++#define SLOT_4_2_0 0xf01fc07f |
++ |
++/* |
++** Read a 64-bit variable-length integer from memory starting at p[0]. |
++** Return the number of bytes read. The value is stored in *v. |
++*/ |
++u8 recoverGetVarint(const unsigned char *p, u64 *v){ |
++ u32 a,b,s; |
++ |
++ a = *p; |
++ /* a: p0 (unmasked) */ |
++ if (!(a&0x80)) |
++ { |
++ *v = a; |
++ return 1; |
++ } |
++ |
++ p++; |
++ b = *p; |
++ /* b: p1 (unmasked) */ |
++ if (!(b&0x80)) |
++ { |
++ a &= 0x7f; |
++ a = a<<7; |
++ a |= b; |
++ *v = a; |
++ return 2; |
++ } |
++ |
++ /* Verify that constants are precomputed correctly */ |
++ assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); |
++ assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); |
++ |
++ p++; |
++ a = a<<14; |
++ a |= *p; |
++ /* a: p0<<14 | p2 (unmasked) */ |
++ if (!(a&0x80)) |
++ { |
++ a &= SLOT_2_0; |
++ b &= 0x7f; |
++ b = b<<7; |
++ a |= b; |
++ *v = a; |
++ return 3; |
++ } |
++ |
++ /* CSE1 from below */ |
++ a &= SLOT_2_0; |
++ p++; |
++ b = b<<14; |
++ b |= *p; |
++ /* b: p1<<14 | p3 (unmasked) */ |
++ if (!(b&0x80)) |
++ { |
++ b &= SLOT_2_0; |
++ /* moved CSE1 up */ |
++ /* a &= (0x7f<<14)|(0x7f); */ |
++ a = a<<7; |
++ a |= b; |
++ *v = a; |
++ return 4; |
++ } |
++ |
++ /* a: p0<<14 | p2 (masked) */ |
++ /* b: p1<<14 | p3 (unmasked) */ |
++ /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
++ /* moved CSE1 up */ |
++ /* a &= (0x7f<<14)|(0x7f); */ |
++ b &= SLOT_2_0; |
++ s = a; |
++ /* s: p0<<14 | p2 (masked) */ |
++ |
++ p++; |
++ a = a<<14; |
++ a |= *p; |
++ /* a: p0<<28 | p2<<14 | p4 (unmasked) */ |
++ if (!(a&0x80)) |
++ { |
++ /* we can skip these cause they were (effectively) done above in calc'ing s */ |
++ /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ |
++ /* b &= (0x7f<<14)|(0x7f); */ |
++ b = b<<7; |
++ a |= b; |
++ s = s>>18; |
++ *v = ((u64)s)<<32 | a; |
++ return 5; |
++ } |
++ |
++ /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
++ s = s<<7; |
++ s |= b; |
++ /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
++ |
++ p++; |
++ b = b<<14; |
++ b |= *p; |
++ /* b: p1<<28 | p3<<14 | p5 (unmasked) */ |
++ if (!(b&0x80)) |
++ { |
++ /* we can skip this cause it was (effectively) done above in calc'ing s */ |
++ /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ |
++ a &= SLOT_2_0; |
++ a = a<<7; |
++ a |= b; |
++ s = s>>18; |
++ *v = ((u64)s)<<32 | a; |
++ return 6; |
++ } |
++ |
++ p++; |
++ a = a<<14; |
++ a |= *p; |
++ /* a: p2<<28 | p4<<14 | p6 (unmasked) */ |
++ if (!(a&0x80)) |
++ { |
++ a &= SLOT_4_2_0; |
++ b &= SLOT_2_0; |
++ b = b<<7; |
++ a |= b; |
++ s = s>>11; |
++ *v = ((u64)s)<<32 | a; |
++ return 7; |
++ } |
++ |
++ /* CSE2 from below */ |
++ a &= SLOT_2_0; |
++ p++; |
++ b = b<<14; |
++ b |= *p; |
++ /* b: p3<<28 | p5<<14 | p7 (unmasked) */ |
++ if (!(b&0x80)) |
++ { |
++ b &= SLOT_4_2_0; |
++ /* moved CSE2 up */ |
++ /* a &= (0x7f<<14)|(0x7f); */ |
++ a = a<<7; |
++ a |= b; |
++ s = s>>4; |
++ *v = ((u64)s)<<32 | a; |
++ return 8; |
++ } |
++ |
++ p++; |
++ a = a<<15; |
++ a |= *p; |
++ /* a: p4<<29 | p6<<15 | p8 (unmasked) */ |
++ |
++ /* moved CSE2 up */ |
++ /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ |
++ b &= SLOT_2_0; |
++ b = b<<8; |
++ a |= b; |
++ |
++ s = s<<4; |
++ b = p[-4]; |
++ b &= 0x7f; |
++ b = b>>3; |
++ s |= b; |
++ |
++ *v = ((u64)s)<<32 | a; |
++ |
++ return 9; |
++} |
++ |
diff --git a/third_party/sqlite/src/test/recover.test b/third_party/sqlite/src/test/recover.test |
new file mode 100644 |
index 0000000..bfb7888 |
@@ -3729,19 +3901,6 @@ index 0000000..8aa4e04 |
+} [list 4 1024 1 text [string length $substr] $substr] |
+ |
+finish_test |
-diff --git a/third_party/sqlite/src/tool/mksqlite3c.tcl b/third_party/sqlite/src/tool/mksqlite3c.tcl |
-index 23241e2..1113758 100644 |
---- a/third_party/sqlite/src/tool/mksqlite3c.tcl |
-+++ b/third_party/sqlite/src/tool/mksqlite3c.tcl |
-@@ -361,6 +361,8 @@ foreach file { |
- main.c |
- notify.c |
- |
-+ recover.c |
-+ |
- fts3.c |
- fts3_aux.c |
- fts3_expr.c |
-- |
-2.7.0 |
+2.5.0 |