From 83a2253409c9856093c1fc9be16c5793d295a375 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 14 Jan 2016 18:01:16 +0000 Subject: [PATCH 01/29] Minor adjustments to the MSVC makefile. FossilOrigin-Name: e2cba1bbfdcb24e35b2275e29071d8a4e4943417 --- Makefile.msc | 8 ++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 0eb660adc7..728154737b 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1714,8 +1714,8 @@ fts5_ext.lo: fts5.c $(HDR) $(EXTHDR) fts5.dll: fts5_ext.lo $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ fts5_ext.lo -sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c +sqlite3rbu.lo: $(TOP)\ext\rbu\sqlite3rbu.c $(HDR) $(EXTHDR) + $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\rbu\sqlite3rbu.c # Rules to build the 'testfixture' application. # @@ -1840,8 +1840,8 @@ speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) - $(LTLINK) $(NO_WARN) -I. -DSQLITE_ENABLE_RBU -Fe$@ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) \ - $(LDFLAGS) $(LTLINKOPTS) + $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) \ + /link $(LDFLAGS) $(LTLINKOPTS) clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL diff --git a/manifest b/manifest index 1354db7a40..199dfc584f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Yet\sanother\schange\sto\sFTS5\strying\sto\sget\sit\sto\smerge\ssuccessfully\sinto\ssessions. -D 2016-01-14T14:33:36.733 +C Minor\sadjustments\sto\sthe\sMSVC\smakefile. +D 2016-01-14T18:01:16.348 F Makefile.in cfa1ac03c4b414992fd53f24d978b45b0c21de55 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 1dc36cfd3c047c9685e539257e158485f16ef035 +F Makefile.msc 2d8b2ad5a03315940bcb9e64145ab70850d66b4d F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1412,7 +1412,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f791fc7009d68941c60d7bf953bab19d86112133 -R 52083946c40dd4f44744cbc0b447540f -U drh -Z 9b36451b3b0b6d81cfd6f7c438e3b3aa +P 8dedff3b9ac3e6bf9c131fee19f7d26dc1ebd61f +R ed5fce327e310c7f92985b6ea8c3a0f4 +U mistachkin +Z a106ef292e4f8d6ed0328b1e83183a0f diff --git a/manifest.uuid b/manifest.uuid index 92616336df..754bc8aa98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8dedff3b9ac3e6bf9c131fee19f7d26dc1ebd61f \ No newline at end of file +e2cba1bbfdcb24e35b2275e29071d8a4e4943417 \ No newline at end of file From 3349620e9eb892ae05a54c9141755adf9ec96a93 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Jan 2016 19:32:46 +0000 Subject: [PATCH 02/29] Simplification to the ISO8610 parser in the imnplementation of date/time functions. FossilOrigin-Name: b9159f42a517a95ae52464c96431708c00b7bb36 --- manifest | 14 +++++------ manifest.uuid | 2 +- src/date.c | 70 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 199dfc584f..a9997b0834 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sadjustments\sto\sthe\sMSVC\smakefile. -D 2016-01-14T18:01:16.348 +C Simplification\sto\sthe\sISO8610\sparser\sin\sthe\simnplementation\sof\sdate/time\nfunctions. +D 2016-01-14T19:32:46.777 F Makefile.in cfa1ac03c4b414992fd53f24d978b45b0c21de55 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 2d8b2ad5a03315940bcb9e64145ab70850d66b4d @@ -288,7 +288,7 @@ F src/build.c 9d497ff4bf3c82cecb520436e0e9963785627583 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 -F src/date.c e4655393bb403fa310eef66cc4583d75d4d7fd93 +F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c fe55c489362d1429c364e98c877514f4455f45a6 @@ -1412,7 +1412,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8dedff3b9ac3e6bf9c131fee19f7d26dc1ebd61f -R ed5fce327e310c7f92985b6ea8c3a0f4 -U mistachkin -Z a106ef292e4f8d6ed0328b1e83183a0f +P e2cba1bbfdcb24e35b2275e29071d8a4e4943417 +R 79fbdde13a17c7cb82657d609276debb +U drh +Z 2e5da468d29690cad1fa7e36751b6984 diff --git a/manifest.uuid b/manifest.uuid index 754bc8aa98..7e5be39175 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2cba1bbfdcb24e35b2275e29071d8a4e4943417 \ No newline at end of file +b9159f42a517a95ae52464c96431708c00b7bb36 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 3d7604ab45..d78e83cf57 100644 --- a/src/date.c +++ b/src/date.c @@ -70,34 +70,49 @@ struct DateTime { /* -** Convert zDate into one or more integers. Additional arguments -** come in groups of 5 as follows: +** Convert zDate into one or more integers according to the conversion +** specifier zFormat. ** -** N number of digits in the integer -** min minimum allowed value of the integer -** max maximum allowed value of the integer -** nextC first character after the integer -** pVal where to write the integers value. +** zFormat[] contains 4 characters for each integer converted, except for +** the last integer which is specified by three characters. The meaning +** of a four-character format specifiers ABCD is: +** +** A: number of digits to convert. Always "2" or "4". +** B: minimum value. Always "0" or "1". +** C: maximum value, decoded as: +** a: 12 +** b: 14 +** c: 24 +** d: 31 +** e: 59 +** f: 9999 +** D: the separator character, or \000 to indicate this is the +** last number to convert. +** +** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would +** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-". +** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates +** the 2-digit day which is the last integer in the set. ** -** Conversions continue until one with nextC==0 is encountered. ** The function returns the number of successful conversions. */ -static int getDigits(const char *zDate, ...){ +static int getDigits(const char *zDate, const char *zFormat, ...){ + /* The aMx[] array translates the 3rd character of each format + ** spec into a max size: a b c d e f */ + static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; va_list ap; - int val; - int N; - int min; - int max; - int nextC; - int *pVal; int cnt = 0; - va_start(ap, zDate); + char nextC; + va_start(ap, zFormat); do{ - N = va_arg(ap, int); - min = va_arg(ap, int); - max = va_arg(ap, int); - nextC = va_arg(ap, int); - pVal = va_arg(ap, int*); + char N = zFormat[0] - '0'; + char min = zFormat[1] - '0'; + int val = 0; + u16 max; + + assert( zFormat[2]>='a' && zFormat[2]<='f' ); + max = aMx[zFormat[2] - 'a']; + nextC = zFormat[3]; val = 0; while( N-- ){ if( !sqlite3Isdigit(*zDate) ){ @@ -106,12 +121,13 @@ static int getDigits(const char *zDate, ...){ val = val*10 + *zDate - '0'; zDate++; } - if( valmax || (nextC!=0 && nextC!=*zDate) ){ + if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){ goto end_getDigits; } - *pVal = val; + *va_arg(ap,int*) = val; zDate++; cnt++; + zFormat += 4; }while( nextC ); end_getDigits: va_end(ap); @@ -152,7 +168,7 @@ static int parseTimezone(const char *zDate, DateTime *p){ return c!=0; } zDate++; - if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ + if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){ return 1; } zDate += 5; @@ -173,13 +189,13 @@ zulu_time: static int parseHhMmSs(const char *zDate, DateTime *p){ int h, m, s; double ms = 0.0; - if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){ + if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){ return 1; } zDate += 5; if( *zDate==':' ){ zDate++; - if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ + if( getDigits(zDate, "20e", &s)!=1 ){ return 1; } zDate += 2; @@ -267,7 +283,7 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ }else{ neg = 0; } - if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){ + if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){ return 1; } zDate += 10; From 2cfe049f40d61a17ababf57e0575a12f761a7841 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Jan 2016 20:05:59 +0000 Subject: [PATCH 03/29] Add a test to verify that the fts3 and fts5 "unicode61" tokenizers are byte for byte compatible. FossilOrigin-Name: 8ec8314354edc9d6f7d1c8a6370fd984a552a52f --- Makefile.in | 1 + Makefile.msc | 1 + ext/fts5/fts5_tcl.c | 32 ++- ext/fts5/fts5_test_tok.c | 482 ++++++++++++++++++++++++++++++++++++ ext/fts5/test/fts5tok1.test | 115 +++++++++ ext/fts5/test/fts5tok2.test | 47 ++++ main.mk | 3 +- manifest | 23 +- manifest.uuid | 2 +- 9 files changed, 692 insertions(+), 14 deletions(-) create mode 100644 ext/fts5/fts5_test_tok.c create mode 100644 ext/fts5/test/fts5tok1.test create mode 100644 ext/fts5/test/fts5tok2.test diff --git a/Makefile.in b/Makefile.in index 2782e765f5..005d529594 100644 --- a/Makefile.in +++ b/Makefile.in @@ -418,6 +418,7 @@ TESTSRC += \ $(TOP)/ext/misc/fuzzer.c \ $(TOP)/ext/fts5/fts5_tcl.c \ $(TOP)/ext/fts5/fts5_test_mi.c \ + $(TOP)/ext/fts5/fts5_test_tok.c \ $(TOP)/ext/misc/ieee754.c \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ diff --git a/Makefile.msc b/Makefile.msc index 728154737b..c8275fde25 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1087,6 +1087,7 @@ TESTEXT = \ $(TOP)\ext\misc\fuzzer.c \ $(TOP)\ext\fts5\fts5_tcl.c \ $(TOP)\ext\fts5\fts5_test_mi.c \ + $(TOP)\ext\fts5\fts5_test_tok.c \ $(TOP)\ext\misc\ieee754.c \ $(TOP)\ext\misc\nextchar.c \ $(TOP)\ext\misc\percentile.c \ diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index 4a331a59f4..e633f0ac58 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -23,7 +23,8 @@ #include extern int sqlite3_fts5_may_be_corrupt; -extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *); +extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*); +extern int sqlite3Fts5TestRegisterTok(sqlite3*, fts5_api*); /************************************************************************* ** This is a copy of the first part of the SqliteDb structure in @@ -1078,6 +1079,32 @@ static int f5tRegisterMatchinfo( return TCL_OK; } +static int f5tRegisterTok( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + sqlite3 *db = 0; + fts5_api *pApi = 0; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( f5tDbAndApi(interp, objv[1], &db, &pApi) ){ + return TCL_ERROR; + } + + rc = sqlite3Fts5TestRegisterTok(db, pApi); + if( rc!=SQLITE_OK ){ + Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE); + return TCL_ERROR; + } + return TCL_OK; +} + /* ** Entry point. */ @@ -1093,7 +1120,8 @@ int Fts5tcl_Init(Tcl_Interp *interp){ { "sqlite3_fts5_create_function", f5tCreateFunction, 0 }, { "sqlite3_fts5_may_be_corrupt", f5tMayBeCorrupt, 0 }, { "sqlite3_fts5_token_hash", f5tTokenHash, 0 }, - { "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 } + { "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 }, + { "sqlite3_fts5_register_fts5tokenize", f5tRegisterTok, 0 } }; int i; F5tTokenizerContext *pContext; diff --git a/ext/fts5/fts5_test_tok.c b/ext/fts5/fts5_test_tok.c new file mode 100644 index 0000000000..10af126c10 --- /dev/null +++ b/ext/fts5/fts5_test_tok.c @@ -0,0 +1,482 @@ +/* +** 2013 Apr 22 +** +** 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 contains code for the "fts5tokenize" virtual table module. +** An fts5tokenize virtual table is created as follows: +** +** CREATE VIRTUAL TABLE USING fts5tokenize( +** , , ... +** ); +** +** The table created has the following schema: +** +** CREATE TABLE (input HIDDEN, token, start, end, position) +** +** When queried, the query must include a WHERE clause of type: +** +** input = +** +** The virtual table module tokenizes this , using the FTS3 +** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE +** statement and returns one row for each token in the result. With +** fields set as follows: +** +** input: Always set to a copy of +** token: A token from the input. +** start: Byte offset of the token within the input . +** end: Byte offset of the byte immediately following the end of the +** token within the input string. +** pos: Token offset of token within input. +** +*/ +#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5) + +#include +#include +#include + +typedef struct Fts5tokTable Fts5tokTable; +typedef struct Fts5tokCursor Fts5tokCursor; +typedef struct Fts5tokRow Fts5tokRow; + +/* +** Virtual table structure. +*/ +struct Fts5tokTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + fts5_tokenizer tok; /* Tokenizer functions */ + Fts5Tokenizer *pTok; /* Tokenizer instance */ +}; + +/* +** A container for a rows values. +*/ +struct Fts5tokRow { + char *zToken; + int iStart; + int iEnd; + int iPos; +}; + +/* +** Virtual table cursor structure. +*/ +struct Fts5tokCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + int iRowid; /* Current 'rowid' value */ + char *zInput; /* Input string */ + int nRow; /* Number of entries in aRow[] */ + Fts5tokRow *aRow; /* Array of rows to return */ +}; + +static void fts5tokDequote(char *z){ + char q = z[0]; + + if( q=='[' || q=='\'' || q=='"' || q=='`' ){ + int iIn = 1; + int iOut = 0; + if( q=='[' ) q = ']'; + + while( z[iIn] ){ + if( z[iIn]==q ){ + if( z[iIn+1]!=q ){ + /* Character iIn was the close quote. */ + iIn++; + break; + }else{ + /* Character iIn and iIn+1 form an escaped quote character. Skip + ** the input cursor past both and copy a single quote character + ** to the output buffer. */ + iIn += 2; + z[iOut++] = q; + } + }else{ + z[iOut++] = z[iIn++]; + } + } + + z[iOut] = '\0'; + } +} + +/* +** The second argument, argv[], is an array of pointers to nul-terminated +** strings. This function makes a copy of the array and strings into a +** single block of memory. It then dequotes any of the strings that appear +** to be quoted. +** +** If successful, output parameter *pazDequote is set to point at the +** array of dequoted strings and SQLITE_OK is returned. The caller is +** responsible for eventually calling sqlite3_free() to free the array +** in this case. Or, if an error occurs, an SQLite error code is returned. +** The final value of *pazDequote is undefined in this case. +*/ +static int fts5tokDequoteArray( + int argc, /* Number of elements in argv[] */ + const char * const *argv, /* Input array */ + char ***pazDequote /* Output array */ +){ + int rc = SQLITE_OK; /* Return code */ + if( argc==0 ){ + *pazDequote = 0; + }else{ + int i; + int nByte = 0; + char **azDequote; + + for(i=0; i0 ){ + zModule = azDequote[0]; + } + + rc = pApi->xFindTokenizer(pApi, zModule, &pTokCtx, &pTab->tok); + if( rc==SQLITE_OK ){ + const char **azArg = (const char **)&azDequote[1]; + int nArg = nDequote>0 ? nDequote-1 : 0; + rc = pTab->tok.xCreate(pTokCtx, azArg, nArg, &pTab->pTok); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(pTab); + pTab = 0; + } + + *ppVtab = (sqlite3_vtab*)pTab; + sqlite3_free(azDequote); + return rc; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts5tokDisconnectMethod(sqlite3_vtab *pVtab){ + Fts5tokTable *pTab = (Fts5tokTable *)pVtab; + if( pTab->pTok ){ + pTab->tok.xDelete(pTab->pTok); + } + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts5tokBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable + && pInfo->aConstraint[i].iColumn==0 + && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + pInfo->idxNum = 1; + pInfo->aConstraintUsage[i].argvIndex = 1; + pInfo->aConstraintUsage[i].omit = 1; + pInfo->estimatedCost = 1; + return SQLITE_OK; + } + } + + pInfo->idxNum = 0; + assert( pInfo->estimatedCost>1000000.0 ); + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts5tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts5tokCursor *pCsr; + + pCsr = (Fts5tokCursor *)sqlite3_malloc(sizeof(Fts5tokCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts5tokCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Reset the tokenizer cursor passed as the only argument. As if it had +** just been returned by fts5tokOpenMethod(). +*/ +static void fts5tokResetCursor(Fts5tokCursor *pCsr){ + int i; + for(i=0; inRow; i++){ + sqlite3_free(pCsr->aRow[i].zToken); + } + sqlite3_free(pCsr->zInput); + sqlite3_free(pCsr->aRow); + pCsr->zInput = 0; + pCsr->aRow = 0; + pCsr->nRow = 0; + pCsr->iRowid = 0; +} + +/* +** xClose - Close a cursor. +*/ +static int fts5tokCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor; + fts5tokResetCursor(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts5tokNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor; + pCsr->iRowid++; + return SQLITE_OK; +} + +static int fts5tokCb( + void *pCtx, /* Pointer to Fts5tokCursor */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ +){ + Fts5tokCursor *pCsr = (Fts5tokCursor*)pCtx; + Fts5tokRow *pRow; + + if( (pCsr->nRow & (pCsr->nRow-1))==0 ){ + int nNew = pCsr->nRow ? pCsr->nRow*2 : 32; + Fts5tokRow *aNew; + aNew = (Fts5tokRow*)sqlite3_realloc(pCsr->aRow, nNew*sizeof(Fts5tokRow)); + if( aNew==0 ) return SQLITE_NOMEM; + memset(&aNew[pCsr->nRow], 0, sizeof(Fts5tokRow)*(nNew-pCsr->nRow)); + pCsr->aRow = aNew; + } + + pRow = &pCsr->aRow[pCsr->nRow]; + pRow->iStart = iStart; + pRow->iEnd = iEnd; + if( pCsr->nRow ){ + pRow->iPos = pRow[-1].iPos + ((tflags & FTS5_TOKEN_COLOCATED) ? 0 : 1); + } + pRow->zToken = sqlite3_malloc(nToken+1); + if( pRow->zToken==0 ) return SQLITE_NOMEM; + memcpy(pRow->zToken, pToken, nToken); + pRow->zToken[nToken] = 0; + pCsr->nRow++; + + return SQLITE_OK; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts5tokFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_ERROR; + Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor; + Fts5tokTable *pTab = (Fts5tokTable *)(pCursor->pVtab); + + fts5tokResetCursor(pCsr); + if( idxNum==1 ){ + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); + int nByte = sqlite3_value_bytes(apVal[0]); + pCsr->zInput = sqlite3_malloc(nByte+1); + if( pCsr->zInput==0 ){ + rc = SQLITE_NOMEM; + }else{ + memcpy(pCsr->zInput, zByte, nByte); + pCsr->zInput[nByte] = 0; + rc = pTab->tok.xTokenize( + pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb + ); + } + } + + if( rc!=SQLITE_OK ) return rc; + return fts5tokNextMethod(pCursor); +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts5tokEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor; + return (pCsr->iRowid>pCsr->nRow); +} + +/* +** xColumn - Return a column value. +*/ +static int fts5tokColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor; + Fts5tokRow *pRow = &pCsr->aRow[pCsr->iRowid-1]; + + /* CREATE TABLE x(input, token, start, end, position) */ + switch( iCol ){ + case 0: + sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); + break; + case 1: + sqlite3_result_text(pCtx, pRow->zToken, -1, SQLITE_TRANSIENT); + break; + case 2: + sqlite3_result_int(pCtx, pRow->iStart); + break; + case 3: + sqlite3_result_int(pCtx, pRow->iEnd); + break; + default: + assert( iCol==4 ); + sqlite3_result_int(pCtx, pRow->iPos); + break; + } + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts5tokRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor; + *pRowid = (sqlite3_int64)pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts5tok module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +int sqlite3Fts5TestRegisterTok(sqlite3 *db, fts5_api *pApi){ + static const sqlite3_module fts5tok_module = { + 0, /* iVersion */ + fts5tokConnectMethod, /* xCreate */ + fts5tokConnectMethod, /* xConnect */ + fts5tokBestIndexMethod, /* xBestIndex */ + fts5tokDisconnectMethod, /* xDisconnect */ + fts5tokDisconnectMethod, /* xDestroy */ + fts5tokOpenMethod, /* xOpen */ + fts5tokCloseMethod, /* xClose */ + fts5tokFilterMethod, /* xFilter */ + fts5tokNextMethod, /* xNext */ + fts5tokEofMethod, /* xEof */ + fts5tokColumnMethod, /* xColumn */ + fts5tokRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module(db, "fts5tokenize", &fts5tok_module, (void*)pApi); + return rc; +} + +#endif /* defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5) */ diff --git a/ext/fts5/test/fts5tok1.test b/ext/fts5/test/fts5tok1.test new file mode 100644 index 0000000000..6ba170062e --- /dev/null +++ b/ext/fts5/test/fts5tok1.test @@ -0,0 +1,115 @@ +# 2016 Jan 15 +# +# 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. +# +#************************************************************************* +# + +source [file join [file dirname [info script]] fts5_common.tcl] +ifcapable !fts5 { finish_test ; return } +set ::testprefix fts5tok1 + + +sqlite3_fts5_register_fts5tokenize db + +#------------------------------------------------------------------------- +# Simple test cases. Using the default (ascii) tokenizer. +# +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5tokenize(ascii); + CREATE VIRTUAL TABLE t2 USING fts5tokenize(); + CREATE VIRTUAL TABLE t3 USING fts5tokenize( + ascii, 'separators', 'xyz', tokenchars, '''' + ); +} + +foreach {tn tbl} {1 t1 2 t2 3 t3} { + do_execsql_test 1.$tn.1 "SELECT input, * FROM $tbl ('one two three')" { + {one two three} one 0 3 0 + {one two three} two 4 7 1 + {one two three} three 8 13 2 + } + + do_execsql_test 1.$tn.2 " + SELECT token FROM $tbl WHERE input = 'OnE tWo tHrEe' + " { + one two three + } +} + +do_execsql_test 1.4 { + SELECT token FROM t3 WHERE input = '1x2x3x' +} {1 2 3} + +do_execsql_test 1.5 { + SELECT token FROM t1 WHERE input = '1x2x3x' +} {1x2x3x} + +do_execsql_test 1.6 { + SELECT token FROM t3 WHERE input = '1''2x3x' +} {1'2 3} + +do_execsql_test 1.7 { + SELECT token FROM t3 WHERE input = '' +} {} + +do_execsql_test 1.8 { + SELECT token FROM t3 WHERE input = NULL +} {} + +do_execsql_test 1.9 { + SELECT input, * FROM t3 WHERE input = 123 +} {123 123 0 3 0} + +do_execsql_test 1.10 { + SELECT input, * FROM t1 WHERE input = 'a b c' AND token = 'b'; +} { + {a b c} b 2 3 1 +} + +do_execsql_test 1.11 { + SELECT input, * FROM t1 WHERE token = 'b' AND input = 'a b c'; +} { + {a b c} b 2 3 1 +} + +do_execsql_test 1.12 { + SELECT input, * FROM t1 WHERE input < 'b' AND input = 'a b c'; +} { + {a b c} a 0 1 0 + {a b c} b 2 3 1 + {a b c} c 4 5 2 +} + +do_execsql_test 1.13.1 { + CREATE TABLE c1(x); + INSERT INTO c1(x) VALUES('a b c'); + INSERT INTO c1(x) VALUES('d e f'); +} +do_execsql_test 1.13.2 { + SELECT c1.*, input, t1.* FROM c1, t1 WHERE input = x AND c1.rowid=t1.rowid; +} { + {a b c} {a b c} a 0 1 0 + {d e f} {d e f} e 2 3 1 +} + + +#------------------------------------------------------------------------- +# Error cases. +# +do_catchsql_test 2.0 { + CREATE VIRTUAL TABLE tX USING fts5tokenize(nosuchtokenizer); +} {1 {vtable constructor failed: tX}} + +do_catchsql_test 2.1 { + CREATE VIRTUAL TABLE t4 USING fts5tokenize; + SELECT * FROM t4; +} {1 {SQL logic error or missing database}} + + +finish_test diff --git a/ext/fts5/test/fts5tok2.test b/ext/fts5/test/fts5tok2.test new file mode 100644 index 0000000000..77c7e1ec8e --- /dev/null +++ b/ext/fts5/test/fts5tok2.test @@ -0,0 +1,47 @@ +# 2016 Jan 15 +# +# 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. +# +#************************************************************************* +# + +source [file join [file dirname [info script]] fts5_common.tcl] +ifcapable !fts5||!fts3 { finish_test ; return } +set ::testprefix fts5tok2 + +sqlite3_fts5_register_fts5tokenize db + +#------------------------------------------------------------------------- +# Simple test cases. Using the default (ascii) tokenizer. +# +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t5 USING fts5tokenize(unicode61); + CREATE VIRTUAL TABLE t3 USING fts3tokenize(unicode61); +} + +do_test 1.1 { + array unset -nocomplain A + + for {set i 1} {$i < 65536} {incr i} { + set input [format "abc%cxyz" $i] + set expect [execsql { + SELECT input, token, start, end FROM t3 WHERE input=$input + }] + + incr A([llength $expect]) + + set res [execsql { + SELECT input, token, start, end FROM t5($input) + }] + if {$res != $expect} {error "failed at i=$i"} + } +} {} + +do_test 1.1.nTokenChars=$A(4).nSeparators=$A(8) {} {} + +finish_test diff --git a/main.mk b/main.mk index e6ca1acbd6..7aaa58fffd 100644 --- a/main.mk +++ b/main.mk @@ -333,7 +333,8 @@ TESTSRC += \ $(TOP)/ext/misc/wholenumber.c \ $(TOP)/ext/misc/vfslog.c \ $(TOP)/ext/fts5/fts5_tcl.c \ - $(TOP)/ext/fts5/fts5_test_mi.c + $(TOP)/ext/fts5/fts5_test_mi.c \ + $(TOP)/ext/fts5/fts5_test_tok.c #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c diff --git a/manifest b/manifest index a9997b0834..1c030127fd 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Simplification\sto\sthe\sISO8610\sparser\sin\sthe\simnplementation\sof\sdate/time\nfunctions. -D 2016-01-14T19:32:46.777 -F Makefile.in cfa1ac03c4b414992fd53f24d978b45b0c21de55 +C Add\sa\stest\sto\sverify\sthat\sthe\sfts3\sand\sfts5\s"unicode61"\stokenizers\sare\sbyte\sfor\sbyte\scompatible. +D 2016-01-14T20:05:59.293 +F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 2d8b2ad5a03315940bcb9e64145ab70850d66b4d +F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -106,8 +106,9 @@ F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 F ext/fts5/fts5_index.c aa798d3a839847fd351b3d0f49520f190e57c2e3 F ext/fts5/fts5_main.c 488ceecdb4400ecc6a3d3b2247cedef153955388 F ext/fts5/fts5_storage.c f7b2d330dd7b29a9f4da09f6d85879ca8c41b2e8 -F ext/fts5/fts5_tcl.c 18e9382d8cdad4c05b49559c68494968b9b4a4fb +F ext/fts5/fts5_tcl.c bcacc05dec0446e7b1a44d5d906057e677bd7ea4 F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 +F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 @@ -174,6 +175,8 @@ F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 F ext/fts5/test/fts5simple2.test 843f1f7fe439ff32bf74f4fd6430632f9636ef3a F ext/fts5/test/fts5synonym.test cf88c0a56d5ea9591e3939ef1f6e294f7f2d0671 F ext/fts5/test/fts5synonym2.test d2d9099d9d105b55ea03fd52d61ae2847d534129 +F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 +F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89 F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59 @@ -262,7 +265,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 20e46c09ac8732a74a9e2d55e8d90257d97eb844 +F main.mk 55f0940264e55540773214ee1f2dbba0bf359957 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1412,7 +1415,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e2cba1bbfdcb24e35b2275e29071d8a4e4943417 -R 79fbdde13a17c7cb82657d609276debb -U drh -Z 2e5da468d29690cad1fa7e36751b6984 +P b9159f42a517a95ae52464c96431708c00b7bb36 +R e09ac1cbb3100668573769c5e2d7569a +U dan +Z 6d6590c289b1d7ff01c17cc7ff7964e6 diff --git a/manifest.uuid b/manifest.uuid index 7e5be39175..98da96e742 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9159f42a517a95ae52464c96431708c00b7bb36 \ No newline at end of file +8ec8314354edc9d6f7d1c8a6370fd984a552a52f \ No newline at end of file From 2d80151f324fc8b4ba93c96bfc7547ce62a8a80f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Jan 2016 22:19:58 +0000 Subject: [PATCH 04/29] Combine the xFunc and xStep pointers of the FuncDef object into a single pointer xSFunc. FossilOrigin-Name: 0d1b3d7d3ca66cb0b97493f1aeade1703af3c9f4 --- manifest | 34 +++++++++++++++++----------------- manifest.uuid | 2 +- src/analyze.c | 9 +++------ src/attach.c | 6 ++---- src/callback.c | 10 +++++----- src/expr.c | 2 +- src/main.c | 27 +++++++++++++-------------- src/resolve.c | 2 +- src/sqliteInt.h | 21 ++++++++++----------- src/vdbe.c | 6 +++--- src/vdbeapi.c | 4 ++-- src/vdbemem.c | 2 +- src/vtab.c | 6 +++--- 13 files changed, 62 insertions(+), 69 deletions(-) diff --git a/manifest b/manifest index 1c030127fd..01c7dc6b20 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\sto\sverify\sthat\sthe\sfts3\sand\sfts5\s"unicode61"\stokenizers\sare\sbyte\sfor\sbyte\scompatible. -D 2016-01-14T20:05:59.293 +C Combine\sthe\sxFunc\sand\sxStep\spointers\sof\sthe\sFuncDef\sobject\sinto\sa\ssingle\npointer\sxSFunc. +D 2016-01-14T22:19:58.884 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -278,8 +278,8 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267 -F src/analyze.c 977bd50c751bb939ef52917892e12bedbfcea7ce -F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395 +F src/analyze.c 905d387f6f7e89866e1dc73e13b6e09172bee350 +F src/attach.c ec9f119ca7542b5364924aab84f214440f8ac9e5 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf @@ -288,13 +288,13 @@ F src/btree.c 5d93e2477acb99d50a8b045f2e26a0be3d7751fe F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 9d497ff4bf3c82cecb520436e0e9963785627583 -F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 +F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da -F src/expr.c fe55c489362d1429c364e98c877514f4455f45a6 +F src/expr.c 9a1a4150864f002b633d12f170a4114c28bbe94d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44 F src/func.c ccaf46fa98f795673afbfab73dff7c18db88f3cd @@ -306,7 +306,7 @@ F src/insert.c 6b45cc86967da11aa024d034745f93f66d53f650 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b -F src/main.c 6d589f27980c4aec014ae9a081d611e7e5ebc115 +F src/main.c 6bcb3de6b4f02552d3df44f2ef73ff6b7ccf5322 F src/malloc.c 8f787669e79de26efc42272b5797bc00fff527c6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -339,14 +339,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c a83b41104e6ff69855d03cd0aaa09e93927ec39f +F src/resolve.c 08dbe0292b24abc79b0c55ea97368e8a6bd235ec F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 5b0f2aa9f73ec7b65d1711d485471854d5bad23c F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h b8ccd34a919e4b6bab8c4164046330002aa9a27a +F src/sqliteInt.h 028d1f88501048b5258f7119032278a55c963512 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -406,16 +406,16 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 6572d00eefeaa0b14b325fdf3a409920ec3fee82 +F src/vdbe.c 4f3585480f61f96af3327e921baad223af0ce23e F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 -F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca +F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e F src/vdbeaux.c f2e6b4fae037db04323be8de7bcd266375746471 F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15 -F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045 +F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806 +F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde F src/vxworks.h 974e7d9a98f602d6310d563e1dc4e08f9fc48e47 F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -1415,7 +1415,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b9159f42a517a95ae52464c96431708c00b7bb36 -R e09ac1cbb3100668573769c5e2d7569a -U dan -Z 6d6590c289b1d7ff01c17cc7ff7964e6 +P 8ec8314354edc9d6f7d1c8a6370fd984a552a52f +R 470d19e0ca1a1fc910b5e91ee98341ee +U drh +Z f0946172c7ca453502410c246bc450d2 diff --git a/manifest.uuid b/manifest.uuid index 98da96e742..154ae8ed29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ec8314354edc9d6f7d1c8a6370fd984a552a52f \ No newline at end of file +0d1b3d7d3ca66cb0b97493f1aeade1703af3c9f4 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 06918eb744..367dd698dd 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -478,8 +478,7 @@ static const FuncDef statInitFuncdef = { SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ - statInit, /* xFunc */ - 0, /* xStep */ + statInit, /* xSFunc */ 0, /* xFinalize */ "stat_init", /* zName */ 0, /* pHash */ @@ -779,8 +778,7 @@ static const FuncDef statPushFuncdef = { SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ - statPush, /* xFunc */ - 0, /* xStep */ + statPush, /* xSFunc */ 0, /* xFinalize */ "stat_push", /* zName */ 0, /* pHash */ @@ -926,8 +924,7 @@ static const FuncDef statGetFuncdef = { SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ - statGet, /* xFunc */ - 0, /* xStep */ + statGet, /* xSFunc */ 0, /* xFinalize */ "stat_get", /* zName */ 0, /* pHash */ diff --git a/src/attach.c b/src/attach.c index 2ab55e6ed6..2c47ed47ba 100644 --- a/src/attach.c +++ b/src/attach.c @@ -388,8 +388,7 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){ SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ - detachFunc, /* xFunc */ - 0, /* xStep */ + detachFunc, /* xSFunc */ 0, /* xFinalize */ "sqlite_detach", /* zName */ 0, /* pHash */ @@ -409,8 +408,7 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ - attachFunc, /* xFunc */ - 0, /* xStep */ + attachFunc, /* xSFunc */ 0, /* xFinalize */ "sqlite_attach", /* zName */ 0, /* pHash */ diff --git a/src/callback.c b/src/callback.c index cd213b4b28..2a9f5b802a 100644 --- a/src/callback.c +++ b/src/callback.c @@ -243,8 +243,8 @@ CollSeq *sqlite3FindCollSeq( ** 5: UTF16 byte order conversion required - argument count matches exactly ** 6: Perfect match: encoding and argument count match exactly. ** -** If nArg==(-2) then any function with a non-null xStep or xFunc is -** a perfect match and any function with both xStep and xFunc NULL is +** If nArg==(-2) then any function with a non-null xSFunc is +** a perfect match and any function with xSFunc NULL is ** a non-match. */ #define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ @@ -256,7 +256,7 @@ static int matchQuality( int match; /* nArg of -2 is a special case */ - if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH; + if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; /* Wrong number of arguments means "no match" */ if( p->nArg!=nArg && p->nArg>=0 ) return 0; @@ -334,7 +334,7 @@ void sqlite3FuncDefInsert( ** no matching function previously existed. ** ** If nArg is -2, then the first valid function found is returned. A -** function is valid if either xFunc or xStep is non-zero. The nArg==(-2) +** function is valid if xSFunc is non-zero. The nArg==(-2) ** case is used to see if zName is a valid function name for some number ** of arguments. If nArg is -2, then createFlag must be 0. ** @@ -411,7 +411,7 @@ FuncDef *sqlite3FindFunction( sqlite3FuncDefInsert(&db->aFunc, pBest); } - if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ + if( pBest && (pBest->xSFunc || createFlag) ){ return pBest; } return 0; diff --git a/src/expr.c b/src/expr.c index 3be3bf52db..b8cf3f7720 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2896,7 +2896,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); - if( pDef==0 || pDef->xFunc==0 ){ + if( pDef==0 || pDef->xFinalize!=0 ){ sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); break; } diff --git a/src/main.c b/src/main.c index 2998f54c77..35c0607b47 100644 --- a/src/main.c +++ b/src/main.c @@ -1575,7 +1575,7 @@ int sqlite3CreateFunc( int nArg, int enc, void *pUserData, - void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*), FuncDestructor *pDestructor @@ -1586,9 +1586,9 @@ int sqlite3CreateFunc( assert( sqlite3_mutex_held(db->mutex) ); if( zFunctionName==0 || - (xFunc && (xFinal || xStep)) || - (!xFunc && (xFinal && !xStep)) || - (!xFunc && (!xFinal && xStep)) || + (xSFunc && (xFinal || xStep)) || + (!xSFunc && (xFinal && !xStep)) || + (!xSFunc && (!xFinal && xStep)) || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; @@ -1611,10 +1611,10 @@ int sqlite3CreateFunc( }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, - pUserData, xFunc, xStep, xFinal, pDestructor); + pUserData, xSFunc, xStep, xFinal, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, - pUserData, xFunc, xStep, xFinal, pDestructor); + pUserData, xSFunc, xStep, xFinal, pDestructor); } if( rc!=SQLITE_OK ){ return rc; @@ -1658,8 +1658,7 @@ int sqlite3CreateFunc( p->pDestructor = pDestructor; p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; testcase( p->funcFlags & SQLITE_DETERMINISTIC ); - p->xFunc = xFunc; - p->xStep = xStep; + p->xSFunc = xSFunc ? xSFunc : xStep; p->xFinalize = xFinal; p->pUserData = pUserData; p->nArg = (u16)nArg; @@ -1675,11 +1674,11 @@ int sqlite3_create_function( int nArg, int enc, void *p, - void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*) ){ - return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep, + return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, 0); } @@ -1689,7 +1688,7 @@ int sqlite3_create_function_v2( int nArg, int enc, void *p, - void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*), void (*xDestroy)(void *) @@ -1712,7 +1711,7 @@ int sqlite3_create_function_v2( pArg->xDestroy = xDestroy; pArg->pUserData = p; } - rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg); + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg); if( pArg && pArg->nRef==0 ){ assert( rc!=SQLITE_OK ); xDestroy(p); @@ -1732,7 +1731,7 @@ int sqlite3_create_function16( int nArg, int eTextRep, void *p, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ){ @@ -1745,7 +1744,7 @@ int sqlite3_create_function16( sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0); sqlite3DbFree(db, zFunc8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); diff --git a/src/resolve.c b/src/resolve.c index bb6646256a..97cb6556ac 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -665,7 +665,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ wrong_num_args = 1; } }else{ - is_agg = pDef->xFunc==0; + is_agg = pDef->xFinalize!=0; if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ ExprSetProperty(pExpr, EP_Unlikely|EP_Skip); if( n==2 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a4d4f65f3c..a70b0cfb36 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1363,9 +1363,8 @@ struct FuncDef { u16 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ - void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */ - void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */ + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ + void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ char *zName; /* SQL name of the function. */ FuncDef *pHash; /* Next with a different name but the same hash */ FuncDestructor *pDestructor; /* Reference counted destructor function */ @@ -1448,28 +1447,28 @@ struct FuncDestructor { */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0} #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0} #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0} #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0} #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - pArg, 0, xFunc, 0, 0, #zName, 0, 0} + pArg, 0, xFunc, 0, #zName, 0, 0} #define LIKEFUNC(zName, nArg, arg, flags) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ - (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} + (void *)arg, 0, likeFunc, 0, #zName, 0, 0} #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0} #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ - SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0} /* ** All current savepoints are stored in a linked list starting at diff --git a/src/vdbe.c b/src/vdbe.c index 7eb4c0baeb..d4060cae96 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1662,8 +1662,8 @@ case OP_Function: { MemSetTypeFlag(pCtx->pOut, MEM_Null); pCtx->fErrorOrAux = 0; db->lastRowid = lastRowid; - (*pCtx->pFunc->xFunc)(pCtx, pCtx->argc, pCtx->argv); /* IMP: R-24505-23230 */ - lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */ + (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ + lastRowid = db->lastRowid; /* Remember rowid changes made by xSFunc */ /* If the function returned an error, throw an exception */ if( pCtx->fErrorOrAux ){ @@ -5903,7 +5903,7 @@ case OP_AggStep: { pCtx->pOut = &t; pCtx->fErrorOrAux = 0; pCtx->skipFlag = 0; - (pCtx->pFunc->xStep)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ + (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ if( pCtx->fErrorOrAux ){ if( pCtx->isError ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(&t)); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 33c6ba3b28..4bc912b940 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -779,7 +779,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ ** same context that was returned on prior calls. */ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ - assert( p && p->pFunc && p->pFunc->xStep ); + assert( p && p->pFunc && p->pFunc->xFinalize ); assert( sqlite3_mutex_held(p->pOut->db->mutex) ); testcase( nByte<0 ); if( (p->pMem->flags & MEM_Agg)==0 ){ @@ -870,7 +870,7 @@ failed: ** context. */ int sqlite3_aggregate_count(sqlite3_context *p){ - assert( p && p->pMem && p->pFunc && p->pFunc->xStep ); + assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize ); return p->pMem->n; } #endif diff --git a/src/vdbemem.c b/src/vdbemem.c index fae69b18a4..0eeb59ef85 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1224,7 +1224,7 @@ static int valueFromFunction( memset(&ctx, 0, sizeof(ctx)); ctx.pOut = pVal; ctx.pFunc = pFunc; - pFunc->xFunc(&ctx, nVal, apVal); + pFunc->xSFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); diff --git a/src/vtab.c b/src/vtab.c index 6054df3d71..ea79cd8cef 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -1016,7 +1016,7 @@ FuncDef *sqlite3VtabOverloadFunction( Table *pTab; sqlite3_vtab *pVtab; sqlite3_module *pMod; - void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0; + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0; void *pArg = 0; FuncDef *pNew; int rc = 0; @@ -1044,7 +1044,7 @@ FuncDef *sqlite3VtabOverloadFunction( for(z=(unsigned char*)zLowerName; *z; z++){ *z = sqlite3UpperToLower[*z]; } - rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); + rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg); sqlite3DbFree(db, zLowerName); } if( rc==0 ){ @@ -1061,7 +1061,7 @@ FuncDef *sqlite3VtabOverloadFunction( *pNew = *pDef; pNew->zName = (char *)&pNew[1]; memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1); - pNew->xFunc = xFunc; + pNew->xSFunc = xSFunc; pNew->pUserData = pArg; pNew->funcFlags |= SQLITE_FUNC_EPHEM; return pNew; From 1e38927c12c854970033b51aef7c41906912a238 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 15 Jan 2016 05:39:55 +0000 Subject: [PATCH 05/29] Fix a couple C99-isms in FTS5 that cause compile errors on MSVC. FossilOrigin-Name: 584848d4396d7755027fab377c97e40fbcc90d21 --- ext/fts5/fts5_index.c | 6 ++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 2f5b3bdaae..d5ea972414 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1875,13 +1875,15 @@ static void fts5SegIterNext( int iOff; int bNewTerm = 0; int nKeep = 0; + u8 *a; + int n; assert( pbNewTerm==0 || *pbNewTerm==0 ); assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE ); /* Search for the end of the position list within the current page. */ - u8 *a = pLeaf->p; - int n = pLeaf->szLeaf; + a = pLeaf->p; + n = pLeaf->szLeaf; ASSERT_SZLEAF_OK(pLeaf); iOff = pIter->iLeafOffset + pIter->nPos; diff --git a/manifest b/manifest index 01c7dc6b20..9643928154 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\sxFunc\sand\sxStep\spointers\sof\sthe\sFuncDef\sobject\sinto\sa\ssingle\npointer\sxSFunc. -D 2016-01-14T22:19:58.884 +C Fix\sa\scouple\sC99-isms\sin\sFTS5\sthat\scause\scompile\serrors\son\sMSVC. +D 2016-01-15T05:39:55.053 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -103,7 +103,7 @@ F ext/fts5/fts5_buffer.c 87204c8b3b8bc62b27376eab09b74d6d5acc41f1 F ext/fts5/fts5_config.c 9c243d04ac0ca997d2d2e2252891f2a10fbd7217 F ext/fts5/fts5_expr.c 510db45967ca359f64f2ba2c707ab57d740cad56 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c aa798d3a839847fd351b3d0f49520f190e57c2e3 +F ext/fts5/fts5_index.c cd036089b22b0340fccef88a3ad62ac1016c7cbb F ext/fts5/fts5_main.c 488ceecdb4400ecc6a3d3b2247cedef153955388 F ext/fts5/fts5_storage.c f7b2d330dd7b29a9f4da09f6d85879ca8c41b2e8 F ext/fts5/fts5_tcl.c bcacc05dec0446e7b1a44d5d906057e677bd7ea4 @@ -1415,7 +1415,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8ec8314354edc9d6f7d1c8a6370fd984a552a52f -R 470d19e0ca1a1fc910b5e91ee98341ee -U drh -Z f0946172c7ca453502410c246bc450d2 +P 0d1b3d7d3ca66cb0b97493f1aeade1703af3c9f4 +R b460170dac8e7d7fa7ff80be818c5f70 +U mistachkin +Z 9c8571095ec15b56fdafaa6935514e64 diff --git a/manifest.uuid b/manifest.uuid index 154ae8ed29..b39e9f110d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d1b3d7d3ca66cb0b97493f1aeade1703af3c9f4 \ No newline at end of file +584848d4396d7755027fab377c97e40fbcc90d21 \ No newline at end of file From 055f298ad49e107b9114017db4fb03e9b72cc7f9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Jan 2016 15:06:41 +0000 Subject: [PATCH 06/29] Work toward making the schema parsing logic simplier and more compact. FossilOrigin-Name: c52ca2c0662bb30ab34574f933429512655b19ff --- manifest | 20 ++++----- manifest.uuid | 2 +- src/btree.c | 119 +++++++++++++++++++++++++------------------------- src/build.c | 78 +++++++++++++++------------------ src/prepare.c | 58 +++++------------------- src/vdbe.c | 1 + 6 files changed, 115 insertions(+), 163 deletions(-) diff --git a/manifest b/manifest index 9643928154..21f3a58b93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sC99-isms\sin\sFTS5\sthat\scause\scompile\serrors\son\sMSVC. -D 2016-01-15T05:39:55.053 +C Work\stoward\smaking\sthe\sschema\sparsing\slogic\ssimplier\sand\smore\scompact. +D 2016-01-15T15:06:41.166 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -284,10 +284,10 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 5d93e2477acb99d50a8b045f2e26a0be3d7751fe +F src/btree.c d9c6b2e2df06314079aa582f12937401a62171a6 F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 9d497ff4bf3c82cecb520436e0e9963785627583 +F src/build.c 2778ccdb327923b2eb6cea304e232efd0c85cbe1 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -336,7 +336,7 @@ F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 +F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19 F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 08dbe0292b24abc79b0c55ea97368e8a6bd235ec @@ -406,7 +406,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 4f3585480f61f96af3327e921baad223af0ce23e +F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -1415,7 +1415,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0d1b3d7d3ca66cb0b97493f1aeade1703af3c9f4 -R b460170dac8e7d7fa7ff80be818c5f70 -U mistachkin -Z 9c8571095ec15b56fdafaa6935514e64 +P 584848d4396d7755027fab377c97e40fbcc90d21 +R d396ff3cd92323018eeceb835a86df32 +U drh +Z d625867287e0b3ea5f45a2d19f9bb7c8 diff --git a/manifest.uuid b/manifest.uuid index b39e9f110d..281520412b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -584848d4396d7755027fab377c97e40fbcc90d21 \ No newline at end of file +c52ca2c0662bb30ab34574f933429512655b19ff \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b5a1ee3b2c..eb0808f1d9 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8541,6 +8541,14 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ return SQLITE_LOCKED_SHAREDCACHE; } + /* + ** It is illegal to drop the sqlite_master table on page 1. But again, + ** this error is caught long before reaching this point. + */ + if( NEVER(iTable<2) ){ + return SQLITE_CORRUPT_BKPT; + } + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); if( rc ) return rc; rc = sqlite3BtreeClearTable(p, iTable, 0); @@ -8551,76 +8559,67 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ *piMoved = 0; - if( iTable>1 ){ #ifdef SQLITE_OMIT_AUTOVACUUM - freePage(pPage, &rc); - releasePage(pPage); + freePage(pPage, &rc); + releasePage(pPage); #else - if( pBt->autoVacuum ){ - Pgno maxRootPgno; - sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); - if( iTable==maxRootPgno ){ - /* If the table being dropped is the table with the largest root-page - ** number in the database, put the root page on the free list. - */ - freePage(pPage, &rc); - releasePage(pPage); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - /* The table being dropped does not have the largest root-page - ** number in the database. So move the page that does into the - ** gap left by the deleted root-page. - */ - MemPage *pMove; - releasePage(pPage); - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); - releasePage(pMove); - if( rc!=SQLITE_OK ){ - return rc; - } - pMove = 0; - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); - freePage(pMove, &rc); - releasePage(pMove); - if( rc!=SQLITE_OK ){ - return rc; - } - *piMoved = maxRootPgno; - } - - /* Set the new 'max-root-page' value in the database header. This - ** is the old value less one, less one more if that happens to - ** be a root-page number, less one again if that is the - ** PENDING_BYTE_PAGE. + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. */ - maxRootPgno--; - while( maxRootPgno==PENDING_BYTE_PAGE(pBt) - || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ - maxRootPgno--; - } - assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); - - rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); - }else{ freePage(pPage, &rc); releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; } -#endif - }else{ - /* If sqlite3BtreeDropTable was called on page 1. - ** This really never should happen except in a corrupt - ** database. + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. */ - zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); + maxRootPgno--; + while( maxRootPgno==PENDING_BYTE_PAGE(pBt) + || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + }else{ + freePage(pPage, &rc); releasePage(pPage); } +#endif return rc; } int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ diff --git a/src/build.c b/src/build.c index 6aac454172..7bc7fc898b 100644 --- a/src/build.c +++ b/src/build.c @@ -758,7 +758,8 @@ int sqlite3TwoPartName( int iDb; /* Database holding the object */ sqlite3 *db = pParse->db; - if( ALWAYS(pName2!=0) && pName2->n>0 ){ + assert( pName2!=0 ); + if( pName2->n>0 ){ if( db->init.busy ) { sqlite3ErrorMsg(pParse, "corrupt database"); return -1; @@ -847,62 +848,46 @@ void sqlite3StartTable( int iDb; /* Database number to create the table in */ Token *pName; /* Unqualified name of the table to create */ - /* The table or view name to create is passed to this routine via tokens - ** pName1 and pName2. If the table name was fully qualified, for example: - ** - ** CREATE TABLE xxx.yyy (...); - ** - ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if - ** the table name is not fully qualified, i.e.: - ** - ** CREATE TABLE yyy(...); - ** - ** Then pName1 is set to "yyy" and pName2 is "". - ** - ** The call below sets the pName pointer to point at the token (pName1 or - ** pName2) that stores the unqualified table name. The variable iDb is - ** set to the index of the database that the table or view is to be - ** created in. - */ - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); - if( iDb<0 ) return; - if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ - /* If creating a temp table, the name may not be qualified. Unless - ** the database name is "temp" anyway. */ - sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - return; + if( db->init.busy && db->init.newTnum==1 ){ + /* Special case: Parsing the sqlite_master or sqlite_temp_master schema */ + iDb = db->init.iDb; + zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb)); + pName = pName1; + }else{ + /* The common case */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) return; + if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ + /* If creating a temp table, the name may not be qualified. Unless + ** the database name is "temp" anyway. */ + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); + return; + } + if( !OMIT_TEMPDB && isTemp ) iDb = 1; + zName = sqlite3NameFromToken(db, pName); } - if( !OMIT_TEMPDB && isTemp ) iDb = 1; - pParse->sNameToken = *pName; - zName = sqlite3NameFromToken(db, pName); if( zName==0 ) return; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION - assert( (isTemp & 1)==isTemp ); + assert( isTemp==0 || isTemp==1 ); + assert( isView==0 || isView==1 ); { - int code; + static const u8 aCode[] = { + SQLITE_CREATE_TABLE, + SQLITE_CREATE_TEMP_TABLE, + SQLITE_CREATE_VIEW, + SQLITE_CREATE_TEMP_VIEW + }; char *zDb = db->aDb[iDb].zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ goto begin_table_error; } - if( isView ){ - if( !OMIT_TEMPDB && isTemp ){ - code = SQLITE_CREATE_TEMP_VIEW; - }else{ - code = SQLITE_CREATE_VIEW; - } - }else{ - if( !OMIT_TEMPDB && isTemp ){ - code = SQLITE_CREATE_TEMP_TABLE; - }else{ - code = SQLITE_CREATE_TABLE; - } - } - if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ + if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView], + zName, 0, zDb) ){ goto begin_table_error; } } @@ -1864,9 +1849,13 @@ void sqlite3EndTable( ** So do not write to the disk again. Extract the root page number ** for the table from the db->init.newTnum field. (The page number ** should have been put there by the sqliteOpenCb routine.) + ** + ** If the root page number is 1, that means this is the sqlite_master + ** table itself. So mark it read-only. */ if( db->init.busy ){ p->tnum = db->init.newTnum; + if( p->tnum==1 ) p->tabFlags |= TF_Readonly; } /* Special processing for WITHOUT ROWID Tables */ @@ -2319,6 +2308,7 @@ void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); int r1 = sqlite3GetTempReg(pParse); + assert( iTable>1 ); sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); sqlite3MayAbort(pParse); #ifndef SQLITE_OMIT_AUTOVACUUM diff --git a/src/prepare.c b/src/prepare.c index 5d1ae00d13..acc70dd2d5 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -137,61 +137,27 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ #ifndef SQLITE_OMIT_DEPRECATED int size; #endif - Table *pTab; Db *pDb; char const *azArg[4]; int meta[5]; InitData initData; - char const *zMasterSchema; - char const *zMasterName; + const char *zMasterName; int openedTransaction = 0; - /* - ** The master database table has a structure like this - */ - static const char master_schema[] = - "CREATE TABLE sqlite_master(\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")" - ; -#ifndef SQLITE_OMIT_TEMPDB - static const char temp_master_schema[] = - "CREATE TEMP TABLE sqlite_temp_master(\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")" - ; -#else - #define temp_master_schema 0 -#endif - assert( iDb>=0 && iDbnDb ); assert( db->aDb[iDb].pSchema ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); - /* zMasterSchema and zInitScript are set to point at the master schema - ** and initialisation script appropriate for the database being - ** initialized. zMasterName is the name of the master table. - */ - if( !OMIT_TEMPDB && iDb==1 ){ - zMasterSchema = temp_master_schema; - }else{ - zMasterSchema = master_schema; - } - zMasterName = SCHEMA_TABLE(iDb); - - /* Construct the schema tables. */ - azArg[0] = zMasterName; + /* Construct the in-memory representation schema tables (sqlite_master or + ** sqlite_temp_master) by invoking the parser directly. The appropriate + ** table name will be inserted automatically by the parser so we can just + ** use the abbreviation "x" here. The parser will also automatically tag + ** the schema table as read-only. */ + azArg[0] = zMasterName = SCHEMA_TABLE(iDb); azArg[1] = "1"; - azArg[2] = zMasterSchema; + azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text," + "rootpage integer,sql text)"; azArg[3] = 0; initData.db = db; initData.iDb = iDb; @@ -202,10 +168,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ rc = initData.rc; goto error_out; } - pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); - if( ALWAYS(pTab) ){ - pTab->tabFlags |= TF_Readonly; - } /* Create a cursor to hold the database open */ @@ -324,7 +286,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ { char *zSql; zSql = sqlite3MPrintf(db, - "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", + "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid", db->aDb[iDb].zName, zMasterName); #ifndef SQLITE_OMIT_AUTHORIZATION { diff --git a/src/vdbe.c b/src/vdbe.c index d4060cae96..c6d5f7b0cc 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5099,6 +5099,7 @@ case OP_Destroy: { /* out2 */ int iDb; assert( p->readOnly==0 ); + assert( pOp->p1>1 ); pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Null; if( db->nVdbeRead > db->nVDestroy+1 ){ From 241873e55c491d7b65b3440b2f3d32d5ab9bbfae Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Jan 2016 16:11:58 +0000 Subject: [PATCH 07/29] Remove unnecessary de-initialization of the Parse object. FossilOrigin-Name: 75ab30c5fcb51e556342dc3112f9acf122f79947 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 21f3a58b93..4bde0b8c82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\stoward\smaking\sthe\sschema\sparsing\slogic\ssimplier\sand\smore\scompact. -D 2016-01-15T15:06:41.166 +C Remove\sunnecessary\sde-initialization\sof\sthe\sParse\sobject. +D 2016-01-15T16:11:58.808 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -287,7 +287,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c d9c6b2e2df06314079aa582f12937401a62171a6 F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 2778ccdb327923b2eb6cea304e232efd0c85cbe1 +F src/build.c ae94a76279b988a62f82ae25344c68026d5fd47c F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -1415,7 +1415,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 584848d4396d7755027fab377c97e40fbcc90d21 -R d396ff3cd92323018eeceb835a86df32 +P c52ca2c0662bb30ab34574f933429512655b19ff +R 18101cd5e40446f0b579af30aa8257e8 U drh -Z d625867287e0b3ea5f45a2d19f9bb7c8 +Z 9e527ccefb4d19cf49503262bc52d994 diff --git a/manifest.uuid b/manifest.uuid index 281520412b..f3f393f928 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c52ca2c0662bb30ab34574f933429512655b19ff \ No newline at end of file +75ab30c5fcb51e556342dc3112f9acf122f79947 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 7bc7fc898b..d783406761 100644 --- a/src/build.c +++ b/src/build.c @@ -228,15 +228,19 @@ void sqlite3FinishCoding(Parse *pParse){ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; - pParse->colNamesSet = 0; }else{ pParse->rc = SQLITE_ERROR; } + + /* We are done with this Parse object. There is no need to de-initialize it */ +#if 0 + pParse->colNamesSet = 0; pParse->nTab = 0; pParse->nMem = 0; pParse->nSet = 0; pParse->nVar = 0; DbMaskZero(pParse->cookieMask); +#endif } /* From 25247435be528220e2a0e40e966c9b73c8918b3a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jan 2016 19:54:47 +0000 Subject: [PATCH 08/29] Rationalize some code in fts5_storage.c. Add tests to cover recently added branches in fts5. FossilOrigin-Name: 3b72df405ac9b3a71144f45317d32e25f0084c4b --- ext/fts5/fts5Int.h | 4 +- ext/fts5/fts5_main.c | 18 ++--- ext/fts5/fts5_storage.c | 125 +++++++++++---------------------- ext/fts5/fts5_vocab.c | 12 +++- ext/fts5/test/fts5fault5.test | 31 +++++++- ext/fts5/test/fts5fault8.test | 12 +++- ext/fts5/test/fts5simple2.test | 26 ++++++- ext/fts5/test/fts5update.test | 93 ++++++++++++++++++++++++ ext/fts5/test/fts5vocab.test | 54 ++++++++++++++ main.mk | 3 +- manifest | 31 ++++---- manifest.uuid | 2 +- 12 files changed, 292 insertions(+), 119 deletions(-) create mode 100644 ext/fts5/test/fts5update.test diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 1daeefc09f..ee953c399c 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -586,7 +586,7 @@ int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); int sqlite3Fts5DropAll(Fts5Config*); int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); -int sqlite3Fts5StorageDelete(Fts5Storage *p, i64); +int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); @@ -606,8 +606,6 @@ int sqlite3Fts5StorageConfigValue( Fts5Storage *p, const char*, sqlite3_value*, int ); -int sqlite3Fts5StorageSpecialDelete(Fts5Storage *p, i64 iDel, sqlite3_value**); - int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); int sqlite3Fts5StorageRebuild(Fts5Storage *p); int sqlite3Fts5StorageOptimize(Fts5Storage *p); diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index fec589efcb..95fb10baeb 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1405,7 +1405,7 @@ static int fts5SpecialDelete( int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); - rc = sqlite3Fts5StorageSpecialDelete(pTab->pStorage, iDel, &apVal[2]); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); } return rc; } @@ -1512,7 +1512,7 @@ static int fts5UpdateMethod( /* Case 1: DELETE */ else if( nArg==1 ){ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); } /* Case 2: INSERT */ @@ -1522,7 +1522,7 @@ static int fts5UpdateMethod( && sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); } @@ -1533,22 +1533,22 @@ static int fts5UpdateMethod( i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ if( iOld!=iNew ){ if( eConflict==SQLITE_REPLACE ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); }else{ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid); } } }else{ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); fts5StorageInsert(&rc, pTab, apVal, pRowid); } } @@ -1747,7 +1747,9 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ const u8 *a; int n; rc = fts5CsrPoslist(pCsr, i, &a, &n); - sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); + if( rc==SQLITE_OK ){ + sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); + } } if( rc==SQLITE_OK ){ diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 4a1ce3a3d9..56383619d1 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -378,39 +378,52 @@ static int fts5StorageInsertCallback( ** delete-markers to the FTS index necessary to delete it. Do not actually ** remove the %_content row at this time though. */ -static int fts5StorageDeleteFromIndex(Fts5Storage *p, i64 iDel){ +static int fts5StorageDeleteFromIndex( + Fts5Storage *p, + i64 iDel, + sqlite3_value **apVal +){ Fts5Config *pConfig = p->pConfig; - sqlite3_stmt *pSeek; /* SELECT to read row iDel from %_data */ + sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ int rc; /* Return code */ + int rc2; /* sqlite3_reset() return code */ + int iCol; + Fts5InsertCtx ctx; - rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); - if( rc==SQLITE_OK ){ - int rc2; + if( apVal==0 ){ + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); + if( rc!=SQLITE_OK ) return rc; sqlite3_bind_int64(pSeek, 1, iDel); - if( sqlite3_step(pSeek)==SQLITE_ROW ){ - int iCol; - Fts5InsertCtx ctx; - ctx.pStorage = p; - ctx.iCol = -1; - rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); - for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ - if( pConfig->abUnindexed[iCol-1] ) continue; - ctx.szCol = 0; - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_column_text(pSeek, iCol), - sqlite3_column_bytes(pSeek, iCol), - (void*)&ctx, - fts5StorageInsertCallback - ); - p->aTotalSize[iCol-1] -= (i64)ctx.szCol; - } - p->nTotalRow--; + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + return sqlite3_reset(pSeek); } - rc2 = sqlite3_reset(pSeek); - if( rc==SQLITE_OK ) rc = rc2; } + ctx.pStorage = p; + ctx.iCol = -1; + rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); + for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ + if( pConfig->abUnindexed[iCol-1]==0 ){ + const char *zText; + int nText; + if( pSeek ){ + zText = (const char*)sqlite3_column_text(pSeek, iCol); + nText = sqlite3_column_bytes(pSeek, iCol); + }else{ + zText = (const char*)sqlite3_value_text(apVal[iCol-1]); + nText = sqlite3_value_bytes(apVal[iCol-1]); + } + ctx.szCol = 0; + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, + zText, nText, (void*)&ctx, fts5StorageInsertCallback + ); + p->aTotalSize[iCol-1] -= (i64)ctx.szCol; + } + } + p->nTotalRow--; + + rc2 = sqlite3_reset(pSeek); + if( rc==SQLITE_OK ) rc = rc2; return rc; } @@ -490,16 +503,17 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ /* ** Remove a row from the FTS table. */ -int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){ +int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ Fts5Config *pConfig = p->pConfig; int rc; sqlite3_stmt *pDel = 0; + assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 ); rc = fts5StorageLoadTotals(p, 1); /* Delete the index records */ if( rc==SQLITE_OK ){ - rc = fts5StorageDeleteFromIndex(p, iDel); + rc = fts5StorageDeleteFromIndex(p, iDel, apVal); } /* Delete the %_docsize record */ @@ -532,61 +546,6 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){ return rc; } -int sqlite3Fts5StorageSpecialDelete( - Fts5Storage *p, - i64 iDel, - sqlite3_value **apVal -){ - Fts5Config *pConfig = p->pConfig; - int rc; - sqlite3_stmt *pDel = 0; - - assert( pConfig->eContent!=FTS5_CONTENT_NORMAL ); - rc = fts5StorageLoadTotals(p, 1); - - /* Delete the index records */ - if( rc==SQLITE_OK ){ - int iCol; - Fts5InsertCtx ctx; - ctx.pStorage = p; - ctx.iCol = -1; - - rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); - for(iCol=0; rc==SQLITE_OK && iColnCol; iCol++){ - if( pConfig->abUnindexed[iCol] ) continue; - ctx.szCol = 0; - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_value_text(apVal[iCol]), - sqlite3_value_bytes(apVal[iCol]), - (void*)&ctx, - fts5StorageInsertCallback - ); - p->aTotalSize[iCol] -= (i64)ctx.szCol; - } - p->nTotalRow--; - } - - /* Delete the %_docsize record */ - if( pConfig->bColumnsize ){ - if( rc==SQLITE_OK ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0); - } - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pDel, 1, iDel); - sqlite3_step(pDel); - rc = sqlite3_reset(pDel); - } - } - - /* Write the averages record */ - if( rc==SQLITE_OK ){ - rc = fts5StorageSaveTotals(p); - } - - return rc; -} - /* ** Delete all entries in the FTS5 index. */ diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 2ed10b7cdb..ddc5576c5d 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -427,6 +427,10 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ int ii = FTS5_POS2COLUMN(iPos); pCsr->aCnt[ii]++; if( iCol!=ii ){ + if( ii>=nCol ){ + rc = FTS5_CORRUPT; + break; + } pCsr->aDoc[ii]++; iCol = ii; } @@ -444,7 +448,11 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ if( rc==SQLITE_OK ){ while( 0==sqlite3Fts5PoslistNext64(buf.p, buf.n, &iOff,&iPos) ){ assert_nc( iPos>=0 && iPosaDoc[iPos]++; + if( iPos>=nCol ){ + rc = FTS5_CORRUPT; + break; + } + pCsr->aDoc[iPos]++; } } sqlite3Fts5BufferFree(&buf); @@ -472,7 +480,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ } } - if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){ + if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){ while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++; assert( pCsr->iColpConfig->nCol ); } diff --git a/ext/fts5/test/fts5fault5.test b/ext/fts5/test/fts5fault5.test index 41de5208b2..75b7d9af50 100644 --- a/ext/fts5/test/fts5fault5.test +++ b/ext/fts5/test/fts5fault5.test @@ -65,19 +65,26 @@ do_faultsim_test 2.2 -faults oom-t* -body { } #------------------------------------------------------------------------- -# OOM while scanning an fts5vocab table. +# OOM while scanning fts5vocab tables. # reset_db do_test 3.0 { execsql { CREATE VIRTUAL TABLE tt USING fts5(x); CREATE VIRTUAL TABLE tv USING fts5vocab(tt, 'row'); + + CREATE VIRTUAL TABLE tt2 USING fts5(x, detail=col); + CREATE VIRTUAL TABLE tv2 USING fts5vocab(tt2, 'col'); + INSERT INTO tt(tt, rank) VALUES('pgsz', 32); + INSERT INTO tt2(tt2, rank) VALUES('pgsz', 32); BEGIN; } + for {set i 0} {$i < 20} {incr i} { set str [string repeat "$i " 50] execsql { INSERT INTO tt VALUES($str) } + execsql { INSERT INTO tt2 VALUES($str) } } execsql COMMIT } {} @@ -98,6 +105,28 @@ do_faultsim_test 3.2 -faults oom-t* -body { faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}} } +breakpoint +do_execsql_test 3.3.0 { + SELECT * FROM tv2; +} { + 0 x 1 {} 1 x 1 {} 10 x 1 {} 11 x 1 {} 12 x 1 {} 13 x 1 {} + 14 x 1 {} 15 x 1 {} 16 x 1 {} 17 x 1 {} 18 x 1 {} 19 x 1 {} + 2 x 1 {} 3 x 1 {} 4 x 1 {} 5 x 1 {} 6 x 1 {} 7 x 1 {} 8 x 1 {} + 9 x 1 {} +} +do_faultsim_test 3.3 -faults oom-t* -body { + db eval { + SELECT * FROM tv2; + } +} -test { + faultsim_test_result [list 0 [list \ + 0 x 1 {} 1 x 1 {} 10 x 1 {} 11 x 1 {} 12 x 1 {} 13 x 1 {} \ + 14 x 1 {} 15 x 1 {} 16 x 1 {} 17 x 1 {} 18 x 1 {} 19 x 1 {} \ + 2 x 1 {} 3 x 1 {} 4 x 1 {} 5 x 1 {} 6 x 1 {} 7 x 1 {} 8 x 1 {} \ + 9 x 1 {} + ]] +} + finish_test diff --git a/ext/fts5/test/fts5fault8.test b/ext/fts5/test/fts5fault8.test index 01a1876955..d93066c6c0 100644 --- a/ext/fts5/test/fts5fault8.test +++ b/ext/fts5/test/fts5fault8.test @@ -24,8 +24,6 @@ ifcapable !fts5 { foreach_detail_mode $testprefix { -if {[detail_is_none]==0} continue - fts5_aux_test_functions db do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); @@ -34,7 +32,7 @@ do_execsql_test 1.0 { INSERT INTO t1 VALUES(NULL, '1 2 1 2'); } -do_faultsim_test 1 -faults oom-t* -body { +do_faultsim_test 1 -faults oom-* -body { execsql { SELECT rowid, fts5_test_poslist(t1) FROM t1 WHERE t1 MATCH 'b OR 2' } @@ -43,6 +41,14 @@ do_faultsim_test 1 -faults oom-t* -body { {1 SQLITE_NOMEM} } +do_faultsim_test 2 -faults oom-* -body { + execsql { + INSERT INTO t1(t1) VALUES('integrity-check'); + } +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} + } finish_test diff --git a/ext/fts5/test/fts5simple2.test b/ext/fts5/test/fts5simple2.test index c61970e154..33b2a73ab9 100644 --- a/ext/fts5/test/fts5simple2.test +++ b/ext/fts5/test/fts5simple2.test @@ -267,8 +267,6 @@ do_execsql_test 14.1 { SELECT fts5_test_poslist(t1) FROM t1('b') ORDER BY rank; } {0.0.1} -} - #------------------------------------------------------------------------- # reset_db @@ -299,6 +297,30 @@ do_execsql_test 15.3.2 { do_test 15.4 { execsql { INSERT INTO t1(t1) VALUES('integrity-check') } } {} + +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 16.0 { + CREATE VIRTUAL TABLE t2 USING fts5(x, detail=none); + BEGIN; + INSERT INTO t2(rowid, x) VALUES(1, 'a b c'); + INSERT INTO t2(rowid, x) VALUES(456, 'a b c'); + INSERT INTO t2(rowid, x) VALUES(1000, 'a b c'); + COMMIT; + UPDATE t2 SET x=x; +} + +do_execsql_test 16.1 { + INSERT INTO t2(t2) VALUES('integrity-check'); +} {} + +do_execsql_test 16.2 { + SELECT rowid FROM t2('b') ORDER BY rowid DESC +} {1000 456 1} + finish_test diff --git a/ext/fts5/test/fts5update.test b/ext/fts5/test/fts5update.test new file mode 100644 index 0000000000..9e7debe9da --- /dev/null +++ b/ext/fts5/test/fts5update.test @@ -0,0 +1,93 @@ +# 2016 Jan 16 +# +# 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 implements regression tests for SQLite library. The +# focus of this script is testing the FTS5 module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5update + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +set docs { + "eight zero iv eight 7" "ix one 8 one three ii one" + "1 9 9 three viii" "5 zero ii 6 nine ix 3" + "3 zero 5 2 seven nine" "two eight viii eight 1" + "4 six two 5 9 vii" "viii ii four 8 i i iv" + "vii 0 iv seven 7 viii" "five 1 nine vi seven" + "1 zero zero iii 1" "one one six 6 nine seven" + "one v 4 zero 4 iii ii" "2 3 eight six ix" + "six iv 7 three 5" "ix zero 0 8 ii 7 3" + "four six nine 2 vii 3" "five viii 5 8 0 7" +} + +foreach_detail_mode $::testprefix { + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); +} {} + +do_test 1.1 { + foreach {a b} $docs { + execsql {INSERT INTO t1 VALUES($a, $b)} + } +} {} + +proc update {iRowid iA iB} { + set a [lindex $::docs $iA] + set b [lindex $::docs $iB] + execsql { UPDATE t1 SET a=$a, b=$b WHERE rowid=$iRowid } +} + +set nDoc [llength $::docs] +foreach n {1 5 10 50 100} { + do_test 1.2.$n { + execsql BEGIN + for {set i 1} {$i <= 1000} {incr i} { + set iRowid [expr {int(rand() * ($nDoc/2)) + 1}] + set iA [expr {int(rand() * $nDoc)}] + set iB [expr {int(rand() * $nDoc)}] + update $iRowid $iA $iB + + if {($i % $n)==0} { + execsql { COMMIT; BEGIN } + } + + if {($i % $n)==100} { + execsql { INSERT INTO t1(t1) VALUES('integrity-check') } + } + } + execsql COMMIT + execsql { INSERT INTO t1(t1) VALUES('integrity-check') } + } {} +} + +do_execsql_test 1.3 { + UPDATE t1 SET a=a AND b=b; + INSERT INTO t1(t1) VALUES('integrity-check'); +} + +do_test 1.4 { + execsql { INSERT INTO t1(t1, rank) VALUES('pgsz', 32) } + for {set i 0} {$i < 50} {incr i} { + execsql { UPDATE t1 SET a=a AND b=b } + execsql { INSERT INTO t1(t1) VALUES('integrity-check') } + } +} {} + +} +finish_test + + diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index 823b2b2872..f7278dd5c1 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -57,6 +57,8 @@ proc row_to_col {L} { set ret } +if 1 { + do_execsql_test 1.1.1 { CREATE VIRTUAL TABLE t1 USING fts5(one, prefix=1, detail=%DETAIL%); CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, 'row'); @@ -391,5 +393,57 @@ if {![detail_is_none]} { } +#------------------------------------------------------------------------- +# Test the fts5vocab tables response to a specific types of corruption: +# where the fts5 index contains hits for columns that do not exist. +# +do_execsql_test 8.0 { + CREATE VIRTUAL TABLE x1 USING fts5(a, b, c, detail=%DETAIL%); + INSERT INTO x1 VALUES('a b c', 'd e f', 'g h i'); + INSERT INTO x1 VALUES('g h i', 'a b c', 'd e f'); + INSERT INTO x1 VALUES('d e f', 'g h i', 'a b c'); + CREATE VIRTUAL TABLE x1_r USING fts5vocab(x1, row); + CREATE VIRTUAL TABLE x1_c USING fts5vocab(x1, col); +} + +set resr [star_from_row {a 3 3 b 3 3 c 3 3 d 3 3 e 3 3 f 3 3 g 3 3 h 3 3 i 3 3}] +set resc [star_from_col { + a a 1 1 a b 1 1 a c 1 1 b a 1 1 + b b 1 1 b c 1 1 c a 1 1 c b 1 1 + c c 1 1 d a 1 1 d b 1 1 d c 1 1 + e a 1 1 e b 1 1 e c 1 1 f a 1 1 + f b 1 1 f c 1 1 g a 1 1 g b 1 1 + g c 1 1 h a 1 1 h b 1 1 h c 1 1 + i a 1 1 i b 1 1 i c 1 1 +}] +if {[detail_is_none]} { set resc [row_to_col $resr] } + +do_execsql_test 8.1.1 { SELECT * FROM x1_r; } $resr +do_execsql_test 8.1.2 { SELECT * FROM x1_c } $resc + +do_execsql_test 8.2 { + PRAGMA writable_schema = 1; + UPDATE sqlite_master + SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(a, detail=%DETAIL%)' + WHERE name = 'x1'; +} +db close +sqlite3 db test.db +sqlite3_fts5_may_be_corrupt 1 + +do_execsql_test 8.2.1 { SELECT * FROM x1_r } $resr + +if {[detail_is_none]} { + do_execsql_test 8.2.2 { SELECT * FROM x1_c } $resc +} else { + do_catchsql_test 8.2.2 { + SELECT * FROM x1_c + } {1 {database disk image is malformed}} +} + +sqlite3_fts5_may_be_corrupt 0 + +} + finish_test diff --git a/main.mk b/main.mk index 7aaa58fffd..abf4fd2be7 100644 --- a/main.mk +++ b/main.mk @@ -334,7 +334,8 @@ TESTSRC += \ $(TOP)/ext/misc/vfslog.c \ $(TOP)/ext/fts5/fts5_tcl.c \ $(TOP)/ext/fts5/fts5_test_mi.c \ - $(TOP)/ext/fts5/fts5_test_tok.c + $(TOP)/ext/fts5/fts5_test_tok.c \ + $(FTS5_SRC) #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c diff --git a/manifest b/manifest index 4bde0b8c82..10927de756 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sde-initialization\sof\sthe\sParse\sobject. -D 2016-01-15T16:11:58.808 +C Rationalize\ssome\scode\sin\sfts5_storage.c.\sAdd\stests\sto\scover\srecently\sadded\sbranches\sin\sfts5. +D 2016-01-15T19:54:47.454 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -97,22 +97,22 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 6c5a332e6add01dd69166a252d1818fb75c42a08 +F ext/fts5/fts5Int.h 313e3276ac9e0245ee722ef803253857a68722b9 F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e F ext/fts5/fts5_buffer.c 87204c8b3b8bc62b27376eab09b74d6d5acc41f1 F ext/fts5/fts5_config.c 9c243d04ac0ca997d2d2e2252891f2a10fbd7217 F ext/fts5/fts5_expr.c 510db45967ca359f64f2ba2c707ab57d740cad56 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 F ext/fts5/fts5_index.c cd036089b22b0340fccef88a3ad62ac1016c7cbb -F ext/fts5/fts5_main.c 488ceecdb4400ecc6a3d3b2247cedef153955388 -F ext/fts5/fts5_storage.c f7b2d330dd7b29a9f4da09f6d85879ca8c41b2e8 +F ext/fts5/fts5_main.c 1d116f5c44c6f06ec282d33dd6d041c8131b3d6a +F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e F ext/fts5/fts5_tcl.c bcacc05dec0446e7b1a44d5d906057e677bd7ea4 F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c da64ecbd217625980a1721fbd588a1e4118a51b6 +F ext/fts5/fts5_vocab.c ee6df1a3be103414d7b7af833ae1885c7b83a9d0 F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 393882afb225a21edf033043bbf936951e9198c1 @@ -149,10 +149,10 @@ F ext/fts5/test/fts5fault1.test 4b39c47ca3544615daa8a2f733b911fa08022c77 F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 F ext/fts5/test/fts5fault4.test 4864f2b5c2c083440dbe85aff60897bc1aa04603 -F ext/fts5/test/fts5fault5.test f2b8645053d48982e8979749e93994c43011c118 +F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b -F ext/fts5/test/fts5fault8.test aeb4717b7b293678bc4d2f3c0159206a525375d9 +F ext/fts5/test/fts5fault8.test f2d8a2b673a5f72ca1fa0e85bdbfb2041ffd347d F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5hash.test 7cf4607b8657c383f0b520668a99971e95d8b139 F ext/fts5/test/fts5integrity.test 87db5d4e7da0ce04a1dcba5ba91658673c997a65 @@ -172,7 +172,7 @@ F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 400384798349d658eaf06aefa1e364957d5d4821 F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 -F ext/fts5/test/fts5simple2.test 843f1f7fe439ff32bf74f4fd6430632f9636ef3a +F ext/fts5/test/fts5simple2.test 7b51f8d411e9a77fa4519fb09ba5a3afda75c94d F ext/fts5/test/fts5synonym.test cf88c0a56d5ea9591e3939ef1f6e294f7f2d0671 F ext/fts5/test/fts5synonym2.test d2d9099d9d105b55ea03fd52d61ae2847d534129 F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 @@ -182,8 +182,9 @@ F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 +F ext/fts5/test/fts5update.test 6f0abb89556f0a638b982e010f4d8d1de373a61c F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e -F ext/fts5/test/fts5vocab.test e4b12f238f113795615ba6343b63fb326d6a360e +F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 F ext/fts5/tool/fts5speed.tcl aaee41894b552df8fbf8616aad003b2ea9ba3221 F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84 F ext/fts5/tool/loadfts5.tcl 4cc2d6af43b58d4fac05bc4fdabd0e5862c3b2c1 @@ -265,7 +266,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 55f0940264e55540773214ee1f2dbba0bf359957 +F main.mk 7575015811ef75a2cfcbc6f09de161cc8236e8a5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1415,7 +1416,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c52ca2c0662bb30ab34574f933429512655b19ff -R 18101cd5e40446f0b579af30aa8257e8 -U drh -Z 9e527ccefb4d19cf49503262bc52d994 +P 75ab30c5fcb51e556342dc3112f9acf122f79947 +R 374e508382342a2641c42b70ee61e09e +U dan +Z e6d3f908cc39d2673b189171ce4240a7 diff --git a/manifest.uuid b/manifest.uuid index f3f393f928..7756c1a36c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75ab30c5fcb51e556342dc3112f9acf122f79947 \ No newline at end of file +3b72df405ac9b3a71144f45317d32e25f0084c4b \ No newline at end of file From 079d446dd2c9f9f83c4a77d23c539e1ae5d5d11a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Jan 2016 21:55:46 +0000 Subject: [PATCH 09/29] Remove an unnecessary memset(). FossilOrigin-Name: 689421a9f73ceeab9786840a2d6ee008124d1f25 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 10927de756..01160c68f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rationalize\ssome\scode\sin\sfts5_storage.c.\sAdd\stests\sto\scover\srecently\sadded\sbranches\sin\sfts5. -D 2016-01-15T19:54:47.454 +C Remove\san\sunnecessary\smemset(). +D 2016-01-15T21:55:46.864 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -288,7 +288,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c d9c6b2e2df06314079aa582f12937401a62171a6 F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c ae94a76279b988a62f82ae25344c68026d5fd47c +F src/build.c a23d2012f06c7a7dbb33e15608df9fdef68326af F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -1416,7 +1416,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 75ab30c5fcb51e556342dc3112f9acf122f79947 -R 374e508382342a2641c42b70ee61e09e -U dan -Z e6d3f908cc39d2673b189171ce4240a7 +P 3b72df405ac9b3a71144f45317d32e25f0084c4b +R 1b6fc5c53ba731472d7f7fb860ed6428 +U drh +Z edef52557fd12bf4085bbb78a4ba3a5f diff --git a/manifest.uuid b/manifest.uuid index 7756c1a36c..6fd8be9245 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b72df405ac9b3a71144f45317d32e25f0084c4b \ No newline at end of file +689421a9f73ceeab9786840a2d6ee008124d1f25 \ No newline at end of file diff --git a/src/build.c b/src/build.c index d783406761..24f908b078 100644 --- a/src/build.c +++ b/src/build.c @@ -499,7 +499,6 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){ } j++; } - memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j])); db->nDb = j; if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); From 095fb474efec4919c103527e5b0fbe02458f5d2d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Jan 2016 03:16:19 +0000 Subject: [PATCH 10/29] Fix a potential use-after-free problem when compiling with SQLITE_HAS_CODEC. FossilOrigin-Name: 653ea15ad8e23b333e234eb5dde7b80134db2baf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 01160c68f8..aecb1e9771 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smemset(). -D 2016-01-15T21:55:46.864 +C Fix\sa\spotential\suse-after-free\sproblem\swhen\scompiling\swith\sSQLITE_HAS_CODEC. +D 2016-01-16T03:16:19.772 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -307,7 +307,7 @@ F src/insert.c 6b45cc86967da11aa024d034745f93f66d53f650 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b -F src/main.c 6bcb3de6b4f02552d3df44f2ef73ff6b7ccf5322 +F src/main.c b686dabe9a7ece9121da87120d5c7bf402d77eb3 F src/malloc.c 8f787669e79de26efc42272b5797bc00fff527c6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1416,7 +1416,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3b72df405ac9b3a71144f45317d32e25f0084c4b -R 1b6fc5c53ba731472d7f7fb860ed6428 +P 689421a9f73ceeab9786840a2d6ee008124d1f25 +R f13b5cb1e79c02d53b1455abc8833659 U drh -Z edef52557fd12bf4085bbb78a4ba3a5f +Z 5aa5fcf53f35b8097ee55e85c4bed5b9 diff --git a/manifest.uuid b/manifest.uuid index 6fd8be9245..a0ae1f7590 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -689421a9f73ceeab9786840a2d6ee008124d1f25 \ No newline at end of file +653ea15ad8e23b333e234eb5dde7b80134db2baf \ No newline at end of file diff --git a/src/main.c b/src/main.c index 35c0607b47..63a105c3f0 100644 --- a/src/main.c +++ b/src/main.c @@ -2969,7 +2969,6 @@ static int openDatabase( sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: - sqlite3_free(zOpen); if( db ){ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); @@ -3006,6 +3005,7 @@ opendb_out: } } #endif + sqlite3_free(zOpen); return rc & 0xff; } From 9b34abee30744c01fcef6570c78859b54c1df256 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Jan 2016 15:12:35 +0000 Subject: [PATCH 11/29] Use sqlite3VdbeAddOp4() rather than a separate sqlite3VdbeChangeP4() call, for a slightly smaller and faster binary. FossilOrigin-Name: a4258cd4613c55acacb5c7b61faa3de7eb0759d2 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/analyze.c | 12 ++++++------ src/attach.c | 6 +++--- src/build.c | 2 +- src/insert.c | 6 +++--- src/trigger.c | 4 ++-- src/vdbeaux.c | 2 +- src/wherecode.c | 3 +-- 9 files changed, 30 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index aecb1e9771..fa6bddb8b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\suse-after-free\sproblem\swhen\scompiling\swith\sSQLITE_HAS_CODEC. -D 2016-01-16T03:16:19.772 +C Use\ssqlite3VdbeAddOp4()\srather\sthan\sa\sseparate\ssqlite3VdbeChangeP4()\scall,\sfor\na\sslightly\ssmaller\sand\sfaster\sbinary. +D 2016-01-16T15:12:35.739 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -279,8 +279,8 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267 -F src/analyze.c 905d387f6f7e89866e1dc73e13b6e09172bee350 -F src/attach.c ec9f119ca7542b5364924aab84f214440f8ac9e5 +F src/analyze.c 0043d3e501f04297fed2bb50b488bc08d5c39f36 +F src/attach.c 07b3a34a1702dce92a7f1d3888c0c06222b63760 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf @@ -288,7 +288,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c d9c6b2e2df06314079aa582f12937401a62171a6 F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c a23d2012f06c7a7dbb33e15608df9fdef68326af +F src/build.c 59783188d873daf92150cc1a1caad55496839e8f F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -303,7 +303,7 @@ F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 6b45cc86967da11aa024d034745f93f66d53f650 +F src/insert.c a00e6d8a843dc22e2c136df04e6300c4528d9b9f F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b @@ -402,7 +402,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66 -F src/trigger.c de3ed31ad3218a20d7d7e18bf1b3b734e78bda66 +F src/trigger.c 056e51182a3677434423e3be0c74e61b90b4a663 F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 @@ -411,7 +411,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c f2e6b4fae037db04323be8de7bcd266375746471 +F src/vdbeaux.c 906c0350f316dd13a26d8a91865f1dd7f14dc19b F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -423,7 +423,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c bb69654f841ae7af0a20cc6fb8f0ac57901c31be F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c dfbfe198e418b01f208b489e088edd230c91a4e7 +F src/wherecode.c 8dee26eb181ea9daa8b1a4d96f34c0860aaf99bd F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1416,7 +1416,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 689421a9f73ceeab9786840a2d6ee008124d1f25 -R f13b5cb1e79c02d53b1455abc8833659 +P 653ea15ad8e23b333e234eb5dde7b80134db2baf +R 2155f55389b348e9a35fea6f93c01bbe U drh -Z 5aa5fcf53f35b8097ee55e85c4bed5b9 +Z 32d5bf122f6c10496965338bc29a15a2 diff --git a/manifest.uuid b/manifest.uuid index a0ae1f7590..39ad2ac515 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -653ea15ad8e23b333e234eb5dde7b80134db2baf \ No newline at end of file +a4258cd4613c55acacb5c7b61faa3de7eb0759d2 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 367dd698dd..4d777fa9f5 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -940,8 +940,8 @@ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ #else UNUSED_PARAMETER( iParam ); #endif - sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4, regOut); - sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); + sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut, + (char*)&statGetFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 1 + IsStat34); } @@ -1095,8 +1095,8 @@ static void analyzeOneTable( #endif sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); - sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4+1, regStat4); - sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); + sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4, + (char*)&statInitFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2+IsStat34); /* Implementation of the following: @@ -1192,8 +1192,8 @@ static void analyzeOneTable( } #endif assert( regChng==(regStat4+1) ); - sqlite3VdbeAddOp3(v, OP_Function0, 1, regStat4, regTemp); - sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); + sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp, + (char*)&statPushFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2+IsStat34); sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); diff --git a/src/attach.c b/src/attach.c index 2c47ed47ba..fd5cc7c76c 100644 --- a/src/attach.c +++ b/src/attach.c @@ -359,11 +359,11 @@ static void codeAttach( assert( v || db->mallocFailed ); if( v ){ - sqlite3VdbeAddOp3(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3); + sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3, + (char *)pFunc, P4_FUNCDEF); assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); - sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); - + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). diff --git a/src/build.c b/src/build.c index 24f908b078..f592bb131c 100644 --- a/src/build.c +++ b/src/build.c @@ -4115,7 +4115,7 @@ void sqlite3HaltConstraint( sqlite3MayAbort(pParse); } sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); - if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg); + sqlite3VdbeChangeP5(v, p5Errmsg); } /* diff --git a/src/insert.c b/src/insert.c index 3e4aac8f4d..8082bcb459 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1595,7 +1595,7 @@ void sqlite3CompleteInsertion( assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; } - if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); + sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; regData = regNewData + 1; @@ -2011,9 +2011,9 @@ static int xferOptimization( assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); - sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, + pDest->zName, 0); sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); - sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); diff --git a/src/trigger.c b/src/trigger.c index be490e923a..48d6772992 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -952,8 +952,8 @@ void sqlite3CodeRowTriggerDirect( if( pPrg ){ int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); - sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem); - sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM); + sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, + (const char *)pPrg->pProgram, P4_SUBPROGRAM); VdbeComment( (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2f65d85777..758c85fd1c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -716,7 +716,7 @@ void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){ sqlite3VdbeGetOp(p,addr)->p3 = val; } void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){ - sqlite3VdbeGetOp(p,-1)->p5 = p5; + if( !p->db->mallocFailed ) p->aOp[p->nOp-1].p5 = p5; } /* diff --git a/src/wherecode.c b/src/wherecode.c index bc72e0ac7d..9d53a20a67 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -327,8 +327,7 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ /* Code the OP_Affinity opcode if there is anything left to do. */ if( n>0 ){ - sqlite3VdbeAddOp2(v, OP_Affinity, base, n); - sqlite3VdbeChangeP4(v, -1, zAff, n); + sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); sqlite3ExprCacheAffinityChange(pParse, base, n); } } From 8631402e6a53599344406d814962a1fab72fe474 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Jan 2016 18:58:51 +0000 Subject: [PATCH 12/29] Add further tests for fts5. Fix some problems with detail=col mode and auxiliary functions. FossilOrigin-Name: de77d6026e8035c505a704e7b8cfe5af6579d35f --- ext/fts5/fts5_buffer.c | 13 +-- ext/fts5/fts5_config.c | 2 +- ext/fts5/fts5_expr.c | 73 ++++++++--------- ext/fts5/fts5_main.c | 44 +++++----- ext/fts5/fts5_tcl.c | 20 +++-- ext/fts5/test/fts5_common.tcl | 67 +++++++++++++++ ext/fts5/test/fts5config.test | 29 +++++++ ext/fts5/test/fts5fault4.test | 21 ----- ext/fts5/test/fts5fault9.test | 140 ++++++++++++++++++++++++++++++++ ext/fts5/test/fts5hash.test | 10 ++- ext/fts5/test/fts5synonym.test | 94 +++++++-------------- ext/fts5/test/fts5synonym2.test | 67 +++++---------- manifest | 35 ++++---- manifest.uuid | 2 +- 14 files changed, 392 insertions(+), 225 deletions(-) create mode 100644 ext/fts5/test/fts5fault9.test diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 251a543c5a..8558687d8a 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -322,14 +322,17 @@ int sqlite3Fts5TermsetAdd( *pbPresent = 0; if( p ){ int i; - int hash; + int hash = 13; Fts5TermsetEntry *pEntry; - /* Calculate a hash value for this term */ - hash = 104 + iIdx; - for(i=0; i=0; i--){ + hash = (hash << 3) ^ hash ^ pTerm[i]; } + hash = (hash << 3) ^ hash ^ iIdx; hash = hash % ArraySize(p->apHash); for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){ diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index d9778bca20..70b1229edb 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -278,7 +278,7 @@ static int fts5ConfigParseSpecial( p++; } - if( rc==SQLITE_OK && (nPre<=0 || nPre>=1000) ){ + if( nPre<=0 || nPre>=1000 ){ *pzErr = sqlite3_mprintf("prefix length out of range (max 999)"); rc = SQLITE_ERROR; break; diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 409fbd1d05..7a433b69a0 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2396,7 +2396,7 @@ int sqlite3Fts5ExprPopulatePoslists( } return sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_AUX, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb + FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb ); } @@ -2412,49 +2412,44 @@ static void fts5ExprClearPoslists(Fts5ExprNode *pNode){ } static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ - if( pNode ){ - pNode->iRowid = iRowid; - pNode->bEof = 0; - switch( pNode->eType ){ - case FTS5_TERM: - case FTS5_STRING: - return (pNode->pNear->apPhrase[0]->poslist.n>0); + pNode->iRowid = iRowid; + pNode->bEof = 0; + switch( pNode->eType ){ + case FTS5_TERM: + case FTS5_STRING: + return (pNode->pNear->apPhrase[0]->poslist.n>0); - case FTS5_AND: { - int i; - for(i=0; inChild; i++){ - if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){ - fts5ExprClearPoslists(pNode); - return 0; - } - } - break; - } - - case FTS5_OR: { - int i; - int bRet = 0; - for(i=0; inChild; i++){ - if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){ - bRet = 1; - } - } - if( bRet==0 ){ - fts5ExprClearPoslists(pNode); - } - return bRet; - } - - default: { - assert( pNode->eType==FTS5_NOT ); - if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid) - || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid) - ){ + case FTS5_AND: { + int i; + for(i=0; inChild; i++){ + if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){ fts5ExprClearPoslists(pNode); return 0; } - break; } + break; + } + + case FTS5_OR: { + int i; + int bRet = 0; + for(i=0; inChild; i++){ + if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){ + bRet = 1; + } + } + return bRet; + } + + default: { + assert( pNode->eType==FTS5_NOT ); + if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid) + || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid) + ){ + fts5ExprClearPoslists(pNode); + return 0; + } + break; } } return 1; diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 95fb10baeb..7447f9b5e1 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -844,33 +844,32 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ } -static sqlite3_stmt *fts5PrepareStatement( - int *pRc, +static int fts5PrepareStatement( + sqlite3_stmt **ppStmt, Fts5Config *pConfig, const char *zFmt, ... ){ sqlite3_stmt *pRet = 0; + int rc; + char *zSql; va_list ap; - va_start(ap, zFmt); - if( *pRc==SQLITE_OK ){ - int rc; - char *zSql = sqlite3_vmprintf(zFmt, ap); - if( zSql==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pRet, 0); - if( rc!=SQLITE_OK ){ - *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); - } - sqlite3_free(zSql); + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pRet, 0); + if( rc!=SQLITE_OK ){ + *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); } - *pRc = rc; + sqlite3_free(zSql); } va_end(ap); - return pRet; + *ppStmt = pRet; + return rc; } static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ @@ -878,7 +877,7 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ Fts5Sorter *pSorter; int nPhrase; int nByte; - int rc = SQLITE_OK; + int rc; const char *zRank = pCsr->zRank; const char *zRankArgs = pCsr->zRankArgs; @@ -896,7 +895,7 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ ** table, saving it creates a circular reference. ** ** If SQLite a built-in statement cache, this wouldn't be a problem. */ - pSorter->pStmt = fts5PrepareStatement(&rc, pConfig, + rc = fts5PrepareStatement(&pSorter->pStmt, pConfig, "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s", pConfig->zDb, pConfig->zName, zRank, pConfig->zName, (zRankArgs ? ", " : ""), @@ -2039,8 +2038,15 @@ static int fts5ApiPhraseFirstColumn( Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + Fts5Sorter *pSorter = pCsr->pSorter; int n; - rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); + if( pSorter ){ + int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); + n = pSorter->aIdx[iPhrase] - i1; + pIter->a = &pSorter->aPoslist[i1]; + }else{ + rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); + } if( rc==SQLITE_OK ){ pIter->b = &pIter->a[n]; *piCol = 0; diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index e633f0ac58..72db65777f 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -447,10 +447,12 @@ static int xF5tApi( zColvar = Tcl_GetString(objv[3]); zOffvar = Tcl_GetString(objv[4]); - for(p->pApi->xPhraseFirst(p->pFts, iPhrase, &iter, &iCol, &iOff); - iCol>=0; - p->pApi->xPhraseNext(p->pFts, &iter, &iCol, &iOff) - ){ + rc = p->pApi->xPhraseFirst(p->pFts, iPhrase, &iter, &iCol, &iOff); + if( rc!=SQLITE_OK ){ + Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); + return TCL_ERROR; + } + for( ;iCol>=0; p->pApi->xPhraseNext(p->pFts, &iter, &iCol, &iOff) ){ Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0); Tcl_SetVar2Ex(interp, zOffvar, 0, Tcl_NewIntObj(iOff), 0); rc = Tcl_EvalObjEx(interp, pScript, 0); @@ -474,10 +476,12 @@ static int xF5tApi( if( Tcl_GetIntFromObj(interp, objv[2], &iPhrase) ) return TCL_ERROR; zColvar = Tcl_GetString(objv[3]); - for(p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol); - iCol>=0; - p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol) - ){ + rc = p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol); + if( rc!=SQLITE_OK ){ + Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); + return TCL_ERROR; + } + for( ; iCol>=0; p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol)){ Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0); rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc==TCL_CONTINUE ) rc = TCL_OK; diff --git a/ext/fts5/test/fts5_common.tcl b/ext/fts5/test/fts5_common.tcl index 2c7fedcefe..e45355a6dd 100644 --- a/ext/fts5/test/fts5_common.tcl +++ b/ext/fts5/test/fts5_common.tcl @@ -510,6 +510,22 @@ proc fts5_poslist_data {expr tbl {order ASC} {aDictVar ""}} { set res } +proc fts5_collist_data {expr tbl {order ASC} {aDictVar ""}} { + set res [list] + + if {$aDictVar!=""} { + upvar $aDictVar aDict + set dict aDict + } else { + set dict "" + } + + foreach {rowid poslist collist} [fts5_query_data $expr $tbl $order $dict] { + lappend res $rowid $collist + } + set res +} + #------------------------------------------------------------------------- # @@ -561,3 +577,54 @@ proc nearset_rc {aCol args} { list } + +#------------------------------------------------------------------------- +# Code for a simple Tcl tokenizer that supports synonyms at query time. +# +proc tclnum_tokenize {mode tflags text} { + foreach {w iStart iEnd} [fts5_tokenize_split $text] { + sqlite3_fts5_token $w $iStart $iEnd + if {$tflags == $mode && [info exists ::tclnum_syn($w)]} { + foreach s $::tclnum_syn($w) { sqlite3_fts5_token -colo $s $iStart $iEnd } + } + } +} + +proc tclnum_create {args} { + set mode query + if {[llength $args]} { + set mode [lindex $args 0] + } + if {$mode != "query" && $mode != "document"} { error "bad mode: $mode" } + return [list tclnum_tokenize $mode] +} + +proc fts5_tclnum_register {db} { + foreach SYNDICT { + {zero 0} + {one 1 i} + {two 2 ii} + {three 3 iii} + {four 4 iv} + {five 5 v} + {six 6 vi} + {seven 7 vii} + {eight 8 viii} + {nine 9 ix} + + {a1 a2 a3 a4 a5 a6 a7 a8 a9} + {b1 b2 b3 b4 b5 b6 b7 b8 b9} + {c1 c2 c3 c4 c5 c6 c7 c8 c9} + } { + foreach s $SYNDICT { + set o [list] + foreach x $SYNDICT {if {$x!=$s} {lappend o $x}} + set ::tclnum_syn($s) $o + } + } + sqlite3_fts5_create_tokenizer db tclnum tclnum_create +} +# +# End of tokenizer code. +#------------------------------------------------------------------------- + diff --git a/ext/fts5/test/fts5config.test b/ext/fts5/test/fts5config.test index dcda2d42a6..223e504a65 100644 --- a/ext/fts5/test/fts5config.test +++ b/ext/fts5/test/fts5config.test @@ -44,6 +44,8 @@ foreach {tn opt} { 3 {prefix='$'} 4 {prefix='1,2,'} 5 {prefix=',1'} + 6 {prefix='1,2,3...'} + 7 {prefix='1,2,3xyz'} } { set res [list 1 {malformed prefix=... directive}] do_catchsql_test 2.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res @@ -159,6 +161,8 @@ do_catchsql_test 8.1 { # 9.1.* 'pgsz' options. # 9.2.* 'automerge' options. # 9.3.* 'crisismerge' options. +# 9.4.* a non-existant option. +# 9.5.* 'hashsize' options. # do_execsql_test 9.0 { CREATE VIRTUAL TABLE abc USING fts5(a, b); @@ -203,6 +207,16 @@ do_catchsql_test 9.4.1 { INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1); } {1 {SQL logic error or missing database}} +do_catchsql_test 9.5.1 { + INSERT INTO abc(abc, rank) VALUES('hashsize', 'not an integer'); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.5.2 { + INSERT INTO abc(abc, rank) VALUES('hashsize', -500000); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.5.3 { + INSERT INTO abc(abc, rank) VALUES('hashsize', 500000); +} {0 {}} + #------------------------------------------------------------------------- # Too many prefix indexes. Maximum allowed is 31. # @@ -214,5 +228,20 @@ foreach {tn spec} { do_catchsql_test 10.$tn $sql {1 {too many prefix indexes (max 31)}} } +#------------------------------------------------------------------------- +# errors in the detail= option. +# +foreach {tn opt} { + 1 {detail=x} + 2 {detail='x'} + 3 {detail='$'} + 4 {detail='1,2,'} + 5 {detail=',1'} + 6 {detail=''} +} { + set res [list 1 {malformed detail=... directive}] + do_catchsql_test 11.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res +} + finish_test diff --git a/ext/fts5/test/fts5fault4.test b/ext/fts5/test/fts5fault4.test index 989a372d49..acc43ebfc6 100644 --- a/ext/fts5/test/fts5fault4.test +++ b/ext/fts5/test/fts5fault4.test @@ -40,27 +40,6 @@ do_faultsim_test 1 -faults oom-* -prep { faultsim_test_result [list 0 {}] } -#------------------------------------------------------------------------- -# An OOM within an "ORDER BY rank" query. -# -db func rnddoc fts5_rnddoc -do_execsql_test 2.0 { - CREATE VIRTUAL TABLE xx USING fts5(x); - INSERT INTO xx VALUES ('abc ' || rnddoc(10)); - INSERT INTO xx VALUES ('abc abc' || rnddoc(9)); - INSERT INTO xx VALUES ('abc abc abc' || rnddoc(8)); -} {} -faultsim_save_and_close - -do_faultsim_test 2 -faults oom-* -prep { - faultsim_restore_and_reopen - execsql { SELECT * FROM xx } -} -body { - execsql { SELECT rowid FROM xx WHERE xx MATCH 'abc' ORDER BY rank } -} -test { - faultsim_test_result [list 0 {3 2 1}] -} - #------------------------------------------------------------------------- # An OOM while "reseeking" an FTS cursor. # diff --git a/ext/fts5/test/fts5fault9.test b/ext/fts5/test/fts5fault9.test new file mode 100644 index 0000000000..b827c32df4 --- /dev/null +++ b/ext/fts5/test/fts5fault9.test @@ -0,0 +1,140 @@ +# 2015 September 3 +# +# 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 is focused on OOM errors. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5fault9 + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach_detail_mode $testprefix { + +fts5_aux_test_functions db + +if 1 { + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); + INSERT INTO t1(t1, rank) VALUES('pgsz', 32); + WITH seq(s) AS ( SELECT 1 UNION ALL SELECT s+1 FROM seq WHERE s<50) + INSERT INTO t1 SELECT 'x x x y y y', 'a b c d e f' FROM seq; +} + +do_faultsim_test 1 -faults oom-* -body { + execsql { SELECT count(*) FROM t1('x AND y') } +} -test { + faultsim_test_result {0 50} +} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t2 USING fts5(a, b, detail=%DETAIL%); + INSERT INTO t2(t2, rank) VALUES('pgsz', 32); + INSERT INTO t2 VALUES('abc cba', 'cba abc'); + INSERT INTO t2 VALUES('abc cba', 'cba abc'); + INSERT INTO t2 VALUES('abc cba', 'cba abc'); + + INSERT INTO t2 VALUES('axy cyx', 'cyx axy'); + INSERT INTO t2 VALUES('axy cyx', 'cyx axy'); + INSERT INTO t2 VALUES('axy cyx', 'cyx axy'); +} + +do_faultsim_test 2 -faults oom-* -body { + execsql { SELECT count(*) FROM t2('a* AND c*') } +} -test { + faultsim_test_result {0 6} +} + + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE t3 USING fts5(a, detail=%DETAIL%); + INSERT INTO t3 VALUES('a x x a x a a a'); + INSERT INTO t3 VALUES('x a a x a x x x'); +} + +do_faultsim_test 3.1 -faults oom-* -body { + execsql { SELECT highlight(t3, 0, '[', ']') FROM t3('a') } +} -test { + faultsim_test_result {0 {{[a] x x [a] x [a] [a] [a]} {x [a] [a] x [a] x x x}}} +} + +do_faultsim_test 3.2 -faults oom-t* -body { + execsql { SELECT fts5_test_poslist2(t3) FROM t3('x') } +} -test { + faultsim_test_result \ + {0 {{0.0.1 0.0.2 0.0.4} {0.0.0 0.0.3 0.0.5 0.0.6 0.0.7}}} \ + {1 SQLITE_NOMEM} +} + +#------------------------------------------------------------------------- +# Test OOM injection with the xPhraseFirstColumn() API and a tokenizer +# uses query synonyms. +# +fts5_tclnum_register db +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE t4 USING fts5(x, y, z, detail=%DETAIL%, tokenize=tclnum); + INSERT INTO t4 VALUES('one two three', '1 2 3', 'i ii iii'); + INSERT INTO t4 VALUES('1 2 3', 'i ii iii', 'one two three'); + INSERT INTO t4 VALUES('i ii iii', 'one two three', 'i ii iii'); + + INSERT INTO t4 VALUES('a1 a2 a3', 'a4 a5 a6', 'a7 a8 a9'); + INSERT INTO t4 VALUES('b1 b2 b3', 'b4 b5 b6', 'b7 b8 b9'); + INSERT INTO t4 VALUES('c1 c2 c3', 'c4 c5 c6', 'c7 c8 c9'); +} + +do_faultsim_test 4.1 -faults oom-t* -body { + execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') } +} -test { + faultsim_test_result \ + {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} {1 SQLITE_NOMEM} +} + +do_faultsim_test 4.2 -faults oom-t* -body { + execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') } +} -test { + faultsim_test_result \ + {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} {1 SQLITE_NOMEM} +} + +} + + +#------------------------------------------------------------------------- +# An OOM within an "ORDER BY rank" query. +# +db func rnddoc fts5_rnddoc +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE xx USING fts5(x, y, detail=%DETAIL%); + INSERT INTO xx VALUES ('def', 'abc ' || rnddoc(10)); + INSERT INTO xx VALUES ('def', 'abc abc' || rnddoc(9)); + INSERT INTO xx VALUES ('def', 'abc abc abc' || rnddoc(8)); +} {} +faultsim_save_and_close + +do_faultsim_test 5 -faults oom-* -prep { + faultsim_restore_and_reopen + execsql { SELECT * FROM xx } +} -body { + execsql { SELECT rowid FROM xx('abc AND def') ORDER BY rank } +} -test { + faultsim_test_result [list 0 {3 2 1}] +} + +} ;# foreach_detail_mode... + +finish_test + diff --git a/ext/fts5/test/fts5hash.test b/ext/fts5/test/fts5hash.test index a4a4f28343..ac8486f070 100644 --- a/ext/fts5/test/fts5hash.test +++ b/ext/fts5/test/fts5hash.test @@ -64,11 +64,13 @@ proc random_doc {vocab nWord} { return $doc } +foreach_detail_mode $testprefix { + set vocab [build_vocab1] db func r random_doc do_execsql_test 1.0 { - CREATE VIRTUAL TABLE eee USING fts5(e, ee); + CREATE VIRTUAL TABLE eee USING fts5(e, ee, detail=%DETAIL%); BEGIN; WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100) INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii; @@ -91,7 +93,7 @@ do_test 1.2 { } } {} -do_test 1.2 { +do_test 1.3 { db eval { SELECT term, doc FROM vocab } { set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}] if {$nRow != $doc} { @@ -101,10 +103,12 @@ do_test 1.2 { set {} {} } {} -do_execsql_test 1.3 { +do_execsql_test 1.4 { COMMIT; INSERT INTO eee(eee) VALUES('integrity-check'); } +} ;# foreach_detail_mode + finish_test diff --git a/ext/fts5/test/fts5synonym.test b/ext/fts5/test/fts5synonym.test index 008d2fc543..185dda3ff4 100644 --- a/ext/fts5/test/fts5synonym.test +++ b/ext/fts5/test/fts5synonym.test @@ -21,42 +21,16 @@ ifcapable !fts5 { return } -foreach S { - {zero 0} - {one 1 i} - {two 2 ii} - {three 3 iii} - {four 4 iv} - {five 5 v} - {six 6 vi} - {seven 7 vii} - {eight 8 viii} - {nine 9 ix} -} { - foreach s $S { - set o [list] - foreach x $S {if {$x!=$s} {lappend o $x}} - set ::syn($s) $o - } -} +proc tcl_create {args} { return "tcl_tokenize" } -proc tcl_tokenize {tflags text} { - foreach {w iStart iEnd} [fts5_tokenize_split $text] { - sqlite3_fts5_token $w $iStart $iEnd - } -} - -proc tcl_create {args} { - return "tcl_tokenize" -} - -sqlite3_fts5_create_tokenizer db tcl tcl_create +foreach_detail_mode $testprefix { #------------------------------------------------------------------------- # Warm body test for the code in fts5_tcl.c. # +fts5_tclnum_register db do_execsql_test 1.0 { - CREATE VIRTUAL TABLE ft USING fts5(x, tokenize = tcl); + CREATE VIRTUAL TABLE ft USING fts5(x, tokenize = "tclnum document", detail=%DETAIL%); INSERT INTO ft VALUES('abc def ghi'); INSERT INTO ft VALUES('jkl mno pqr'); SELECT rowid, x FROM ft WHERE ft MATCH 'def'; @@ -67,22 +41,13 @@ do_execsql_test 1.0 { # Test a tokenizer that supports synonyms by adding extra entries to the # FTS index. # - -proc tcl_tokenize {tflags text} { - foreach {w iStart iEnd} [fts5_tokenize_split $text] { - sqlite3_fts5_token $w $iStart $iEnd - if {$tflags=="document" && [info exists ::syn($w)]} { - foreach s $::syn($w) { - sqlite3_fts5_token -colo $s $iStart $iEnd - } - } - } -} reset_db -sqlite3_fts5_create_tokenizer db tcl tcl_create +fts5_tclnum_register db do_execsql_test 2.0 { - CREATE VIRTUAL TABLE ft USING fts5(x, tokenize = tcl); + CREATE VIRTUAL TABLE ft USING fts5( + x, tokenize = "tclnum document", detail=%DETAIL% + ); INSERT INTO ft VALUES('one two three'); INSERT INTO ft VALUES('four five six'); INSERT INTO ft VALUES('eight nine ten'); @@ -95,6 +60,7 @@ foreach {tn expr res} { 4 "1*" {1} 5 "1 + 2" {1} } { + if {![fts5_expr_ok $expr ft]} continue do_execsql_test 2.1.$tn { SELECT rowid FROM ft WHERE ft MATCH $expr } $res @@ -180,17 +146,7 @@ do_execsql_test 3.2.5 { # Check that expressions with synonyms can be parsed and executed. # reset_db -sqlite3_fts5_create_tokenizer db tcl tcl_create -proc tcl_tokenize {tflags text} { - foreach {w iStart iEnd} [fts5_tokenize_split $text] { - sqlite3_fts5_token $w $iStart $iEnd - if {$tflags=="query" && [info exists ::syn($w)]} { - foreach s $::syn($w) { - sqlite3_fts5_token -colo $s $iStart $iEnd - } - } - } -} +fts5_tclnum_register db foreach {tn expr res} { 1 {abc} {"abc"} @@ -198,11 +154,13 @@ foreach {tn expr res} { 3 {3} {"3"|"iii"|"three"} 4 {3*} {"3"|"iii"|"three" *} } { - do_execsql_test 4.1.$tn {SELECT fts5_expr($expr, 'tokenize=tcl')} [list $res] + do_execsql_test 4.1.$tn { + SELECT fts5_expr($expr, 'tokenize=tclnum') + } [list $res] } do_execsql_test 4.2.1 { - CREATE VIRTUAL TABLE xx USING fts5(x, tokenize=tcl); + CREATE VIRTUAL TABLE xx USING fts5(x, tokenize=tclnum, detail=%DETAIL%); INSERT INTO xx VALUES('one two'); INSERT INTO xx VALUES('three four'); } @@ -217,7 +175,7 @@ do_execsql_test 4.2.3 { do_test 5.0 { execsql { - CREATE VIRTUAL TABLE t1 USING fts5(a, b, tokenize=tcl) + CREATE VIRTUAL TABLE t1 USING fts5(a, b, tokenize=tclnum, detail=%DETAIL%) } foreach {rowid a b} { 1 {four v 4 i three} {1 3 five five 4 one} @@ -285,6 +243,7 @@ foreach {tn q res} { 5 {three i v i four 4 1} {ii [five five five] iii} } } { + if {![fts5_expr_ok $q t1]} continue do_execsql_test 5.1.$tn { SELECT rowid, highlight(t1, 0, '[', ']'), highlight(t1, 1, '[', ']') FROM t1 WHERE t1 MATCH $q @@ -316,7 +275,6 @@ foreach {tn q res} { } $res } - #------------------------------------------------------------------------- # Test terms with more than 4 synonyms. # @@ -334,17 +292,19 @@ proc tcl_tokenize {tflags text} { } do_execsql_test 6.0.1 { - CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize=tcl); + CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize=tcl, detail=%DETAIL%); INSERT INTO t1 VALUES('yy xx qq'); INSERT INTO t1 VALUES('yy xx xx'); } -do_execsql_test 6.0.2 { - SELECT * FROM t1 WHERE t1 MATCH 'NEAR(y q)'; -} {{yy xx qq}} +if {[fts5_expr_ok "NEAR(y q)" t1]} { + do_execsql_test 6.0.2 { + SELECT * FROM t1 WHERE t1 MATCH 'NEAR(y q)'; + } {{yy xx qq}} +} do_test 6.0.3 { execsql { - CREATE VIRTUAL TABLE t2 USING fts5(a, b, tokenize=tcl) + CREATE VIRTUAL TABLE t2 USING fts5(a, b, tokenize=tcl, detail=%DETAIL%) } foreach {rowid a b} { 1 {yyyy vvvvv qq oo yyyyyy vvvv eee} {ffff uu r qq aaaa} @@ -387,6 +347,8 @@ foreach {tn q res} { 2 {ww oooooo bbbbb ssssss mm} {ffffff [yy] iiii rr s ccc [qqqqq]} } } { + if {![fts5_expr_ok $q t2]} continue + do_execsql_test 6.1.$tn.asc { SELECT rowid, highlight(t2, 0, '[', ']'), highlight(t2, 1, '[', ']') FROM t2 WHERE t2 MATCH $q @@ -435,7 +397,7 @@ proc tcl_tokenize {tflags text} { } do_execsql_test 7.0.1 { - CREATE VIRTUAL TABLE t1 USING fts5(a, b, columnsize=1, tokenize=tcl); + CREATE VIRTUAL TABLE t1 USING fts5(a, b, columnsize=1, tokenize=tcl, detail=%DETAIL%); INSERT INTO t1 VALUES('0 2 3', '4 5 6 7'); INSERT INTO t1 VALUES('8 9', '0 0 0 0 0 0 0 0 0 0'); SELECT fts5_test_columnsize(t1) FROM t1 WHERE t1 MATCH '000 AND 00 AND 0'; @@ -446,7 +408,7 @@ do_execsql_test 7.0.2 { } do_execsql_test 7.1.1 { - CREATE VIRTUAL TABLE t2 USING fts5(a, b, columnsize=0, tokenize=tcl); + CREATE VIRTUAL TABLE t2 USING fts5(a, b, columnsize=0, tokenize=tcl, detail=%DETAIL%); INSERT INTO t2 VALUES('0 2 3', '4 5 6 7'); INSERT INTO t2 VALUES('8 9', '0 0 0 0 0 0 0 0 0 0'); SELECT fts5_test_columnsize(t2) FROM t2 WHERE t2 MATCH '000 AND 00 AND 0'; @@ -456,5 +418,7 @@ do_execsql_test 7.1.2 { INSERT INTO t2(t2) VALUES('integrity-check'); } +} ;# foreach_detail_mode + finish_test diff --git a/ext/fts5/test/fts5synonym2.test b/ext/fts5/test/fts5synonym2.test index 96cacb293f..dddaa17af8 100644 --- a/ext/fts5/test/fts5synonym2.test +++ b/ext/fts5/test/fts5synonym2.test @@ -21,52 +21,22 @@ ifcapable !fts5 { return } -#------------------------------------------------------------------------- -# Code for a simple Tcl tokenizer that supports synonyms at query time. -# -foreach SYNDICT { - {zero 0} - {one 1 i} - {two 2 ii} - {three 3 iii} - {four 4 iv} - {five 5 v} - {six 6 vi} - {seven 7 vii} - {eight 8 viii} - {nine 9 ix} -} { - foreach s $SYNDICT { - set o [list] - foreach x $SYNDICT {if {$x!=$s} {lappend o $x}} - set ::syn($s) $o - } -} - -proc tcl_tokenize {tflags text} { - foreach {w iStart iEnd} [fts5_tokenize_split $text] { - sqlite3_fts5_token $w $iStart $iEnd - if {$tflags == "query"} { - foreach s $::syn($w) { sqlite3_fts5_token -colo $s $iStart $iEnd } - } - } -} - -proc tcl_create {args} { - return "tcl_tokenize" -} - -# -# End of tokenizer code. -#------------------------------------------------------------------------- - +foreach tok {query document} { foreach_detail_mode $testprefix { -sqlite3_fts5_create_tokenizer db tcl tcl_create +fts5_tclnum_register db fts5_aux_test_functions db -do_execsql_test 1.0 { - CREATE VIRTUAL TABLE ss USING fts5(a, b, tokenize=tcl, detail=%DETAIL%); +proc fts5_rowid {cmd} { expr [$cmd xColumnText -1] } +sqlite3_fts5_create_function db fts5_rowid fts5_rowid + +do_execsql_test 1.$tok.0.1 " + CREATE VIRTUAL TABLE ss USING fts5(a, b, + tokenize='tclnum $tok', detail=%DETAIL%); + INSERT INTO ss(ss, rank) VALUES('rank', 'fts5_rowid()'); +" + +do_execsql_test 1.$tok.0.2 { INSERT INTO ss VALUES('5 5 five seven 3 seven i', '2 1 5 0 two 1 i'); INSERT INTO ss VALUES('six ix iii 7 i vii iii', 'one seven nine 4 9 1 vi'); INSERT INTO ss VALUES('6 viii i five six zero seven', '5 v iii iv iv 3'); @@ -137,17 +107,22 @@ foreach {tn expr} { 4.3 "NEAR(eight nine, 1) OR NEAR(six seven, 1)" } { if {[fts5_expr_ok $expr ss]==0} { - do_test 1.$tn.OMITTED { list } [list] + do_test 1.$tok.$tn.OMITTED { list } [list] continue } - set res [fts5_query_data $expr ss ASC ::syn] - breakpoint - do_execsql_test 1.$tn.[llength $res].asc { + set res [fts5_query_data $expr ss ASC ::tclnum_syn] + do_execsql_test 1.$tok.$tn.[llength $res].asc.1 { SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr) } $res + + do_execsql_test 1.$tok.$tn.[llength $res].asc.2 { + SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr) + ORDER BY rank ASC + } $res } +} } finish_test diff --git a/manifest b/manifest index fa6bddb8b1..8872e8fc50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3VdbeAddOp4()\srather\sthan\sa\sseparate\ssqlite3VdbeChangeP4()\scall,\sfor\na\sslightly\ssmaller\sand\sfaster\sbinary. -D 2016-01-16T15:12:35.739 +C Add\sfurther\stests\sfor\sfts5.\sFix\ssome\sproblems\swith\sdetail=col\smode\sand\sauxiliary\sfunctions. +D 2016-01-16T18:58:51.767 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -99,14 +99,14 @@ F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7 F ext/fts5/fts5Int.h 313e3276ac9e0245ee722ef803253857a68722b9 F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e -F ext/fts5/fts5_buffer.c 87204c8b3b8bc62b27376eab09b74d6d5acc41f1 -F ext/fts5/fts5_config.c 9c243d04ac0ca997d2d2e2252891f2a10fbd7217 -F ext/fts5/fts5_expr.c 510db45967ca359f64f2ba2c707ab57d740cad56 +F ext/fts5/fts5_buffer.c ba59964c95f760bd5ff1dbe173b85f197a13864e +F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 +F ext/fts5/fts5_expr.c 3ba4c9588ebb2e4f852d807869af7130b6362e5a F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 F ext/fts5/fts5_index.c cd036089b22b0340fccef88a3ad62ac1016c7cbb -F ext/fts5/fts5_main.c 1d116f5c44c6f06ec282d33dd6d041c8131b3d6a +F ext/fts5/fts5_main.c 833db0a3df10ab26e0221a9baa40cf871c450df3 F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e -F ext/fts5/fts5_tcl.c bcacc05dec0446e7b1a44d5d906057e677bd7ea4 +F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8 @@ -115,7 +115,7 @@ F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 F ext/fts5/fts5_vocab.c ee6df1a3be103414d7b7af833ae1885c7b83a9d0 F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba -F ext/fts5/test/fts5_common.tcl 393882afb225a21edf033043bbf936951e9198c1 +F ext/fts5/test/fts5_common.tcl 75b0af04898c18df289620dd4e7442d881e3ccc1 F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test d5073ca7bd2d9fe8aab0c82c6c75a7e4b0d70ced @@ -134,7 +134,7 @@ F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 -F ext/fts5/test/fts5config.test 42c1336cc6ed33d7e9c4a05dbce81721b765e7d0 +F ext/fts5/test/fts5config.test 83941309b94d002ed6f55d9cd814e0353c9ae013 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 @@ -148,13 +148,14 @@ F ext/fts5/test/fts5eb.test 021aa80b7ac09b964249aa32ced9ee908703e4aa F ext/fts5/test/fts5fault1.test 4b39c47ca3544615daa8a2f733b911fa08022c77 F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 -F ext/fts5/test/fts5fault4.test 4864f2b5c2c083440dbe85aff60897bc1aa04603 +F ext/fts5/test/fts5fault4.test 532b6dacb963016cbf7003196bd87fb366540277 F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b F ext/fts5/test/fts5fault8.test f2d8a2b673a5f72ca1fa0e85bdbfb2041ffd347d +F ext/fts5/test/fts5fault9.test 964a3ee82b95053bd45d809fe2b7acf4a8c90ca9 F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 -F ext/fts5/test/fts5hash.test 7cf4607b8657c383f0b520668a99971e95d8b139 +F ext/fts5/test/fts5hash.test 00668f6fa9b9bffbd7c1be29f408aa2bdade0451 F ext/fts5/test/fts5integrity.test 87db5d4e7da0ce04a1dcba5ba91658673c997a65 F ext/fts5/test/fts5matchinfo.test 86569026d20f1ed748236587ce798de8a96615f1 F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367 @@ -173,8 +174,8 @@ F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 400384798349d658eaf06aefa1e364957d5d4821 F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 F ext/fts5/test/fts5simple2.test 7b51f8d411e9a77fa4519fb09ba5a3afda75c94d -F ext/fts5/test/fts5synonym.test cf88c0a56d5ea9591e3939ef1f6e294f7f2d0671 -F ext/fts5/test/fts5synonym2.test d2d9099d9d105b55ea03fd52d61ae2847d534129 +F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 +F ext/fts5/test/fts5synonym2.test eadb00c73ef0653258873e756b7e9102e0687539 F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89 @@ -1416,7 +1417,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 653ea15ad8e23b333e234eb5dde7b80134db2baf -R 2155f55389b348e9a35fea6f93c01bbe -U drh -Z 32d5bf122f6c10496965338bc29a15a2 +P a4258cd4613c55acacb5c7b61faa3de7eb0759d2 +R 7d01724b879e1ef98656daadba5b9cfb +U dan +Z d745955e2f048d17831d9a126adffb23 diff --git a/manifest.uuid b/manifest.uuid index 39ad2ac515..94a16261bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4258cd4613c55acacb5c7b61faa3de7eb0759d2 \ No newline at end of file +de77d6026e8035c505a704e7b8cfe5af6579d35f \ No newline at end of file From 2ce1865dd86b6a96e305e0736d719de7e60e7b46 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Jan 2016 20:50:21 +0000 Subject: [PATCH 13/29] Improvements to the way sqlite3VdbeAddOpList() works, resulting in a slightly smaller and faster binary. FossilOrigin-Name: 88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f --- manifest | 20 ++++----- manifest.uuid | 2 +- src/pragma.c | 87 +++++++++++++++++++++---------------- src/vdbe.h | 9 +++- src/vdbeaux.c | 56 +++++++++++++++--------- src/vdbeblob.c | 113 +++++++++++++++++++++++++------------------------ 6 files changed, 161 insertions(+), 126 deletions(-) diff --git a/manifest b/manifest index 8872e8fc50..c9a3b49a57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\stests\sfor\sfts5.\sFix\ssome\sproblems\swith\sdetail=col\smode\sand\sauxiliary\sfunctions. -D 2016-01-16T18:58:51.767 +C Improvements\sto\sthe\sway\ssqlite3VdbeAddOpList()\sworks,\sresulting\sin\sa\sslightly\nsmaller\sand\sfaster\sbinary. +D 2016-01-16T20:50:21.742 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -336,7 +336,7 @@ F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6 +F src/pragma.c 53c95f5454e2a8bdb25ebf1567bed6690910ce25 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19 F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 @@ -409,11 +409,11 @@ F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 -F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 +F src/vdbe.h 22f8c913bd2c8549b3d3a897da3428efbe944378 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 906c0350f316dd13a26d8a91865f1dd7f14dc19b -F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15 +F src/vdbeaux.c 82969fb2558e6cf57601e283f0101d0f60f5a4f2 +F src/vdbeblob.c 8542f282b58293bd61c2ea4b2125f250f4fc9543 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 @@ -1417,7 +1417,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a4258cd4613c55acacb5c7b61faa3de7eb0759d2 -R 7d01724b879e1ef98656daadba5b9cfb -U dan -Z d745955e2f048d17831d9a126adffb23 +P de77d6026e8035c505a704e7b8cfe5af6579d35f +R e442832cd3e3e0853ec0a993c2468ee7 +U drh +Z 51b7d6e877f13b345892ef271baf2a12 diff --git a/manifest.uuid b/manifest.uuid index 94a16261bf..fda58e60e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de77d6026e8035c505a704e7b8cfe5af6579d35f \ No newline at end of file +88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 0d48057d21..50f7229c33 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -430,15 +430,17 @@ void sqlite3Pragma( { OP_Noop, 0, 0, 0}, { OP_ResultRow, 1, 1, 0}, }; - int addr; + VdbeOp *aOp; sqlite3VdbeUsesBtree(v, iDb); if( !zRight ){ setOneColumnName(v, "cache_size"); pParse->nMem += 2; - addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+1, iDb); - sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); + sqlite3VdbeVerifyAvailableSpace(v, ArraySize(getCacheSize)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); + assert( aOp!=0 ); + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; }else{ int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); sqlite3BeginWriteOperation(pParse, 0, iDb); @@ -684,13 +686,16 @@ void sqlite3Pragma( { OP_Integer, 0, 1, 0}, /* 4 */ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ }; - int iAddr; - iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); - sqlite3VdbeChangeP1(v, iAddr, iDb); - sqlite3VdbeChangeP1(v, iAddr+1, iDb); - sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); - sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); - sqlite3VdbeChangeP1(v, iAddr+5, iDb); + VdbeOp *aOp; + int iAddr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyAvailableSpace(v, ArraySize(setMeta6)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); + assert( aOp!=0 ); + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[2].p2 = iAddr+4; + aOp[4].p1 = eAuto - 1; + aOp[5].p1 = iDb; sqlite3VdbeUsesBtree(v, iDb); } } @@ -1396,18 +1401,6 @@ void sqlite3Pragma( case PragTyp_INTEGRITY_CHECK: { int i, j, addr, mxErr; - /* Code that appears at the end of the integrity check. If no error - ** messages have been generated, output OK. Otherwise output the - ** error message - */ - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList endCode[] = { - { OP_AddImm, 1, 0, 0}, /* 0 */ - { OP_If, 1, 0, 0}, /* 1 */ - { OP_String8, 0, 3, 0}, /* 2 */ - { OP_ResultRow, 3, 1, 0}, - }; - int isQuick = (sqlite3Tolower(zLeft[0])=='q'); /* If the PRAGMA command was of the form "PRAGMA .integrity_check", @@ -1604,10 +1597,24 @@ void sqlite3Pragma( #endif /* SQLITE_OMIT_BTREECOUNT */ } } - addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); - sqlite3VdbeChangeP2(v, addr, -mxErr); - sqlite3VdbeJumpHere(v, addr+1); - sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); + { + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList endCode[] = { + { OP_AddImm, 1, 0, 0}, /* 0 */ + { OP_If, 1, 0, 0}, /* 1 */ + { OP_String8, 0, 3, 0}, /* 2 */ + { OP_ResultRow, 3, 1, 0}, + }; + VdbeOp *aOp; + + aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); + if( aOp ){ + aOp[0].p2 = -mxErr; + aOp[1].p2 = sqlite3VdbeCurrentAddr(v); + aOp[2].p4type = P4_STATIC; + aOp[2].p4.z = "ok"; + } + } } break; #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -1724,11 +1731,14 @@ void sqlite3Pragma( { OP_Integer, 0, 1, 0}, /* 1 */ { OP_SetCookie, 0, 0, 1}, /* 2 */ }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight)); - sqlite3VdbeChangeP1(v, addr+2, iDb); - sqlite3VdbeChangeP2(v, addr+2, iCookie); + VdbeOp *aOp; + sqlite3VdbeVerifyAvailableSpace(v, ArraySize(setCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); + assert( aOp!=0 ); + aOp[0].p1 = iDb; + aOp[1].p1 = sqlite3Atoi(zRight); + aOp[2].p1 = iDb; + aOp[2].p2 = iCookie; }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { @@ -1736,10 +1746,13 @@ void sqlite3Pragma( { OP_ReadCookie, 0, 1, 0}, /* 1 */ { OP_ResultRow, 1, 1, 0} }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0); - sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+1, iDb); - sqlite3VdbeChangeP3(v, addr+1, iCookie); + VdbeOp *aOp; + sqlite3VdbeVerifyAvailableSpace(v, ArraySize(readCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); + assert( aOp!=0 ); + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[1].p3 = iCookie; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); } diff --git a/src/vdbe.h b/src/vdbe.h index 68a4f6b2a8..a0ff16d891 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -180,7 +180,12 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); -int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); +#ifdef SQLITE_DEBUG + void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N); +#else +# define sqlite3VdbeVerifyAvailableSpace(A,B) +#endif +VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); @@ -188,7 +193,7 @@ void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); void sqlite3VdbeChangeP5(Vdbe*, u8 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); -void sqlite3VdbeChangeToNoop(Vdbe*, int addr); +int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 758c85fd1c..9859054ba4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -250,8 +250,7 @@ void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ for(i=0; (c = zTypes[i])!=0; i++){ if( c=='s' ){ const char *z = va_arg(ap, const char*); - int addr = sqlite3VdbeAddOp2(p, z==0 ? OP_Null : OP_String8, 0, iDest++); - if( z ) sqlite3VdbeChangeP4(p, addr, z, 0); + sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest++, 0, z, 0); }else{ assert( c=='i' ); sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++); @@ -606,6 +605,17 @@ int sqlite3VdbeCurrentAddr(Vdbe *p){ return p->nOp; } +/* +** Verify that at least N opcode slots are available in p without +** having to malloc for more space. This interface is used for +** testing only. +*/ +#ifdef SQLITE_DEBUG +void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N){ + assert( p->nOp + N <= p->pParse->nOpAlloc ); +} +#endif + /* ** This function returns a pointer to the array of opcodes associated with ** the Vdbe passed as the first argument. It is the callers responsibility @@ -631,19 +641,23 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ } /* -** Add a whole list of operations to the operation stack. Return the -** address of the first operation added. +** Add a whole list of operations to the operation stack. Return a +** pointer to the first operation inserted. */ -int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){ - int addr, i; - VdbeOp *pOut; +VdbeOp *sqlite3VdbeAddOpList( + Vdbe *p, /* Add opcodes to the prepared statement */ + int nOp, /* Number of opcodes to add */ + VdbeOpList const *aOp, /* The opcodes to be added */ + int iLineno /* Source-file line number of first opcode */ +){ + int i; + VdbeOp *pOut, *pFirst; assert( nOp>0 ); assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ return 0; } - addr = p->nOp; - pOut = &p->aOp[addr]; + pFirst = pOut = &p->aOp[p->nOp]; for(i=0; iopcode = aOp->opcode; pOut->p1 = aOp->p1; @@ -663,12 +677,12 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){ #endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ - sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]); + sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]); } #endif } p->nOp += nOp; - return addr; + return pFirst; } #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) @@ -826,14 +840,15 @@ void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ /* ** Change the opcode at addr into OP_Noop */ -void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ - if( addrnOp ){ - VdbeOp *pOp = &p->aOp[addr]; - sqlite3 *db = p->db; - freeP4(db, pOp->p4type, pOp->p4.p); - memset(pOp, 0, sizeof(pOp[0])); - pOp->opcode = OP_Noop; - } +int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ + VdbeOp *pOp; + if( p->db->mallocFailed ) return 0; + assert( addr>=0 && addrnOp ); + pOp = &p->aOp[addr]; + freeP4(p->db, pOp->p4type, pOp->p4.p); + memset(pOp, 0, sizeof(pOp[0])); + pOp->opcode = OP_Noop; + return 1; } /* @@ -842,8 +857,7 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ */ int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){ - sqlite3VdbeChangeToNoop(p, p->nOp-1); - return 1; + return sqlite3VdbeChangeToNoop(p, p->nOp-1); }else{ return 0; } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index a4718efacc..e5f08ce933 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -115,38 +115,6 @@ int sqlite3_blob_open( ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ - - /* This VDBE program seeks a btree cursor to the identified - ** db/table/row entry. The reason for using a vdbe program instead - ** of writing code to use the b-tree layer directly is that the - ** vdbe program will take advantage of the various transaction, - ** locking and error handling infrastructure built into the vdbe. - ** - ** After seeking the cursor, the vdbe executes an OP_ResultRow. - ** Code external to the Vdbe then "borrows" the b-tree cursor and - ** uses it to implement the blob_read(), blob_write() and - ** blob_bytes() functions. - ** - ** The sqlite3_blob_close() function finalizes the vdbe program, - ** which closes the b-tree cursor and (possibly) commits the - ** transaction. - */ - static const int iLn = VDBE_OFFSET_LINENO(4); - static const VdbeOpList openBlob[] = { - /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */ - {OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */ - /* One of the following two instructions is replaced by an OP_Noop. */ - {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ - {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ - {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */ - {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 6 */ - {OP_ResultRow, 1, 0, 0}, /* 7 */ - {OP_Goto, 0, 4, 0}, /* 8 */ - {OP_Close, 0, 0, 0}, /* 9 */ - {OP_Halt, 0, 0, 0}, /* 10 */ - }; - int rc = SQLITE_OK; char *zErr = 0; Table *pTab; @@ -265,45 +233,80 @@ int sqlite3_blob_open( pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse); assert( pBlob->pStmt || db->mallocFailed ); if( pBlob->pStmt ){ + + /* This VDBE program seeks a btree cursor to the identified + ** db/table/row entry. The reason for using a vdbe program instead + ** of writing code to use the b-tree layer directly is that the + ** vdbe program will take advantage of the various transaction, + ** locking and error handling infrastructure built into the vdbe. + ** + ** After seeking the cursor, the vdbe executes an OP_ResultRow. + ** Code external to the Vdbe then "borrows" the b-tree cursor and + ** uses it to implement the blob_read(), blob_write() and + ** blob_bytes() functions. + ** + ** The sqlite3_blob_close() function finalizes the vdbe program, + ** which closes the b-tree cursor and (possibly) commits the + ** transaction. + */ + static const int iLn = VDBE_OFFSET_LINENO(3); + static const VdbeOpList openBlob[] = { + /* {OP_Transaction, 0, 0, 0}, // inserted separately */ + {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ + {OP_OpenRead, 0, 0, 0}, /* 1: Open cursor 0 for reading */ + {OP_OpenWrite, 0, 0, 0}, /* 2: Open cursor 0 for read/write */ + {OP_Variable, 1, 1, 1}, /* 3: Push the rowid to the stack */ + {OP_NotExists, 0, 10, 1}, /* 4: Seek the cursor */ + {OP_Column, 0, 0, 1}, /* 5 */ + {OP_ResultRow, 1, 0, 0}, /* 6 */ + {OP_Goto, 0, 4, 0}, /* 7 */ + {OP_Close, 0, 0, 0}, /* 8 */ + {OP_Halt, 0, 0, 0}, /* 9 */ + }; Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - + VdbeOp *aOp; sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, pTab->pSchema->schema_cookie, pTab->pSchema->iGeneration); sqlite3VdbeChangeP5(v, 1); - sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); + aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); - /* Configure the OP_TableLock instruction */ + if( db->mallocFailed==0 ){ + assert( aOp!=0 ); + /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE - sqlite3VdbeChangeToNoop(v, 1); + aOp[0].opcode = OP_Noop; #else - sqlite3VdbeChangeP1(v, 1, iDb); - sqlite3VdbeChangeP2(v, 1, pTab->tnum); - sqlite3VdbeChangeP3(v, 1, flags); - sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); + aOp[0].p1 = iDb; + aOp[0].p2 = pTab->tnum; + aOp[0].p3 = flags; + sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); + } + if( db->mallocFailed==0 ){ #endif - /* Remove either the OP_OpenWrite or OpenRead. Set the P2 - ** parameter of the other to pTab->tnum. */ - sqlite3VdbeChangeToNoop(v, 3 - flags); - sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum); - sqlite3VdbeChangeP3(v, 2 + flags, iDb); + /* Remove either the OP_OpenWrite or OpenRead. Set the P2 + ** parameter of the other to pTab->tnum. */ + aOp[2-flags].opcode = OP_Noop; + aOp[1+flags].p2 = pTab->tnum; + aOp[1+flags].p3 = iDb; + + /* Configure the number of columns. Configure the cursor to + ** think that the table has one more column than it really + ** does. An OP_Column to retrieve this imaginary column will + ** always return an SQL NULL. This is useful because it means + ** we can invoke OP_Column to fill in the vdbe cursors type + ** and offset cache without causing any IO. + */ + aOp[1+flags].p4type = P4_INT32; + aOp[1+flags].p4.i = pTab->nCol+1; + aOp[5].p2 = pTab->nCol; - /* Configure the number of columns. Configure the cursor to - ** think that the table has one more column than it really - ** does. An OP_Column to retrieve this imaginary column will - ** always return an SQL NULL. This is useful because it means - ** we can invoke OP_Column to fill in the vdbe cursors type - ** and offset cache without causing any IO. - */ - sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); - sqlite3VdbeChangeP2(v, 6, pTab->nCol); - if( !db->mallocFailed ){ pParse->nVar = 1; pParse->nMem = 1; pParse->nTab = 1; From 3ed7029921c201a6dc9a0861497b782d392ac47c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Jan 2016 21:06:41 +0000 Subject: [PATCH 14/29] Add extra tests to cover untested branches in fts5. FossilOrigin-Name: 61deab043dcea860070dba6b02601a7de627fff1 --- ext/fts5/test/fts5fault9.test | 24 ++++++++++++++++++++---- ext/fts5/test/fts5rowid.test | 4 ++-- ext/fts5/test/fts5update.test | 28 ++++++++++++++++++++++++++++ main.mk | 3 +-- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/ext/fts5/test/fts5fault9.test b/ext/fts5/test/fts5fault9.test index b827c32df4..908a91d22a 100644 --- a/ext/fts5/test/fts5fault9.test +++ b/ext/fts5/test/fts5fault9.test @@ -26,8 +26,6 @@ foreach_detail_mode $testprefix { fts5_aux_test_functions db -if 1 { - do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); INSERT INTO t1(t1, rank) VALUES('pgsz', 32); @@ -110,8 +108,6 @@ do_faultsim_test 4.2 -faults oom-t* -body { {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} {1 SQLITE_NOMEM} } -} - #------------------------------------------------------------------------- # An OOM within an "ORDER BY rank" query. @@ -134,6 +130,26 @@ do_faultsim_test 5 -faults oom-* -prep { faultsim_test_result [list 0 {3 2 1}] } +set doc [string repeat "xyz " 500] +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE yy USING fts5(y, detail=%DETAIL%); + INSERT INTO yy(yy, rank) VALUES('pgsz', 64); + INSERT INTO yy VALUES ($doc); + INSERT INTO yy VALUES ('1 2 3'); + INSERT INTO yy VALUES ('xyz'); + UPDATE yy SET y = y WHERE rowid = 1; + UPDATE yy SET y = y WHERE rowid = 1; + UPDATE yy SET y = y WHERE rowid = 1; + UPDATE yy SET y = y WHERE rowid = 1; +} {} + +do_faultsim_test 6 -faults oom-* -body { + execsql { SELECT rowid FROM yy('xyz') } +} -test { + faultsim_test_result [list 0 {1 3}] +} + + } ;# foreach_detail_mode... finish_test diff --git a/ext/fts5/test/fts5rowid.test b/ext/fts5/test/fts5rowid.test index 621934c0f2..1db1d56003 100644 --- a/ext/fts5/test/fts5rowid.test +++ b/ext/fts5/test/fts5rowid.test @@ -63,6 +63,7 @@ do_execsql_test 2.2 { SELECT rnddoc(6), rnddoc(6) FROM r ) INSERT INTO x1 SELECT * FROM r LIMIT 10000; + DELETE FROM x1 WHERE (rowid%2); } set res [db one {SELECT count(*) FROM x1_data}] @@ -71,8 +72,7 @@ do_execsql_test 2.3 { } $res do_execsql_test 2.4 { UPDATE x1_data SET block = X''; - -- SELECT count(fts5_decode(rowid, block)) FROM x1_data; - SELECT count(*) FROM x1_data; + SELECT count(fts5_decode(rowid, block)) FROM x1_data; } $res do_execsql_test 2.5 { diff --git a/ext/fts5/test/fts5update.test b/ext/fts5/test/fts5update.test index 9e7debe9da..399c7ffb11 100644 --- a/ext/fts5/test/fts5update.test +++ b/ext/fts5/test/fts5update.test @@ -87,6 +87,34 @@ do_test 1.4 { } } {} +#------------------------------------------------------------------------- +# Lots of deletes/inserts of the same document with the same rowid. +# +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE x2 USING fts5(x, detail=%DETAIL%); + INSERT INTO x2(x2, rank) VALUES('crisismerge', 2); + INSERT INTO x2 VALUES('a b c'); + INSERT INTO x2 VALUES('a b c'); +} +do_test 2.1 { + for {set i 0} {$i < 1000} {incr i} { + execsql { DELETE FROM x2 WHERE rowid = 2 } + execsql { INSERT INTO x2(rowid, x) VALUES(2, 'a b c') } + } +} {} +do_execsql_test 2.1.integrity { + INSERT INTO x2(x2) VALUES('integrity-check'); +} + +do_test 2.2 { + for {set i 0} {$i < 1000} {incr i} { + execsql { UPDATE x2 SET x=x WHERE rowid=2 } + } +} {} +do_execsql_test 2.2.integrity { + INSERT INTO x2(x2) VALUES('integrity-check'); +} + } finish_test diff --git a/main.mk b/main.mk index abf4fd2be7..934cd36a4e 100644 --- a/main.mk +++ b/main.mk @@ -334,8 +334,7 @@ TESTSRC += \ $(TOP)/ext/misc/vfslog.c \ $(TOP)/ext/fts5/fts5_tcl.c \ $(TOP)/ext/fts5/fts5_test_mi.c \ - $(TOP)/ext/fts5/fts5_test_tok.c \ - $(FTS5_SRC) + $(TOP)/ext/fts5/fts5_test_tok.c #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c diff --git a/manifest b/manifest index c9a3b49a57..931cca91e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\ssqlite3VdbeAddOpList()\sworks,\sresulting\sin\sa\sslightly\nsmaller\sand\sfaster\sbinary. -D 2016-01-16T20:50:21.742 +C Add\sextra\stests\sto\scover\suntested\sbranches\sin\sfts5. +D 2016-01-16T21:06:41.650 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -153,7 +153,7 @@ F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b F ext/fts5/test/fts5fault8.test f2d8a2b673a5f72ca1fa0e85bdbfb2041ffd347d -F ext/fts5/test/fts5fault9.test 964a3ee82b95053bd45d809fe2b7acf4a8c90ca9 +F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5hash.test 00668f6fa9b9bffbd7c1be29f408aa2bdade0451 F ext/fts5/test/fts5integrity.test 87db5d4e7da0ce04a1dcba5ba91658673c997a65 @@ -171,7 +171,7 @@ F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 -F ext/fts5/test/fts5rowid.test 400384798349d658eaf06aefa1e364957d5d4821 +F ext/fts5/test/fts5rowid.test 27a1e18c26d599a80bcabf6f687a4f1d8d29d2d2 F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 F ext/fts5/test/fts5simple2.test 7b51f8d411e9a77fa4519fb09ba5a3afda75c94d F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 @@ -183,7 +183,7 @@ F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 -F ext/fts5/test/fts5update.test 6f0abb89556f0a638b982e010f4d8d1de373a61c +F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 F ext/fts5/tool/fts5speed.tcl aaee41894b552df8fbf8616aad003b2ea9ba3221 @@ -267,7 +267,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 7575015811ef75a2cfcbc6f09de161cc8236e8a5 +F main.mk 8670f56454bdc59d5e33397bf8c7e43eb33af50c F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1417,7 +1417,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P de77d6026e8035c505a704e7b8cfe5af6579d35f -R e442832cd3e3e0853ec0a993c2468ee7 -U drh -Z 51b7d6e877f13b345892ef271baf2a12 +P 88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f +R 06f6f18fb8f74fb2b70e371e01be7b37 +U dan +Z df25345e1d2056d2ea7917d42461493d diff --git a/manifest.uuid b/manifest.uuid index fda58e60e8..539e4c0214 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f \ No newline at end of file +61deab043dcea860070dba6b02601a7de627fff1 \ No newline at end of file From dad300d8e1a9e9db9b9be19929e22d6a3c2bcdda Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Jan 2016 00:20:26 +0000 Subject: [PATCH 15/29] Fix a problem with SQLITE_TEST_REALLOC_STRESS. FossilOrigin-Name: 0aaf3febb00f622c5ef0853b2491d69f7ca7a21e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/pragma.c | 16 ++++++++-------- src/sqliteInt.h | 15 +++++++++++++++ src/vdbe.h | 6 +++--- src/vdbeaux.c | 11 +++++++---- 6 files changed, 44 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 931cca91e8..1042db4582 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stests\sto\scover\suntested\sbranches\sin\sfts5. -D 2016-01-16T21:06:41.650 +C Fix\sa\sproblem\swith\sSQLITE_TEST_REALLOC_STRESS. +D 2016-01-18T00:20:26.450 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -336,7 +336,7 @@ F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c 53c95f5454e2a8bdb25ebf1567bed6690910ce25 +F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19 F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 @@ -348,7 +348,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 028d1f88501048b5258f7119032278a55c963512 +F src/sqliteInt.h 8fbaf9dc2bb979865c739e5272fe0b352fbc709f F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -409,10 +409,10 @@ F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 -F src/vdbe.h 22f8c913bd2c8549b3d3a897da3428efbe944378 +F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 82969fb2558e6cf57601e283f0101d0f60f5a4f2 +F src/vdbeaux.c 95e067a5e2a75e128d45ca597388dc83c58142f0 F src/vdbeblob.c 8542f282b58293bd61c2ea4b2125f250f4fc9543 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -1417,7 +1417,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f -R 06f6f18fb8f74fb2b70e371e01be7b37 -U dan -Z df25345e1d2056d2ea7917d42461493d +P 61deab043dcea860070dba6b02601a7de627fff1 +R 4379f64b4cb45ea0db7a5f863224d3f6 +U drh +Z e0f8e155ee8f1f04cd4cfaa23a1af003 diff --git a/manifest.uuid b/manifest.uuid index 539e4c0214..37eeb2a0f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61deab043dcea860070dba6b02601a7de627fff1 \ No newline at end of file +0aaf3febb00f622c5ef0853b2491d69f7ca7a21e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 50f7229c33..15f0eecce3 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -435,9 +435,9 @@ void sqlite3Pragma( if( !zRight ){ setOneColumnName(v, "cache_size"); pParse->nMem += 2; - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(getCacheSize)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; @@ -688,9 +688,9 @@ void sqlite3Pragma( }; VdbeOp *aOp; int iAddr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(setMeta6)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[2].p2 = iAddr+4; @@ -1732,9 +1732,9 @@ void sqlite3Pragma( { OP_SetCookie, 0, 0, 1}, /* 2 */ }; VdbeOp *aOp; - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(setCookie)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = sqlite3Atoi(zRight); aOp[2].p1 = iDb; @@ -1747,9 +1747,9 @@ void sqlite3Pragma( { OP_ResultRow, 1, 1, 0} }; VdbeOp *aOp; - sqlite3VdbeVerifyAvailableSpace(v, ArraySize(readCookie)); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); - assert( aOp!=0 ); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p3 = iCookie; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a70b0cfb36..5d8a504f87 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -402,6 +402,21 @@ # define NEVER(X) (X) #endif +/* +** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is +** defined. We need to defend against those failures when testing with +** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches +** during a normal build. The following macro can be used to disable tests +** that are always false except when SQLITE_TEST_REALLOC_STRESS is set. +*/ +#if defined(SQLITE_TEST_REALLOC_STRESS) +# define ONLY_IF_REALLOC_STRESS(X) (X) +#elif !defined(NDEBUG) +# define ONLY_IF_REALLOC_STRESS(X) ((X)?(assert(0),1):0) +#else +# define ONLY_IF_REALLOC_STRESS(X) (0) +#endif + /* ** Declarations used for tracing the operating system interfaces. */ diff --git a/src/vdbe.h b/src/vdbe.h index a0ff16d891..f09997bf94 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -180,10 +180,10 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); -#ifdef SQLITE_DEBUG - void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N); +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) + void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); #else -# define sqlite3VdbeVerifyAvailableSpace(A,B) +# define sqlite3VdbeVerifyNoMallocRequired(A,B) #endif VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9859054ba4..492a41599b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -607,11 +607,14 @@ int sqlite3VdbeCurrentAddr(Vdbe *p){ /* ** Verify that at least N opcode slots are available in p without -** having to malloc for more space. This interface is used for -** testing only. +** having to malloc for more space (except when compiled using +** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing +** to verify that certain calls to sqlite3VdbeAddOpList() can never +** fail due to a OOM fault and hence that the return value from +** sqlite3VdbeAddOpList() will always be non-NULL. */ -#ifdef SQLITE_DEBUG -void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N){ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ assert( p->nOp + N <= p->pParse->nOpAlloc ); } #endif From e617bc8c0cad70a2237f1f9d5870d62314000831 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Jan 2016 00:46:11 +0000 Subject: [PATCH 16/29] Simplification of the VDBE bytecode for incremental blob I/O. FossilOrigin-Name: d23849f64a110e336f26282bf2b961a2a2372468 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeblob.c | 36 ++++++++++++++++++------------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 1042db4582..15c1cd6f7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sSQLITE_TEST_REALLOC_STRESS. -D 2016-01-18T00:20:26.450 +C Simplification\sof\sthe\sVDBE\sbytecode\sfor\sincremental\sblob\sI/O. +D 2016-01-18T00:46:11.199 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -413,7 +413,7 @@ F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e F src/vdbeaux.c 95e067a5e2a75e128d45ca597388dc83c58142f0 -F src/vdbeblob.c 8542f282b58293bd61c2ea4b2125f250f4fc9543 +F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 @@ -1417,7 +1417,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 61deab043dcea860070dba6b02601a7de627fff1 -R 4379f64b4cb45ea0db7a5f863224d3f6 +P 0aaf3febb00f622c5ef0853b2491d69f7ca7a21e +R 8210381425f8a73bf29afce4a64c9930 U drh -Z e0f8e155ee8f1f04cd4cfaa23a1af003 +Z 0317022cefd345ebef2be02c7eb84046 diff --git a/manifest.uuid b/manifest.uuid index 37eeb2a0f1..e7a7e7b187 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0aaf3febb00f622c5ef0853b2491d69f7ca7a21e \ No newline at end of file +d23849f64a110e336f26282bf2b961a2a2372468 \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index e5f08ce933..f9015ad6f4 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -249,19 +249,19 @@ int sqlite3_blob_open( ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ - static const int iLn = VDBE_OFFSET_LINENO(3); + static const int iLn = VDBE_OFFSET_LINENO(4); static const VdbeOpList openBlob[] = { - /* {OP_Transaction, 0, 0, 0}, // inserted separately */ - {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ - {OP_OpenRead, 0, 0, 0}, /* 1: Open cursor 0 for reading */ - {OP_OpenWrite, 0, 0, 0}, /* 2: Open cursor 0 for read/write */ - {OP_Variable, 1, 1, 1}, /* 3: Push the rowid to the stack */ - {OP_NotExists, 0, 10, 1}, /* 4: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 5 */ - {OP_ResultRow, 1, 0, 0}, /* 6 */ - {OP_Goto, 0, 4, 0}, /* 7 */ - {OP_Close, 0, 0, 0}, /* 8 */ - {OP_Halt, 0, 0, 0}, /* 9 */ + /* addr/ofst */ + /* {OP_Transaction, 0, 0, 0}, // 0/ inserted separately */ + {OP_TableLock, 0, 0, 0}, /* 1/0: Acquire a read or write lock */ + {OP_OpenRead, 0, 0, 0}, /* 2/1: Open a cursor */ + {OP_Variable, 1, 1, 0}, /* 3/2: Move ?1 into reg[1] */ + {OP_NotExists, 0, 8, 1}, /* 4/3: Seek the cursor */ + {OP_Column, 0, 0, 1}, /* 5/4 */ + {OP_ResultRow, 1, 0, 0}, /* 6/5 */ + {OP_Goto, 0, 3, 0}, /* 7/6 */ + {OP_Close, 0, 0, 0}, /* 8/7 */ + {OP_Halt, 0, 0, 0}, /* 9/8 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -292,9 +292,9 @@ int sqlite3_blob_open( /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ - aOp[2-flags].opcode = OP_Noop; - aOp[1+flags].p2 = pTab->tnum; - aOp[1+flags].p3 = iDb; + if( flags ) aOp[1].opcode = OP_OpenWrite; + aOp[1].p2 = pTab->tnum; + aOp[1].p3 = iDb; /* Configure the number of columns. Configure the cursor to ** think that the table has one more column than it really @@ -303,9 +303,9 @@ int sqlite3_blob_open( ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ - aOp[1+flags].p4type = P4_INT32; - aOp[1+flags].p4.i = pTab->nCol+1; - aOp[5].p2 = pTab->nCol; + aOp[1].p4type = P4_INT32; + aOp[1].p4.i = pTab->nCol+1; + aOp[4].p2 = pTab->nCol; pParse->nVar = 1; pParse->nMem = 1; From 0536a07c0efb1b3bf3ba3371ede382d129d1bad4 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Jan 2016 09:08:56 +0000 Subject: [PATCH 17/29] Add a debugging function to print human-readable versions of fts5 detail=none leaf pages. FossilOrigin-Name: 8358af3658d888516cdef5f8c8d89e9bdee53f91 --- ext/fts5/fts5_index.c | 98 ++++++++++++++++++++++++++++++++++ ext/fts5/test/fts5_common.tcl | 6 +++ ext/fts5/test/fts5simple2.test | 20 +++++-- manifest | 18 +++---- manifest.uuid | 2 +- 5 files changed, 130 insertions(+), 14 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index d5ea972414..3d4488aedf 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5904,6 +5904,47 @@ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ return iOff; } +/* +** This function is part of the fts5_decode() debugging function. It is +** only ever used with detail=none tables. +** +** Buffer (pData/nData) contains a doclist in the format used by detail=none +** tables. This function appends a human-readable version of that list to +** buffer pBuf. +** +** If *pRc is other than SQLITE_OK when this function is called, it is a +** no-op. If an OOM or other error occurs within this function, *pRc is +** set to an SQLite error code before returning. The final state of buffer +** pBuf is undefined in this case. +*/ +static void fts5DecodeRowidList( + int *pRc, /* IN/OUT: Error code */ + Fts5Buffer *pBuf, /* Buffer to append text to */ + const u8 *pData, int nData /* Data to decode list-of-rowids from */ +){ + int i = 0; + i64 iRowid = 0; + + while( i Date: Mon, 18 Jan 2016 13:18:54 +0000 Subject: [PATCH 18/29] Avoid unnecessary calls to memset() for a small performance improvement. FossilOrigin-Name: 9e8c23acf74944a165c733682a956948b15bd401 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 3 ++- src/expr.c | 3 ++- src/select.c | 5 +++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 0405b4eb80..17430c5423 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sdebugging\sfunction\sto\sprint\shuman-readable\sversions\sof\sfts5\sdetail=none\sleaf\spages. -D 2016-01-18T09:08:56.841 +C Avoid\sunnecessary\scalls\sto\smemset()\sfor\sa\ssmall\sperformance\simprovement. +D 2016-01-18T13:18:54.021 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -289,14 +289,14 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c d9c6b2e2df06314079aa582f12937401a62171a6 F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 59783188d873daf92150cc1a1caad55496839e8f +F src/build.c 31af80bba31ac159967951ef58f3144cc7db9d70 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da -F src/expr.c 9a1a4150864f002b633d12f170a4114c28bbe94d +F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44 F src/func.c ccaf46fa98f795673afbfab73dff7c18db88f3cd @@ -343,7 +343,7 @@ F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 08dbe0292b24abc79b0c55ea97368e8a6bd235ec F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 5b0f2aa9f73ec7b65d1711d485471854d5bad23c +F src/select.c 718954db86277d696c520fe671148db1e9c4ed3c F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1417,7 +1417,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d23849f64a110e336f26282bf2b961a2a2372468 -R 31b95f2f1604722a026be65030bac1ab -U dan -Z d8bcb32855d826aa490c728ca6c213ac +P 8358af3658d888516cdef5f8c8d89e9bdee53f91 +R c9824fbd0634badf7e3856a23bc7d527 +U drh +Z 3a50e6364ad5d43622d6dbbf0015cd45 diff --git a/manifest.uuid b/manifest.uuid index 99374d367c..f39ceaa8a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8358af3658d888516cdef5f8c8d89e9bdee53f91 \ No newline at end of file +9e8c23acf74944a165c733682a956948b15bd401 \ No newline at end of file diff --git a/src/build.c b/src/build.c index f592bb131c..f7074ab417 100644 --- a/src/build.c +++ b/src/build.c @@ -3710,9 +3710,10 @@ SrcList *sqlite3SrcListAppend( struct SrcList_item *pItem; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(SrcList) ); + pList = sqlite3DbMallocRaw(db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; + pList->nSrc = 0; } pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); if( db->mallocFailed ){ diff --git a/src/expr.c b/src/expr.c index b8cf3f7720..403e81cf34 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1135,10 +1135,11 @@ ExprList *sqlite3ExprListAppend( ){ sqlite3 *db = pParse->db; if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); + pList = sqlite3DbMallocRaw(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } + pList->nExpr = 0; pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0])); if( pList->a==0 ) goto no_mem; }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ diff --git a/src/select.c b/src/select.c index fd094d05dd..9eb6279c10 100644 --- a/src/select.c +++ b/src/select.c @@ -1005,8 +1005,8 @@ static void selectInnerLoop( ** X extra columns. */ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ - KeyInfo *p = sqlite3DbMallocZero(0, - sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1)); + int nExtra = (N+X)*(sizeof(CollSeq*)+1); + KeyInfo *p = sqlite3Malloc(sizeof(KeyInfo) + nExtra); if( p ){ p->aSortOrder = (u8*)&p->aColl[N+X]; p->nField = (u16)N; @@ -1014,6 +1014,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ p->enc = ENC(db); p->db = db; p->nRef = 1; + memset(&p[1], 0, nExtra); }else{ db->mallocFailed = 1; } From 6d3c2889ece6eddcc4df1bd4af0eef7151e4e660 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Jan 2016 17:48:28 +0000 Subject: [PATCH 19/29] Add tests for fts5. Fix a crash that can occur in fts5 if the database content is corrupted. FossilOrigin-Name: acaf426449bf6fd3140fd63141750ff69d1119a5 --- ext/fts5/fts5Int.h | 8 ++--- ext/fts5/fts5_buffer.c | 8 ++--- ext/fts5/fts5_expr.c | 2 +- ext/fts5/fts5_index.c | 8 ++--- ext/fts5/test/fts5merge2.test | 59 +++++++++++++++++++++++++++++++++++ ext/fts5/test/fts5rowid.test | 27 ++++++++++++++++ manifest | 23 +++++++------- manifest.uuid | 2 +- 8 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 ext/fts5/test/fts5merge2.test diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index ee953c399c..b2f0d6c34e 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -225,13 +225,13 @@ int sqlite3Fts5ConfigParseRank(const char*, char**, char**); typedef struct Fts5Buffer Fts5Buffer; struct Fts5Buffer { u8 *p; - int n; - int nSpace; + u32 n; + u32 nSpace; }; -int sqlite3Fts5BufferSize(int*, Fts5Buffer*, int); +int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32); void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); -void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*); +void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*); void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*); void sqlite3Fts5BufferFree(Fts5Buffer*); void sqlite3Fts5BufferZero(Fts5Buffer*); diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 8558687d8a..94591188d3 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -15,8 +15,8 @@ #include "fts5Int.h" -int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, int nByte){ - int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64; +int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ + u32 nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64; u8 *pNew; while( nNew=0 ); + assert_nc( *pRc || nData>=0 ); if( fts5BufferGrow(pRc, pBuf, nData) ) return; memcpy(&pBuf->p[pBuf->n], pData, nData); pBuf->n += nData; diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 7a433b69a0..c51ed7939c 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -834,7 +834,7 @@ static int fts5ExprTokenTest( assert( pPhrase->aTerm[0].pSynonym==0 ); rc = sqlite3Fts5IterPoslist(pIter, pColset, - (const u8**)&pPhrase->poslist.p, &pPhrase->poslist.n, &pNode->iRowid + (const u8**)&pPhrase->poslist.p, (int*)&pPhrase->poslist.n, &pNode->iRowid ); pNode->bNomatch = (pPhrase->poslist.n==0); return rc; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 3d4488aedf..fc11a23413 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6014,7 +6014,7 @@ static void fts5DecodeFunction( /* Decode any entries that occur before the first term. */ if( szLeaf Date: Tue, 19 Jan 2016 16:06:23 +0000 Subject: [PATCH 20/29] Add further fts5 tests. 100% code coverage is finally restored. FossilOrigin-Name: b914ece0d146cfc8adba4dc4e8633e14f174d6ea --- ext/fts5/test/fts5_common.tcl | 5 +++ ext/fts5/test/fts5bigtok.test | 67 ++++++++++++++++++++++++++++++++ ext/fts5/test/fts5integrity.test | 61 ++++++++++++++++++++++++++++- ext/fts5/test/fts5rowid.test | 8 +++- manifest | 17 ++++---- manifest.uuid | 2 +- 6 files changed, 148 insertions(+), 12 deletions(-) create mode 100644 ext/fts5/test/fts5bigtok.test diff --git a/ext/fts5/test/fts5_common.tcl b/ext/fts5/test/fts5_common.tcl index 4768a3a69b..e7c61af00c 100644 --- a/ext/fts5/test/fts5_common.tcl +++ b/ext/fts5/test/fts5_common.tcl @@ -15,6 +15,11 @@ if {![info exists testdir]} { } source $testdir/tester.tcl +ifcapable !fts5 { + finish_test + return +} + catch { sqlite3_fts5_may_be_corrupt 0 reset_db diff --git a/ext/fts5/test/fts5bigtok.test b/ext/fts5/test/fts5bigtok.test new file mode 100644 index 0000000000..2267be5058 --- /dev/null +++ b/ext/fts5/test/fts5bigtok.test @@ -0,0 +1,67 @@ +# 2016 Jan 19 +# +# 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 implements regression tests for SQLite library. The +# focus of this script is testing the FTS5 module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5bigtok + +proc rndterm {} { + set L [list a b c d e f g h i j k l m n o p q r s t u v w x y z] + set l [lindex $L [expr int(rand() * [llength $L])]] + string repeat $l [expr int(rand() * 5) + 60] +} + +proc rnddoc {n} { + set res [list] + for {set i 0} {$i < $n} {incr i} { + lappend res [rndterm] + } + set res +} + +foreach_detail_mode $::testprefix { + db func rnddoc rnddoc + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%); + INSERT INTO t1(t1, rank) VALUES('pgsz', 32); + CREATE VIRTUAL TABLE t1vocab USING fts5vocab(t1, row); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 ) + INSERT INTO t1 SELECT rnddoc(3) FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 ) + INSERT INTO t1 SELECT rnddoc(3) FROM s; + } + + foreach v [db eval {SELECT term FROM t1vocab}] { + set res [db eval {SELECT rowid FROM t1($v)}] + do_execsql_test 1.[string range $v 0 0] { + SELECT rowid FROM t1($v) ORDER BY rowid DESC + } [lsort -integer -decr $res] + } + + do_execsql_test 2.0 { + INSERT INTO t1(t1) VALUES('optimize'); + } + + foreach v [db eval {SELECT term FROM t1vocab}] { + set res [db eval {SELECT rowid FROM t1($v)}] + do_execsql_test 2.[string range $v 0 0] { + SELECT rowid FROM t1($v) ORDER BY rowid DESC + } [lsort -integer -decr $res] + } +} + +finish_test + + diff --git a/ext/fts5/test/fts5integrity.test b/ext/fts5/test/fts5integrity.test index 84490e0cb4..37ca9331dd 100644 --- a/ext/fts5/test/fts5integrity.test +++ b/ext/fts5/test/fts5integrity.test @@ -145,10 +145,69 @@ do_execsql_test 5.2 { INSERT INTO gg(gg) VALUES('optimize'); } -breakpoint do_execsql_test 5.3 { INSERT INTO gg(gg) VALUES('integrity-check'); } +do_test 5.4.1 { + set ok 0 + for {set i 0} {$i < 10000} {incr i} { + set T [format %.5d $i] + set res [db eval { SELECT rowid FROM gg($T) ORDER BY rowid ASC }] + set res2 [db eval { SELECT rowid FROM gg($T) ORDER BY rowid DESC }] + if {$res == [lsort -integer $res2]} { incr ok } + } + set ok +} {10000} + +do_test 5.4.2 { + set ok 0 + for {set i 0} {$i < 100} {incr i} { + set T "[format %.3d $i]*" + set res [db eval { SELECT rowid FROM gg($T) ORDER BY rowid ASC }] + set res2 [db eval { SELECT rowid FROM gg($T) ORDER BY rowid DESC }] + if {$res == [lsort -integer $res2]} { incr ok } + } + set ok +} {100} + +#------------------------------------------------------------------------- +# Similar to 5.*. +# +foreach {tn pgsz} { + 1 32 + 2 36 + 3 40 + 4 44 + 5 48 +} { + do_execsql_test 6.$tn.1 { + DROP TABLE IF EXISTS hh; + CREATE VIRTUAL TABLE hh USING fts5(y); + INSERT INTO hh(hh, rank) VALUES('pgsz', $pgsz); + + WITH s(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<999) + INSERT INTO hh SELECT printf("%.3d%.3d%.3d %.3d%.3d%.3d",i,i,i,i+1,i+1,i+1) + FROM s; + + WITH s(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<999) + INSERT INTO hh SELECT printf("%.3d%.3d%.3d %.3d%.3d%.3d",i,i,i,i+1,i+1,i+1) + FROM s; + + INSERT INTO hh(hh) VALUES('optimize'); + } + + do_test 6.$tn.2 { + set ok 0 + for {set i 0} {$i < 1000} {incr i} { + set T [format %.3d%.3d%.3d $i $i $i] + set res [db eval { SELECT rowid FROM hh($T) ORDER BY rowid ASC }] + set res2 [db eval { SELECT rowid FROM hh($T) ORDER BY rowid DESC }] + if {$res == [lsort -integer $res2]} { incr ok } + } + set ok + } {1000} +} + finish_test diff --git a/ext/fts5/test/fts5rowid.test b/ext/fts5/test/fts5rowid.test index 13a075e0bc..19590cdf0d 100644 --- a/ext/fts5/test/fts5rowid.test +++ b/ext/fts5/test/fts5rowid.test @@ -202,8 +202,12 @@ do_execsql_test 6.0 { } {32} do_execsql_test 6.1 { - DELETE FROM x5 WHERE rowid=1; - UPDATE x5 SET x='a b c d e f' WHERE rowid=2; + DELETE FROM x5 WHERE rowid <= 2; + SELECT count(fts5_decode_none(rowid, block)) FROM x5_data; +} {34} + +do_execsql_test 6.2 { + UPDATE x5 SET x='a b c d e f' WHERE rowid=3; SELECT count(fts5_decode_none(rowid, block)) FROM x5_data; } {36} diff --git a/manifest b/manifest index cdd417e773..a92d3b5535 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sfts5.\sFix\sa\scrash\sthat\scan\soccur\sin\sfts5\sif\sthe\sdatabase\scontent\sis\scorrupted. -D 2016-01-18T17:48:28.938 +C Add\sfurther\sfts5\stests.\s100%\scode\scoverage\sis\sfinally\srestored. +D 2016-01-19T16:06:23.776 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -115,7 +115,7 @@ F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 F ext/fts5/fts5_vocab.c ee6df1a3be103414d7b7af833ae1885c7b83a9d0 F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba -F ext/fts5/test/fts5_common.tcl cf6392ed5bd3e1e2c9eaff6a6409d9f0cfcc1efa +F ext/fts5/test/fts5_common.tcl 6d0d74b695c4be055a8ba1dd807f22a2abc95b5e F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test d5073ca7bd2d9fe8aab0c82c6c75a7e4b0d70ced @@ -133,6 +133,7 @@ F ext/fts5/test/fts5auto.test 401c20e89f1114d733b94809be1e6f893e16c09e F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb +F ext/fts5/test/fts5bigtok.test 981b2790f6fa02773c889bd35d42c6b97f80f0f4 F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 F ext/fts5/test/fts5config.test 83941309b94d002ed6f55d9cd814e0353c9ae013 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 @@ -156,7 +157,7 @@ F ext/fts5/test/fts5fault8.test f2d8a2b673a5f72ca1fa0e85bdbfb2041ffd347d F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5hash.test 00668f6fa9b9bffbd7c1be29f408aa2bdade0451 -F ext/fts5/test/fts5integrity.test 87db5d4e7da0ce04a1dcba5ba91658673c997a65 +F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d F ext/fts5/test/fts5matchinfo.test 86569026d20f1ed748236587ce798de8a96615f1 F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367 F ext/fts5/test/fts5merge2.test c0cb66eb38a41c26cc5848fb9e50093e0f59ac93 @@ -172,7 +173,7 @@ F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 -F ext/fts5/test/fts5rowid.test 42de27109d2f6091108bf27097b105cb7e34f492 +F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 @@ -1418,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9e8c23acf74944a165c733682a956948b15bd401 -R 08e65f545f5743a4e11b0d8939a59f80 +P acaf426449bf6fd3140fd63141750ff69d1119a5 +R d08b3552b8f27561f27085942ba60d34 U dan -Z 3083046e1d22f6a7fb73cbf36ab37bf0 +Z 7a4ceb8872d3ff383d019f72843d63a3 diff --git a/manifest.uuid b/manifest.uuid index 102b730d6e..0f9bae7512 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -acaf426449bf6fd3140fd63141750ff69d1119a5 \ No newline at end of file +b914ece0d146cfc8adba4dc4e8633e14f174d6ea \ No newline at end of file From b8763639bbef1f0f01cb83c4ac98eb9ff1827b96 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Jan 2016 17:54:21 +0000 Subject: [PATCH 21/29] Fix two harmless compiler warnings about comparisons of dangling pointers. FossilOrigin-Name: 86944f193f1f06b64471953bb5713ecea7f3d803 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- src/whereexpr.c | 4 +++- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index a92d3b5535..4f8ac4d9b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\sfts5\stests.\s100%\scode\scoverage\sis\sfinally\srestored. -D 2016-01-19T16:06:23.776 +C Fix\stwo\sharmless\scompiler\swarnings\sabout\scomparisons\sof\sdangling\spointers. +D 2016-01-19T17:54:21.554 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -414,7 +414,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 95e067a5e2a75e128d45ca597388dc83c58142f0 +F src/vdbeaux.c fcbca1519bdfe619edf2e95b64aad8e7b718494c F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -427,7 +427,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c bb69654f841ae7af0a20cc6fb8f0ac57901c31be F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a F src/wherecode.c 8dee26eb181ea9daa8b1a4d96f34c0860aaf99bd -F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c +F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P acaf426449bf6fd3140fd63141750ff69d1119a5 -R d08b3552b8f27561f27085942ba60d34 -U dan -Z 7a4ceb8872d3ff383d019f72843d63a3 +P b914ece0d146cfc8adba4dc4e8633e14f174d6ea +R 3e5d796fe259d88063a5203a70f6d659 +U drh +Z 42379f3c18aeff0e63b7fa93d55446fd diff --git a/manifest.uuid b/manifest.uuid index 0f9bae7512..5fc95f9db8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b914ece0d146cfc8adba4dc4e8633e14f174d6ea \ No newline at end of file +86944f193f1f06b64471953bb5713ecea7f3d803 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 492a41599b..7cce57a738 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3655,9 +3655,9 @@ static int vdbeCompareMemString( v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); n2 = v2==0 ? 0 : c2.n; rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); + if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM; sqlite3VdbeMemRelease(&c1); sqlite3VdbeMemRelease(&c2); - if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM; return rc; } } diff --git a/src/whereexpr.c b/src/whereexpr.c index 99a97079be..e0b8bac1b7 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -202,6 +202,7 @@ static int isLikeOrGlob( sqlite3 *db = pParse->db; /* Database connection */ sqlite3_value *pVal = 0; int op; /* Opcode of pRight */ + int rc; /* Result code to return */ if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ return 0; @@ -267,8 +268,9 @@ static int isLikeOrGlob( } } + rc = (z!=0); sqlite3ValueFree(pVal); - return (z!=0); + return rc; } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ From e40cf40c1a56dfd10b5d16db11135f5f0612a9c4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Jan 2016 21:36:26 +0000 Subject: [PATCH 22/29] Fix an incorrect VFS version number check in the threadtest3.c test program. FossilOrigin-Name: 5bf6442bec83977006bc5049adcdbd4dd39369fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/threadtest3.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4f8ac4d9b8..46e63fc992 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\sharmless\scompiler\swarnings\sabout\scomparisons\sof\sdangling\spointers. -D 2016-01-19T17:54:21.554 +C Fix\san\sincorrect\sVFS\sversion\snumber\scheck\sin\sthe\sthreadtest3.c\stest\sprogram. +D 2016-01-19T21:36:26.548 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -1084,7 +1084,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 -F test/threadtest3.c 7ca82330041456afa52e4968196bb0867371f91b +F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b914ece0d146cfc8adba4dc4e8633e14f174d6ea -R 3e5d796fe259d88063a5203a70f6d659 +P 86944f193f1f06b64471953bb5713ecea7f3d803 +R 1bd8149c5e96ca5f6729d165e7caff84 U drh -Z 42379f3c18aeff0e63b7fa93d55446fd +Z 65f48ec6556e690748ae351a1c163375 diff --git a/manifest.uuid b/manifest.uuid index 5fc95f9db8..3dd90a8dcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -86944f193f1f06b64471953bb5713ecea7f3d803 \ No newline at end of file +5bf6442bec83977006bc5049adcdbd4dd39369fe \ No newline at end of file diff --git a/test/threadtest3.c b/test/threadtest3.c index 8d213c61f1..6062b64285 100644 --- a/test/threadtest3.c +++ b/test/threadtest3.c @@ -880,7 +880,7 @@ static double currentTime(void){ double t; static sqlite3_vfs *pTimelimitVfs = 0; if( pTimelimitVfs==0 ) pTimelimitVfs = sqlite3_vfs_find(0); - if( pTimelimitVfs->iVersion>=1 && pTimelimitVfs->xCurrentTimeInt64!=0 ){ + if( pTimelimitVfs->iVersion>=2 && pTimelimitVfs->xCurrentTimeInt64!=0 ){ sqlite3_int64 tm; pTimelimitVfs->xCurrentTimeInt64(pTimelimitVfs, &tm); t = tm/86400000.0; From 36b78ee7d8d23cebaffb3d92da28adbdb94a90d3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Jan 2016 01:32:00 +0000 Subject: [PATCH 23/29] Very small simplification to the btree balancer. FossilOrigin-Name: f421adf54c9db91ba6ca64a8ba3751680e47924a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 46e63fc992..da7d7696b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\sVFS\sversion\snumber\scheck\sin\sthe\sthreadtest3.c\stest\sprogram. -D 2016-01-19T21:36:26.548 +C Very\ssmall\ssimplification\sto\sthe\sbtree\sbalancer. +D 2016-01-20T01:32:00.028 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -288,7 +288,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c d9c6b2e2df06314079aa582f12937401a62171a6 +F src/btree.c f224ae877fde69d1a9d430f502edaf8502752dbe F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 31af80bba31ac159967951ef58f3144cc7db9d70 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 86944f193f1f06b64471953bb5713ecea7f3d803 -R 1bd8149c5e96ca5f6729d165e7caff84 +P 5bf6442bec83977006bc5049adcdbd4dd39369fe +R 70eccaeca6a4cd2462229055942e9f5d U drh -Z 65f48ec6556e690748ae351a1c163375 +Z 7b4de528ceedb108b3157672b1895b78 diff --git a/manifest.uuid b/manifest.uuid index 3dd90a8dcc..804b1f705d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bf6442bec83977006bc5049adcdbd4dd39369fe \ No newline at end of file +f421adf54c9db91ba6ca64a8ba3751680e47924a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index eb0808f1d9..4e6f6478af 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7186,9 +7186,8 @@ static int balance_nonroot( ** long be able to find the cells if a pointer to each cell is not saved ** first. */ - memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*limit); + memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ - memset(&b.szCell[b.nCell+limit], 0, sizeof(b.szCell[0])*pOld->nOverflow); limit = pOld->aiOvfl[0]; for(j=0; j Date: Wed, 20 Jan 2016 01:48:25 +0000 Subject: [PATCH 24/29] During compilation, transfer the azVar[0..nzVar-1] array from Parse to Vdbe rather than copying it. Smaller and faster code. FossilOrigin-Name: 80dd495f378614e4eca72e71e43061b1b94ee450 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/vdbeaux.c | 11 +++++------ 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index da7d7696b2..2bdfa7fcdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Very\ssmall\ssimplification\sto\sthe\sbtree\sbalancer. -D 2016-01-20T01:32:00.028 +C During\scompilation,\stransfer\sthe\sazVar[0..nzVar-1]\sarray\sfrom\sParse\sto\sVdbe\nrather\sthan\scopying\sit.\s\sSmaller\sand\sfaster\scode. +D 2016-01-20T01:48:25.150 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -350,7 +350,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 8fbaf9dc2bb979865c739e5272fe0b352fbc709f +F src/sqliteInt.h 9c506d4bc748667c0ea74abd4f034124a4c9a0d1 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -414,7 +414,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c fcbca1519bdfe619edf2e95b64aad8e7b718494c +F src/vdbeaux.c f53b709c4c0d8f80e51dbf343292564e8628e217 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5bf6442bec83977006bc5049adcdbd4dd39369fe -R 70eccaeca6a4cd2462229055942e9f5d +P f421adf54c9db91ba6ca64a8ba3751680e47924a +R 0c5d0312a4aace8397299f6692596f42 U drh -Z 7b4de528ceedb108b3157672b1895b78 +Z ec44132b48754f37e54bd488e98f7a49 diff --git a/manifest.uuid b/manifest.uuid index 804b1f705d..1408be74b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f421adf54c9db91ba6ca64a8ba3751680e47924a \ No newline at end of file +80dd495f378614e4eca72e71e43061b1b94ee450 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5d8a504f87..6684953fd5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2794,7 +2794,7 @@ struct Parse { ** in the recursive region. ************************************************************************/ - int nVar; /* Number of '?' variables seen in the SQL so far */ + ynVar nVar; /* Number of '?' variables seen in the SQL so far */ int nzVar; /* Number of available slots in azVar[] */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ u8 explain; /* True if the EXPLAIN flag is found on the query */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7cce57a738..cbb707d25a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1897,7 +1897,6 @@ void sqlite3VdbeMakeReady( p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte); p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte); p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte); - p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), zCsr, &nFree, &nByte); p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), zCsr, &nFree, &nByte); p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte); @@ -1920,11 +1919,10 @@ void sqlite3VdbeMakeReady( p->aVar[n].db = db; } } - if( p->azVar && pParse->nzVar>0 ){ - p->nzVar = pParse->nzVar; - memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); - memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); - } + p->nzVar = pParse->nzVar; + p->azVar = pParse->azVar; + pParse->nzVar = 0; + pParse->azVar = 0; if( p->aMem ){ p->aMem--; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ @@ -2911,6 +2909,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, pSub); } for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); + sqlite3DbFree(db, p->azVar); vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); From 4b31bda2c5e446e6876c7e7e34c03aa676a0b7a3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Jan 2016 02:01:02 +0000 Subject: [PATCH 25/29] Remove an unnecessary memset() for a small size reduction and speed improvement. FossilOrigin-Name: 730d7efb6fef54ed7c1f4ae27e3b55778ea6ff01 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2bdfa7fcdd..712e32918e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C During\scompilation,\stransfer\sthe\sazVar[0..nzVar-1]\sarray\sfrom\sParse\sto\sVdbe\nrather\sthan\scopying\sit.\s\sSmaller\sand\sfaster\scode. -D 2016-01-20T01:48:25.150 +C Remove\san\sunnecessary\smemset()\sfor\sa\ssmall\ssize\sreduction\sand\sspeed\simprovement. +D 2016-01-20T02:01:02.932 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -414,7 +414,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c f53b709c4c0d8f80e51dbf343292564e8628e217 +F src/vdbeaux.c d34740a472662f9555c0cbb46bbfe323014ba0e5 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f421adf54c9db91ba6ca64a8ba3751680e47924a -R 0c5d0312a4aace8397299f6692596f42 +P 80dd495f378614e4eca72e71e43061b1b94ee450 +R a035637148b8d47d70dffd1e7fd4febf U drh -Z ec44132b48754f37e54bd488e98f7a49 +Z c01377a6a12f63d2df1dc07be9d35345 diff --git a/manifest.uuid b/manifest.uuid index 1408be74b1..4ea4de6797 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80dd495f378614e4eca72e71e43061b1b94ee450 \ No newline at end of file +730d7efb6fef54ed7c1f4ae27e3b55778ea6ff01 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cbb707d25a..47ac9dd9f5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -849,7 +849,7 @@ int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ assert( addr>=0 && addrnOp ); pOp = &p->aOp[addr]; freeP4(p->db, pOp->p4type, pOp->p4.p); - memset(pOp, 0, sizeof(pOp[0])); + pOp->p4type = P4_NOTUSED; pOp->opcode = OP_Noop; return 1; } From 9bfb024de09a48884c49e093ee07d2cb8e26574b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Jan 2016 02:21:50 +0000 Subject: [PATCH 26/29] Remove an unnecessary memset() from the symbol name resolver. FossilOrigin-Name: da527ddae06460ab4b706cdb871de2188ebaf5ac --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/resolve.c | 6 ++++-- src/sqliteInt.h | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 712e32918e..33c05175d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smemset()\sfor\sa\ssmall\ssize\sreduction\sand\sspeed\simprovement. -D 2016-01-20T02:01:02.932 +C Remove\san\sunnecessary\smemset()\sfrom\sthe\ssymbol\sname\sresolver. +D 2016-01-20T02:21:50.387 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -343,14 +343,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19 F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 08dbe0292b24abc79b0c55ea97368e8a6bd235ec +F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 718954db86277d696c520fe671148db1e9c4ed3c F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 9c506d4bc748667c0ea74abd4f034124a4c9a0d1 +F src/sqliteInt.h 8c1debffeeb1579bdc264d54c72c05892e23b7ee F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 80dd495f378614e4eca72e71e43061b1b94ee450 -R a035637148b8d47d70dffd1e7fd4febf +P 730d7efb6fef54ed7c1f4ae27e3b55778ea6ff01 +R 2a84d613eab09af872226a39d465de29 U drh -Z c01377a6a12f63d2df1dc07be9d35345 +Z a3f73fee0434b592305d171cd50a9012 diff --git a/manifest.uuid b/manifest.uuid index 4ea4de6797..8dcaaee610 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -730d7efb6fef54ed7c1f4ae27e3b55778ea6ff01 \ No newline at end of file +da527ddae06460ab4b706cdb871de2188ebaf5ac \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 97cb6556ac..81bb712a2e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1393,10 +1393,12 @@ int sqlite3ResolveExprNames( #endif savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); - memset(&w, 0, sizeof(w)); + w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; - w.pParse = pNC->pParse; + w.xSelectCallback2 = 0; + w.walkerDepth = 0; + w.eCode = 0; w.u.pNC = pNC; sqlite3WalkExpr(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6684953fd5..8ab59b4679 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3076,10 +3076,10 @@ struct Sqlite3Config { ** Context pointer passed down through the tree-walk. */ struct Walker { + Parse *pParse; /* Parser context. */ int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ - Parse *pParse; /* Parser context. */ int walkerDepth; /* Number of subqueries */ u8 eCode; /* A small processing code */ union { /* Extra data for callback */ From 939e778bc86722fed16a6d85771e4b1794b8e81a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Jan 2016 02:36:12 +0000 Subject: [PATCH 27/29] Suppress the display of the P4 operand in EXPLAIN output when an opcode has been converted into a No-op. FossilOrigin-Name: 9f8297f862a110ded686d091854fae20c6bc393c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 33c05175d0..c246f07bd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smemset()\sfrom\sthe\ssymbol\sname\sresolver. -D 2016-01-20T02:21:50.387 +C Suppress\sthe\sdisplay\sof\sthe\sP4\soperand\sin\sEXPLAIN\soutput\swhen\san\sopcode\nhas\sbeen\sconverted\sinto\sa\sNo-op. +D 2016-01-20T02:36:12.461 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -414,7 +414,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c d34740a472662f9555c0cbb46bbfe323014ba0e5 +F src/vdbeaux.c db67d3e0fcedced22bfeca47a567eb9df91b3495 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 730d7efb6fef54ed7c1f4ae27e3b55778ea6ff01 -R 2a84d613eab09af872226a39d465de29 +P da527ddae06460ab4b706cdb871de2188ebaf5ac +R 9c350206cbc3ec71bedbf771eaad6af4 U drh -Z a3f73fee0434b592305d171cd50a9012 +Z d3ee680a30750cc9b6d539ba48a1436a diff --git a/manifest.uuid b/manifest.uuid index 8dcaaee610..4615528f3e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da527ddae06460ab4b706cdb871de2188ebaf5ac \ No newline at end of file +9f8297f862a110ded686d091854fae20c6bc393c \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 47ac9dd9f5..d88fbac611 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -850,6 +850,7 @@ int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ pOp = &p->aOp[addr]; freeP4(p->db, pOp->p4type, pOp->p4.p); pOp->p4type = P4_NOTUSED; + pOp->p4.z = 0; pOp->opcode = OP_Noop; return 1; } From 1da26a48ddec0a3dbe8a99464f5171c0cb0354a7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Jan 2016 03:36:32 +0000 Subject: [PATCH 28/29] Performance improvement in sqlite3DbMallocRaw(). FossilOrigin-Name: ff8eadbed5004ab03438f737492387dee6b9750a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 12 ++++++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c246f07bd4..7ce89fb2c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Suppress\sthe\sdisplay\sof\sthe\sP4\soperand\sin\sEXPLAIN\soutput\swhen\san\sopcode\nhas\sbeen\sconverted\sinto\sa\sNo-op. -D 2016-01-20T02:36:12.461 +C Performance\simprovement\sin\ssqlite3DbMallocRaw(). +D 2016-01-20T03:36:32.428 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -311,7 +311,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b F src/main.c b686dabe9a7ece9121da87120d5c7bf402d77eb3 -F src/malloc.c 8f787669e79de26efc42272b5797bc00fff527c6 +F src/malloc.c b67c26c359c13836d370350b3f43d228dff5b360 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P da527ddae06460ab4b706cdb871de2188ebaf5ac -R 9c350206cbc3ec71bedbf771eaad6af4 +P 9f8297f862a110ded686d091854fae20c6bc393c +R 90386a9e726561832778abc9155cd93d U drh -Z d3ee680a30750cc9b6d539ba48a1436a +Z 2aa4bf87eb3a329408d2351dd05edc2d diff --git a/manifest.uuid b/manifest.uuid index 4615528f3e..50bb5b1795 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f8297f862a110ded686d091854fae20c6bc393c \ No newline at end of file +ff8eadbed5004ab03438f737492387dee6b9750a \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 2c493b9320..c8a04128cf 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -583,8 +583,9 @@ void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ } /* -** Allocate and zero memory. If the allocation fails, make -** the mallocFailed flag in the connection pointer. +** Allocate memory, either lookaside (if possible) or heap. +** If the allocation fails, set the mallocFailed flag in +** the connection pointer. ** ** If db!=0 and db->mallocFailed is true (indicating a prior malloc ** failure on the same database connection) then always return 0. @@ -600,8 +601,8 @@ void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed ** that all prior mallocs (ex: "a") worked too. */ +static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n); void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ - void *p; assert( db==0 || sqlite3_mutex_held(db->mutex) ); assert( db==0 || db->pnBytesFreed==0 ); #ifndef SQLITE_OMIT_LOOKASIDE @@ -631,7 +632,10 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ return 0; } #endif - p = sqlite3Malloc(n); + return dbMallocRawFinish(db, n); +} +static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ + void *p = sqlite3Malloc(n); if( !p && db ){ db->mallocFailed = 1; } From 5c3aa0517ed8a837e4d70cacbaca5d9e267e0fc3 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 20 Jan 2016 08:47:55 +0000 Subject: [PATCH 29/29] Improve performance of sqlite3VtabImportErrmsg(). FossilOrigin-Name: 18d61c8e40ed1466b6a3a2f53bf0eeb09687c20e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 12 +++++++----- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7ce89fb2c7..1c1653b60a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sin\ssqlite3DbMallocRaw(). -D 2016-01-20T03:36:32.428 +C Improve\sperformance\sof\ssqlite3VtabImportErrmsg(). +D 2016-01-20T08:47:55.546 F Makefile.in a476545d0c8626224d0bacac85c6e2967474af81 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 01e855f958932d0d3ed62ec675fc63e2cef61fcb @@ -414,7 +414,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c db67d3e0fcedced22bfeca47a567eb9df91b3495 +F src/vdbeaux.c 07f8f485a6cbc0a62da660f14e303061d45d5cb6 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -1419,7 +1419,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9f8297f862a110ded686d091854fae20c6bc393c -R 90386a9e726561832778abc9155cd93d -U drh -Z 2aa4bf87eb3a329408d2351dd05edc2d +P ff8eadbed5004ab03438f737492387dee6b9750a +R 9def3e1e6201afa0dc73a868079c61c0 +U dan +Z 16223910bb7e7f6f85293111cf2f150d diff --git a/manifest.uuid b/manifest.uuid index 50bb5b1795..eacc6db990 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff8eadbed5004ab03438f737492387dee6b9750a \ No newline at end of file +18d61c8e40ed1466b6a3a2f53bf0eeb09687c20e \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d88fbac611..17f1cb7dc4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4445,10 +4445,12 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ ** in memory obtained from sqlite3DbMalloc). */ void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ - sqlite3 *db = p->db; - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); - sqlite3_free(pVtab->zErrMsg); - pVtab->zErrMsg = 0; + if( pVtab->zErrMsg ){ + sqlite3 *db = p->db; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; + } } #endif /* SQLITE_OMIT_VIRTUALTABLE */