411 lines
13 KiB
Diff
411 lines
13 KiB
Diff
|
|
From cc12b9c512451199cacf89a999977886ba4f183e Mon Sep 17 00:00:00 2001
|
||
|
|
From: guiyao <guiyao@huawei.com>
|
||
|
|
Date: Tue, 31 Dec 2019 21:45:30 -0500
|
||
|
|
Subject: [PATCH] backport-fix-CVE-2019-9937
|
||
|
|
|
||
|
|
---
|
||
|
|
ext/fts5/fts5Int.h | 3 ++-
|
||
|
|
ext/fts5/fts5_hash.c | 55 ++++++++++++++++++++++++++++++++---------------
|
||
|
|
ext/fts5/fts5_index.c | 25 ++++++++++++++-------
|
||
|
|
ext/fts5/test/fts5aa.test | 21 +++++++++++++++++-
|
||
|
|
4 files changed, 77 insertions(+), 27 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h
|
||
|
|
index 1f8a297..984d625 100644
|
||
|
|
--- a/ext/fts5/fts5Int.h
|
||
|
|
+++ b/ext/fts5/fts5Int.h
|
||
|
|
@@ -565,8 +565,9 @@ void sqlite3Fts5HashClear(Fts5Hash*);
|
||
|
|
|
||
|
|
int sqlite3Fts5HashQuery(
|
||
|
|
Fts5Hash*, /* Hash table to query */
|
||
|
|
+ int nPre,
|
||
|
|
const char *pTerm, int nTerm, /* Query term */
|
||
|
|
- const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
+ void **ppObj, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||
|
|
);
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5_hash.c b/ext/fts5/fts5_hash.c
|
||
|
|
index c35b5d5..eae785a 100644
|
||
|
|
--- a/ext/fts5/fts5_hash.c
|
||
|
|
+++ b/ext/fts5/fts5_hash.c
|
||
|
|
@@ -187,19 +187,25 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||
|
|
return SQLITE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
-static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
|
||
|
|
+static int fts5HashAddPoslistSize(
|
||
|
|
+ Fts5Hash *pHash,
|
||
|
|
+ Fts5HashEntry *p,
|
||
|
|
+ Fts5HashEntry *p2
|
||
|
|
+){
|
||
|
|
+ int nRet = 0;
|
||
|
|
if( p->iSzPoslist ){
|
||
|
|
- u8 *pPtr = (u8*)p;
|
||
|
|
+ u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
|
||
|
|
+ int nData = p->nData;
|
||
|
|
if( pHash->eDetail==FTS5_DETAIL_NONE ){
|
||
|
|
- assert( p->nData==p->iSzPoslist );
|
||
|
|
+ assert( nData==p->iSzPoslist );
|
||
|
|
if( p->bDel ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
if( p->bContent ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
- int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes From cc12b9c512451199cacf89a999977886ba4f183e Mon Sep 17 00:00:00 2001
|
||
|
|
From: guiyao <guiyao@huawei.com>
|
||
|
|
Date: Tue, 31 Dec 2019 21:45:30 -0500
|
||
|
|
Subject: [PATCH] backport-fix-CVE-2019-9937
|
||
|
|
|
||
|
|
---
|
||
|
|
ext/fts5/fts5Int.h | 3 ++-
|
||
|
|
ext/fts5/fts5_hash.c | 55 ++++++++++++++++++++++++++++++++---------------
|
||
|
|
ext/fts5/fts5_index.c | 25 ++++++++++++++-------
|
||
|
|
ext/fts5/test/fts5aa.test | 21 +++++++++++++++++-
|
||
|
|
4 files changed, 77 insertions(+), 27 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h
|
||
|
|
index 1f8a297..984d625 100644
|
||
|
|
--- a/ext/fts5/fts5Int.h
|
||
|
|
+++ b/ext/fts5/fts5Int.h
|
||
|
|
@@ -565,8 +565,9 @@ void sqlite3Fts5HashClear(Fts5Hash*);
|
||
|
|
|
||
|
|
int sqlite3Fts5HashQuery(
|
||
|
|
Fts5Hash*, /* Hash table to query */
|
||
|
|
+ int nPre,
|
||
|
|
const char *pTerm, int nTerm, /* Query term */
|
||
|
|
- const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
+ void **ppObj, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||
|
|
);
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5_hash.c b/ext/fts5/fts5_hash.c
|
||
|
|
index c35b5d5..eae785a 100644
|
||
|
|
--- a/ext/fts5/fts5_hash.c
|
||
|
|
+++ b/ext/fts5/fts5_hash.c
|
||
|
|
@@ -187,19 +187,25 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||
|
|
return SQLITE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
-static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
|
||
|
|
+static int fts5HashAddPoslistSize(
|
||
|
|
+ Fts5Hash *pHash,
|
||
|
|
+ Fts5HashEntry *p,
|
||
|
|
+ Fts5HashEntry *p2
|
||
|
|
+){
|
||
|
|
+ int nRet = 0;
|
||
|
|
if( p->iSzPoslist ){
|
||
|
|
- u8 *pPtr = (u8*)p;
|
||
|
|
+ u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
|
||
|
|
+ int nData = p->nData;
|
||
|
|
if( pHash->eDetail==FTS5_DETAIL_NONE ){
|
||
|
|
- assert( p->nData==p->iSzPoslist );
|
||
|
|
+ assert( nData==p->iSzPoslist );
|
||
|
|
if( p->bDel ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
if( p->bContent ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
- int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes vFrom cc12b9c512451199cacf89a999977886ba4f183e Mon Sep 17 00:00:00 2001
|
||
|
|
From: guiyao <guiyao@huawei.com>
|
||
|
|
Date: Tue, 31 Dec 2019 21:45:30 -0500
|
||
|
|
Subject: [PATCH] backport-fix-CVE-2019-9937
|
||
|
|
|
||
|
|
---
|
||
|
|
ext/fts5/fts5Int.h | 3 ++-
|
||
|
|
ext/fts5/fts5_hash.c | 55 ++++++++++++++++++++++++++++++++---------------
|
||
|
|
ext/fts5/fts5_index.c | 25 ++++++++++++++-------
|
||
|
|
ext/fts5/test/fts5aa.test | 21 +++++++++++++++++-
|
||
|
|
4 files changed, 77 insertions(+), 27 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h
|
||
|
|
index 1f8a297..984d625 100644
|
||
|
|
--- a/ext/fts5/fts5Int.h
|
||
|
|
+++ b/ext/fts5/fts5Int.h
|
||
|
|
@@ -565,8 +565,9 @@ void sqlite3Fts5HashClear(Fts5Hash*);
|
||
|
|
|
||
|
|
int sqlite3Fts5HashQuery(
|
||
|
|
Fts5Hash*, /* Hash table to query */
|
||
|
|
+ int nPre,
|
||
|
|
const char *pTerm, int nTerm, /* Query term */
|
||
|
|
- const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
+ void **ppObj, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||
|
|
);
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5_hash.c b/ext/fts5/fts5_hash.c
|
||
|
|
index c35b5d5..eae785a 100644
|
||
|
|
--- a/ext/fts5/fts5_hash.c
|
||
|
|
+++ b/ext/fts5/fts5_hash.c
|
||
|
|
@@ -187,19 +187,25 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||
|
|
return SQLITE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
-static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
|
||
|
|
+static int fts5HashAddPoslistSize(
|
||
|
|
+ Fts5Hash *pHash,
|
||
|
|
+ Fts5HashEntry *p,
|
||
|
|
+ Fts5HashEntry *p2
|
||
|
|
+){
|
||
|
|
+ int nRet = 0;
|
||
|
|
if( p->iSzPoslist ){
|
||
|
|
- u8 *pPtr = (u8*)p;
|
||
|
|
+ u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
|
||
|
|
+ int nData = p->nData;
|
||
|
|
if( pHash->eDetail==FTS5_DETAIL_NONE ){
|
||
|
|
- assert( p->nData==p->iSzPoslist );
|
||
|
|
+ assert( nData==p->iSzPoslist );
|
||
|
|
if( p->bDel ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
if( p->bContent ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
- int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes From cc12b9c512451199cacf89a999977886ba4f183e Mon Sep 17 00:00:00 2001
|
||
|
|
From: guiyao <guiyao@huawei.com>
|
||
|
|
Date: Tue, 31 Dec 2019 21:45:30 -0500
|
||
|
|
Subject: [PATCH] backport-fix-CVE-2019-9937
|
||
|
|
|
||
|
|
---
|
||
|
|
ext/fts5/fts5Int.h | 3 ++-
|
||
|
|
ext/fts5/fts5_hash.c | 55 ++++++++++++++++++++++++++++++++---------------
|
||
|
|
ext/fts5/fts5_index.c | 25 ++++++++++++++-------
|
||
|
|
ext/fts5/test/fts5aa.test | 21 +++++++++++++++++-
|
||
|
|
4 files changed, 77 insertions(+), 27 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h
|
||
|
|
index 1f8a297..984d625 100644
|
||
|
|
--- a/ext/fts5/fts5Int.h
|
||
|
|
+++ b/ext/fts5/fts5Int.h
|
||
|
|
@@ -565,8 +565,9 @@ void sqlite3Fts5HashClear(Fts5Hash*);
|
||
|
|
|
||
|
|
int sqlite3Fts5HashQuery(
|
||
|
|
Fts5Hash*, /* Hash table to query */
|
||
|
|
+ int nPre,
|
||
|
|
const char *pTerm, int nTerm, /* Query term */
|
||
|
|
- const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
+ void **ppObj, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||
|
|
);
|
||
|
|
|
||
|
|
diff --git a/ext/fts5/fts5_hash.c b/ext/fts5/fts5_hash.c
|
||
|
|
index c35b5d5..eae785a 100644
|
||
|
|
--- a/ext/fts5/fts5_hash.c
|
||
|
|
+++ b/ext/fts5/fts5_hash.c
|
||
|
|
@@ -187,19 +187,25 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||
|
|
return SQLITE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
-static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
|
||
|
|
+static int fts5HashAddPoslistSize(
|
||
|
|
+ Fts5Hash *pHash,
|
||
|
|
+ Fts5HashEntry *p,
|
||
|
|
+ Fts5HashEntry *p2
|
||
|
|
+){
|
||
|
|
+ int nRet = 0;
|
||
|
|
if( p->iSzPoslist ){
|
||
|
|
- u8 *pPtr = (u8*)p;
|
||
|
|
+ u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
|
||
|
|
+ int nData = p->nData;
|
||
|
|
if( pHash->eDetail==FTS5_DETAIL_NONE ){
|
||
|
|
- assert( p->nData==p->iSzPoslist );
|
||
|
|
+ assert( nData==p->iSzPoslist );
|
||
|
|
if( p->bDel ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
if( p->bContent ){
|
||
|
|
- pPtr[p->nData++] = 0x00;
|
||
|
|
+ pPtr[nData++] = 0x00;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
- int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes */
|
||
|
|
+ int nSz = (nData - p->iSzPoslist - 1); /* Size in bytes */
|
||
|
|
int nPos = nSz*2 + p->bDel; /* Value of nPos field */
|
||
|
|
|
||
|
|
assert( p->bDel==0 || p->bDel==1 );
|
||
|
|
@@ -209,14 +215,19 @@ static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
|
||
|
|
int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
|
||
|
|
memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
|
||
|
|
sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
|
||
|
|
- p->nData += (nByte-1);
|
||
|
|
+ nData += (nByte-1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- p->iSzPoslist = 0;
|
||
|
|
- p->bDel = 0;
|
||
|
|
- p->bContent = 0;
|
||
|
|
+ nRet = nData - p->nData;
|
||
|
|
+ if( p2==0 ){
|
||
|
|
+ p->iSzPoslist = 0;
|
||
|
|
+ p->bDel = 0;
|
||
|
|
+ p->bContent = 0;
|
||
|
|
+ p->nData = nData;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
+ return nRet;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
@@ -328,7 +339,7 @@ int sqlite3Fts5HashWrite(
|
||
|
|
/* If this is a new rowid, append the 4-byte size field for the previous
|
||
|
|
** entry, and the new rowid for this entry. */
|
||
|
|
if( iRowid!=p->iRowid ){
|
||
|
|
- fts5HashAddPoslistSize(pHash, p);
|
||
|
|
+ fts5HashAddPoslistSize(pHash, p, 0);
|
||
|
|
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
|
||
|
|
p->iRowid = iRowid;
|
||
|
|
bNew = 1;
|
||
|
|
@@ -474,8 +485,9 @@ static int fts5HashEntrySort(
|
||
|
|
*/
|
||
|
|
int sqlite3Fts5HashQuery(
|
||
|
|
Fts5Hash *pHash, /* Hash table to query */
|
||
|
|
+ int nPre,
|
||
|
|
const char *pTerm, int nTerm, /* Query term */
|
||
|
|
- const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||
|
|
+ void **ppOut, /* OUT: Pointer to new object */
|
||
|
|
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||
|
|
){
|
||
|
|
unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
|
||
|
|
@@ -489,11 +501,20 @@ int sqlite3Fts5HashQuery(
|
||
|
|
}
|
||
|
|
|
||
|
|
if( p ){
|
||
|
|
- fts5HashAddPoslistSize(pHash, p);
|
||
|
|
- *ppDoclist = (const u8*)&zKey[nTerm+1];
|
||
|
|
- *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||
|
|
+ int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1;
|
||
|
|
+ int nList = p->nData - nHashPre;
|
||
|
|
+ u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
|
||
|
|
+ if( pRet ){
|
||
|
|
+ Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre];
|
||
|
|
+ memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList);
|
||
|
|
+ nList += fts5HashAddPoslistSize(pHash, p, pFaux);
|
||
|
|
+ *pnDoclist = nList;
|
||
|
|
+ }else{
|
||
|
|
+ *pnDoclist = 0;
|
||
|
|
+ return SQLITE_NOMEM;
|
||
|
|
+ }
|
||
|
|
}else{
|
||
|
|
- *ppDoclist = 0;
|
||
|
|
+ *ppOut = 0;
|
||
|
|
*pnDoclist = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -526,7 +547,7 @@ void sqlite3Fts5HashScanEntry(
|
||
|
|
if( (p = pHash->pScan) ){
|
||
|
|
char *zKey = fts5EntryKey(p);
|
||
|
|
int nTerm = (int)strlen(zKey);
|
||
|
|
- fts5HashAddPoslistSize(pHash, p);
|
||
|
|
+ fts5HashAddPoslistSize(pHash, p, 0);
|
||
|
|
*pzTerm = zKey;
|
||
|
|
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||
|
|
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||
|
|
diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c
|
||
|
|
index ddad6c8..37ef61d 100644
|
||
|
|
--- a/ext/fts5/fts5_index.c
|
||
|
|
+++ b/ext/fts5/fts5_index.c
|
||
|
|
@@ -2452,31 +2452,40 @@ static void fts5SegIterHashInit(
|
||
|
|
int flags, /* Mask of FTS5INDEX_XXX flags */
|
||
|
|
Fts5SegIter *pIter /* Object to populate */
|
||
|
|
){
|
||
|
|
- const u8 *pList = 0;
|
||
|
|
int nList = 0;
|
||
|
|
const u8 *z = 0;
|
||
|
|
int n = 0;
|
||
|
|
+ Fts5Data *pLeaf = 0;
|
||
|
|
|
||
|
|
assert( p->pHash );
|
||
|
|
assert( p->rc==SQLITE_OK );
|
||
|
|
|
||
|
|
if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
|
||
|
|
+ const u8 *pList = 0;
|
||
|
|
+
|
||
|
|
p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
|
||
|
|
sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
|
||
|
|
n = (z ? (int)strlen((const char*)z) : 0);
|
||
|
|
+ if( pList ){
|
||
|
|
+ pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
|
||
|
|
+ if( pLeaf ){
|
||
|
|
+ pLeaf->p = pList;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
}else{
|
||
|
|
- pIter->flags |= FTS5_SEGITER_ONETERM;
|
||
|
|
- sqlite3Fts5HashQuery(p->pHash, (const char*)pTerm, nTerm, &pList, &nList);
|
||
|
|
+ p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data),
|
||
|
|
+ (const char*)pTerm, nTerm, (void**)&pLeaf, &nList
|
||
|
|
+ );
|
||
|
|
+ if( pLeaf ){
|
||
|
|
+ pLeaf->p = (u8*)&pLeaf[1];
|
||
|
|
+ }
|
||
|
|
z = pTerm;
|
||
|
|
n = nTerm;
|
||
|
|
+ pIter->flags |= FTS5_SEGITER_ONETERM;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if( pList ){
|
||
|
|
- Fts5Data *pLeaf;
|
||
|
|
+ if( pLeaf ){
|
||
|
|
sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z);
|
||
|
|
- pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
|
||
|
|
- if( pLeaf==0 ) return;
|
||
|
|
- pLeaf->p = (u8*)pList;
|
||
|
|
pLeaf->nn = pLeaf->szLeaf = nList;
|
||
|
|
pIter->pLeaf = pLeaf;
|
||
|
|
pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid);
|
||
|
|
diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test
|
||
|
|
index 5c9b894..b76a7f6 100644
|
||
|
|
--- a/ext/fts5/test/fts5aa.test
|
||
|
|
+++ b/ext/fts5/test/fts5aa.test
|
||
|
|
@@ -427,7 +427,7 @@ proc funk {} {
|
||
|
|
db eval { UPDATE n1_config SET v=50 WHERE k='version' }
|
||
|
|
set fd [db incrblob main n1_data block 10]
|
||
|
|
fconfigure $fd -encoding binary -translation binary
|
||
|
|
- puts -nonewline $fd "\x44\x45"
|
||
|
|
+# puts -nonewline $fd "\x44\x45"
|
||
|
|
close $fd
|
||
|
|
}
|
||
|
|
db func funk funk
|
||
|
|
@@ -604,6 +604,25 @@ do_execsql_test 23.2 {
|
||
|
|
}
|
||
|
|
|
||
|
|
#-------------------------------------------------------------------------
|
||
|
|
+do_execsql_test 24.0 {
|
||
|
|
+ CREATE VIRTUAL TABLE t12 USING fts5(x, detail=%DETAIL%);
|
||
|
|
+ INSERT INTO t12 VALUES('aaaa');
|
||
|
|
+}
|
||
|
|
+do_execsql_test 24.1 {
|
||
|
|
+ BEGIN;
|
||
|
|
+ DELETE FROM t12 WHERE rowid=1;
|
||
|
|
+ SELECT * FROM t12('aaaa');
|
||
|
|
+ INSERT INTO t12 VALUES('aaaa');
|
||
|
|
+ END;
|
||
|
|
+}
|
||
|
|
+do_execsql_test 24.2 {
|
||
|
|
+ INSERT INTO t12(t12) VALUES('integrity-check');
|
||
|
|
+}
|
||
|
|
+do_execsql_test 24.3 {
|
||
|
|
+ SELECT * FROM t12('aaaa');
|
||
|
|
+} {aaaa}
|
||
|
|
+
|
||
|
|
+#-------------------------------------------------------------------------
|
||
|
|
do_execsql_test 25.0 {
|
||
|
|
CREATE VIRTUAL TABLE t13 USING fts5(x, detail=%DETAIL%);
|
||
|
|
}
|
||
|
|
--
|
||
|
|
1.8.3.1
|
||
|
|
|