| | @@ -452,11 +452,11 @@ |
| 452 | 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | 453 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | 454 | */ |
| 455 | 455 | #define SQLITE_VERSION "3.37.0" |
| 456 | 456 | #define SQLITE_VERSION_NUMBER 3037000 |
| 457 | | -#define SQLITE_SOURCE_ID "2021-10-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813" |
| 457 | +#define SQLITE_SOURCE_ID "2021-10-06 10:36:56 566e6974892ebd3d3de8d77b24655257a5efe14434c553e1a25fc680b201b336" |
| 458 | 458 | |
| 459 | 459 | /* |
| 460 | 460 | ** CAPI3REF: Run-Time Library Version Numbers |
| 461 | 461 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 462 | 462 | ** |
| | @@ -13194,10 +13194,18 @@ |
| 13194 | 13194 | # define VVA_ONLY(X) X |
| 13195 | 13195 | #else |
| 13196 | 13196 | # define VVA_ONLY(X) |
| 13197 | 13197 | #endif |
| 13198 | 13198 | |
| 13199 | +/* |
| 13200 | +** Disable ALWAYS() and NEVER() (make them pass-throughs) for coverage |
| 13201 | +** and mutation testing |
| 13202 | +*/ |
| 13203 | +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
| 13204 | +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
| 13205 | +#endif |
| 13206 | + |
| 13199 | 13207 | /* |
| 13200 | 13208 | ** The ALWAYS and NEVER macros surround boolean expressions which |
| 13201 | 13209 | ** are intended to always be true or false, respectively. Such |
| 13202 | 13210 | ** expressions could be omitted from the code completely. But they |
| 13203 | 13211 | ** are included in a few cases in order to enhance the resilience |
| | @@ -13209,11 +13217,11 @@ |
| 13209 | 13217 | ** |
| 13210 | 13218 | ** When doing coverage testing ALWAYS and NEVER are hard-coded to |
| 13211 | 13219 | ** be true and false so that the unreachable code they specify will |
| 13212 | 13220 | ** not be counted as untested code. |
| 13213 | 13221 | */ |
| 13214 | | -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
| 13222 | +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
| 13215 | 13223 | # define ALWAYS(X) (1) |
| 13216 | 13224 | # define NEVER(X) (0) |
| 13217 | 13225 | #elif !defined(NDEBUG) |
| 13218 | 13226 | # define ALWAYS(X) ((X)?1:(assert(0),0)) |
| 13219 | 13227 | # define NEVER(X) ((X)?(assert(0),1):0) |
| | @@ -23573,11 +23581,11 @@ |
| 23573 | 23581 | |
| 23574 | 23582 | computeJD(&x); |
| 23575 | 23583 | computeYMD_HMS(&x); |
| 23576 | 23584 | for(i=j=0; zFmt[i]; i++){ |
| 23577 | 23585 | if( zFmt[i]!='%' ) continue; |
| 23578 | | - if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j); |
| 23586 | + if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j)); |
| 23579 | 23587 | i++; |
| 23580 | 23588 | j = i + 1; |
| 23581 | 23589 | switch( zFmt[i] ){ |
| 23582 | 23590 | case 'd': { |
| 23583 | 23591 | sqlite3_str_appendf(&sRes, "%02d", x.D); |
| | @@ -23649,11 +23657,11 @@ |
| 23649 | 23657 | sqlite3_str_reset(&sRes); |
| 23650 | 23658 | return; |
| 23651 | 23659 | } |
| 23652 | 23660 | } |
| 23653 | 23661 | } |
| 23654 | | - if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j); |
| 23662 | + if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j)); |
| 23655 | 23663 | sqlite3ResultStrAccum(context, &sRes); |
| 23656 | 23664 | } |
| 23657 | 23665 | |
| 23658 | 23666 | /* |
| 23659 | 23667 | ** current_time() |
| | @@ -49576,11 +49584,11 @@ |
| 49576 | 49584 | /* NULL pBitvec tests */ |
| 49577 | 49585 | sqlite3BitvecSet(0, 1); |
| 49578 | 49586 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 49579 | 49587 | |
| 49580 | 49588 | /* Run the program */ |
| 49581 | | - pc = 0; |
| 49589 | + pc = i = 0; |
| 49582 | 49590 | while( (op = aOp[pc])!=0 ){ |
| 49583 | 49591 | switch( op ){ |
| 49584 | 49592 | case 1: |
| 49585 | 49593 | case 2: |
| 49586 | 49594 | case 5: { |
| | @@ -55500,10 +55508,11 @@ |
| 55500 | 55508 | ** routine which only updates the change-counter if the update is actually |
| 55501 | 55509 | ** needed, as determined by the pPager->changeCountDone state variable. |
| 55502 | 55510 | */ |
| 55503 | 55511 | static void pager_write_changecounter(PgHdr *pPg){ |
| 55504 | 55512 | u32 change_counter; |
| 55513 | + if( NEVER(pPg==0) ) return; |
| 55505 | 55514 | |
| 55506 | 55515 | /* Increment the value just read and write it back to byte 24. */ |
| 55507 | 55516 | change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; |
| 55508 | 55517 | put32bits(((char*)pPg->pData)+24, change_counter); |
| 55509 | 55518 | |
| | @@ -68477,11 +68486,10 @@ |
| 68477 | 68486 | static int lockBtree(BtShared *pBt){ |
| 68478 | 68487 | int rc; /* Result code from subfunctions */ |
| 68479 | 68488 | MemPage *pPage1; /* Page 1 of the database file */ |
| 68480 | 68489 | u32 nPage; /* Number of pages in the database */ |
| 68481 | 68490 | u32 nPageFile = 0; /* Number of pages in the database file */ |
| 68482 | | - u32 nPageHeader; /* Number of pages in the database according to hdr */ |
| 68483 | 68491 | |
| 68484 | 68492 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 68485 | 68493 | assert( pBt->pPage1==0 ); |
| 68486 | 68494 | rc = sqlite3PagerSharedLock(pBt->pPager); |
| 68487 | 68495 | if( rc!=SQLITE_OK ) return rc; |
| | @@ -68489,11 +68497,11 @@ |
| 68489 | 68497 | if( rc!=SQLITE_OK ) return rc; |
| 68490 | 68498 | |
| 68491 | 68499 | /* Do some checking to help insure the file we opened really is |
| 68492 | 68500 | ** a valid database file. |
| 68493 | 68501 | */ |
| 68494 | | - nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); |
| 68502 | + nPage = get4byte(28+(u8*)pPage1->aData); |
| 68495 | 68503 | sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); |
| 68496 | 68504 | if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ |
| 68497 | 68505 | nPage = nPageFile; |
| 68498 | 68506 | } |
| 68499 | 68507 | if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){ |
| | @@ -73069,15 +73077,14 @@ |
| 73069 | 73077 | Pgno pgno; /* Temp var to store a page number in */ |
| 73070 | 73078 | u8 abDone[NB+2]; /* True after i'th new page is populated */ |
| 73071 | 73079 | Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ |
| 73072 | 73080 | Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ |
| 73073 | 73081 | u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ |
| 73074 | | - CellArray b; /* Parsed information on cells being balanced */ |
| 73082 | + CellArray b; /* Parsed information on cells being balanced */ |
| 73075 | 73083 | |
| 73076 | 73084 | memset(abDone, 0, sizeof(abDone)); |
| 73077 | | - b.nCell = 0; |
| 73078 | | - b.apCell = 0; |
| 73085 | + memset(&b, 0, sizeof(b)); |
| 73079 | 73086 | pBt = pParent->pBt; |
| 73080 | 73087 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 73081 | 73088 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| 73082 | 73089 | |
| 73083 | 73090 | /* At this point pParent may have at most one overflow cell. And if |
| | @@ -73884,11 +73891,11 @@ |
| 73884 | 73891 | |
| 73885 | 73892 | /* |
| 73886 | 73893 | ** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid |
| 73887 | 73894 | ** on the same B-tree as pCur. |
| 73888 | 73895 | ** |
| 73889 | | -** This can if a database is corrupt with two or more SQL tables |
| 73896 | +** This can occur if a database is corrupt with two or more SQL tables |
| 73890 | 73897 | ** pointing to the same b-tree. If an insert occurs on one SQL table |
| 73891 | 73898 | ** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL |
| 73892 | 73899 | ** table linked to the same b-tree. If the secondary insert causes a |
| 73893 | 73900 | ** rebalance, that can change content out from under the cursor on the |
| 73894 | 73901 | ** first SQL table, violating invariants on the first insert. |
| | @@ -77209,10 +77216,11 @@ |
| 77209 | 77216 | */ |
| 77210 | 77217 | SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ |
| 77211 | 77218 | #ifndef SQLITE_OMIT_UTF16 |
| 77212 | 77219 | int rc; |
| 77213 | 77220 | #endif |
| 77221 | + assert( pMem!=0 ); |
| 77214 | 77222 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 77215 | 77223 | assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE |
| 77216 | 77224 | || desiredEnc==SQLITE_UTF16BE ); |
| 77217 | 77225 | if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ |
| 77218 | 77226 | return SQLITE_OK; |
| | @@ -77341,10 +77349,11 @@ |
| 77341 | 77349 | ** MEM.zMalloc, where it can be safely written. |
| 77342 | 77350 | ** |
| 77343 | 77351 | ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. |
| 77344 | 77352 | */ |
| 77345 | 77353 | SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ |
| 77354 | + assert( pMem!=0 ); |
| 77346 | 77355 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77347 | 77356 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 77348 | 77357 | if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ |
| 77349 | 77358 | if( ExpandBlob(pMem) ) return SQLITE_NOMEM; |
| 77350 | 77359 | if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ |
| | @@ -77365,10 +77374,11 @@ |
| 77365 | 77374 | ** blob stored in dynamically allocated space. |
| 77366 | 77375 | */ |
| 77367 | 77376 | #ifndef SQLITE_OMIT_INCRBLOB |
| 77368 | 77377 | SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ |
| 77369 | 77378 | int nByte; |
| 77379 | + assert( pMem!=0 ); |
| 77370 | 77380 | assert( pMem->flags & MEM_Zero ); |
| 77371 | 77381 | assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) ); |
| 77372 | 77382 | testcase( sqlite3_value_nochange(pMem) ); |
| 77373 | 77383 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 77374 | 77384 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| | @@ -77392,10 +77402,11 @@ |
| 77392 | 77402 | |
| 77393 | 77403 | /* |
| 77394 | 77404 | ** Make sure the given Mem is \u0000 terminated. |
| 77395 | 77405 | */ |
| 77396 | 77406 | SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ |
| 77407 | + assert( pMem!=0 ); |
| 77397 | 77408 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77398 | 77409 | testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); |
| 77399 | 77410 | testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); |
| 77400 | 77411 | if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ |
| 77401 | 77412 | return SQLITE_OK; /* Nothing to do */ |
| | @@ -77419,10 +77430,11 @@ |
| 77419 | 77430 | ** user and the latter is an internal programming error. |
| 77420 | 77431 | */ |
| 77421 | 77432 | SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ |
| 77422 | 77433 | const int nByte = 32; |
| 77423 | 77434 | |
| 77435 | + assert( pMem!=0 ); |
| 77424 | 77436 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77425 | 77437 | assert( !(pMem->flags&MEM_Zero) ); |
| 77426 | 77438 | assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); |
| 77427 | 77439 | assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) ); |
| 77428 | 77440 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| | @@ -77454,10 +77466,11 @@ |
| 77454 | 77466 | */ |
| 77455 | 77467 | SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ |
| 77456 | 77468 | sqlite3_context ctx; |
| 77457 | 77469 | Mem t; |
| 77458 | 77470 | assert( pFunc!=0 ); |
| 77471 | + assert( pMem!=0 ); |
| 77459 | 77472 | assert( pFunc->xFinalize!=0 ); |
| 77460 | 77473 | assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); |
| 77461 | 77474 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77462 | 77475 | memset(&ctx, 0, sizeof(ctx)); |
| 77463 | 77476 | memset(&t, 0, sizeof(t)); |
| | @@ -77604,10 +77617,11 @@ |
| 77604 | 77617 | sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); |
| 77605 | 77618 | return value; |
| 77606 | 77619 | } |
| 77607 | 77620 | SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ |
| 77608 | 77621 | int flags; |
| 77622 | + assert( pMem!=0 ); |
| 77609 | 77623 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77610 | 77624 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 77611 | 77625 | flags = pMem->flags; |
| 77612 | 77626 | if( flags & (MEM_Int|MEM_IntReal) ){ |
| 77613 | 77627 | testcase( flags & MEM_IntReal ); |
| | @@ -77632,10 +77646,11 @@ |
| 77632 | 77646 | double val = (double)0; |
| 77633 | 77647 | sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); |
| 77634 | 77648 | return val; |
| 77635 | 77649 | } |
| 77636 | 77650 | SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ |
| 77651 | + assert( pMem!=0 ); |
| 77637 | 77652 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77638 | 77653 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 77639 | 77654 | if( pMem->flags & MEM_Real ){ |
| 77640 | 77655 | return pMem->u.r; |
| 77641 | 77656 | }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ |
| | @@ -77664,10 +77679,11 @@ |
| 77664 | 77679 | ** The MEM structure is already a MEM_Real. Try to also make it a |
| 77665 | 77680 | ** MEM_Int if we can. |
| 77666 | 77681 | */ |
| 77667 | 77682 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ |
| 77668 | 77683 | i64 ix; |
| 77684 | + assert( pMem!=0 ); |
| 77669 | 77685 | assert( pMem->flags & MEM_Real ); |
| 77670 | 77686 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 77671 | 77687 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77672 | 77688 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 77673 | 77689 | |
| | @@ -77691,10 +77707,11 @@ |
| 77691 | 77707 | |
| 77692 | 77708 | /* |
| 77693 | 77709 | ** Convert pMem to type integer. Invalidate any prior representations. |
| 77694 | 77710 | */ |
| 77695 | 77711 | SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ |
| 77712 | + assert( pMem!=0 ); |
| 77696 | 77713 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77697 | 77714 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 77698 | 77715 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 77699 | 77716 | |
| 77700 | 77717 | pMem->u.i = sqlite3VdbeIntValue(pMem); |
| | @@ -77705,10 +77722,11 @@ |
| 77705 | 77722 | /* |
| 77706 | 77723 | ** Convert pMem so that it is of type MEM_Real. |
| 77707 | 77724 | ** Invalidate any prior representations. |
| 77708 | 77725 | */ |
| 77709 | 77726 | SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ |
| 77727 | + assert( pMem!=0 ); |
| 77710 | 77728 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 77711 | 77729 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 77712 | 77730 | |
| 77713 | 77731 | pMem->u.r = sqlite3VdbeRealValue(pMem); |
| 77714 | 77732 | MemSetTypeFlag(pMem, MEM_Real); |
| | @@ -77738,10 +77756,11 @@ |
| 77738 | 77756 | ** Every effort is made to force the conversion, even if the input |
| 77739 | 77757 | ** is a string that does not look completely like a number. Convert |
| 77740 | 77758 | ** as much of the string as we can and ignore the rest. |
| 77741 | 77759 | */ |
| 77742 | 77760 | SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ |
| 77761 | + assert( pMem!=0 ); |
| 77743 | 77762 | testcase( pMem->flags & MEM_Int ); |
| 77744 | 77763 | testcase( pMem->flags & MEM_Real ); |
| 77745 | 77764 | testcase( pMem->flags & MEM_IntReal ); |
| 77746 | 77765 | testcase( pMem->flags & MEM_Null ); |
| 77747 | 77766 | if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ |
| | @@ -78089,10 +78108,11 @@ |
| 78089 | 78108 | ){ |
| 78090 | 78109 | i64 nByte = n; /* New value for pMem->n */ |
| 78091 | 78110 | int iLimit; /* Maximum allowed string or blob size */ |
| 78092 | 78111 | u16 flags = 0; /* New value for pMem->flags */ |
| 78093 | 78112 | |
| 78113 | + assert( pMem!=0 ); |
| 78094 | 78114 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 78095 | 78115 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 78096 | 78116 | |
| 78097 | 78117 | /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ |
| 78098 | 78118 | if( !z ){ |
| | @@ -79162,12 +79182,14 @@ |
| 79162 | 79182 | assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); |
| 79163 | 79183 | assert( op>=0 && op<0xff ); |
| 79164 | 79184 | if( p->nOpAlloc<=i ){ |
| 79165 | 79185 | return growOp3(p, op, p1, p2, p3); |
| 79166 | 79186 | } |
| 79187 | + assert( p->aOp!=0 ); |
| 79167 | 79188 | p->nOp++; |
| 79168 | 79189 | pOp = &p->aOp[i]; |
| 79190 | + assert( pOp!=0 ); |
| 79169 | 79191 | pOp->opcode = (u8)op; |
| 79170 | 79192 | pOp->p5 = 0; |
| 79171 | 79193 | pOp->p1 = p1; |
| 79172 | 79194 | pOp->p2 = p2; |
| 79173 | 79195 | pOp->p3 = p3; |
| | @@ -80406,11 +80428,11 @@ |
| 80406 | 80428 | zOpName = sqlite3OpcodeName(pOp->opcode); |
| 80407 | 80429 | nOpName = sqlite3Strlen30(zOpName); |
| 80408 | 80430 | if( zOpName[nOpName+1] ){ |
| 80409 | 80431 | int seenCom = 0; |
| 80410 | 80432 | char c; |
| 80411 | | - zSynopsis = zOpName += nOpName + 1; |
| 80433 | + zSynopsis = zOpName + nOpName + 1; |
| 80412 | 80434 | if( strncmp(zSynopsis,"IF ",3)==0 ){ |
| 80413 | 80435 | sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); |
| 80414 | 80436 | zSynopsis = zAlt; |
| 80415 | 80437 | } |
| 80416 | 80438 | for(ii=0; (c = zSynopsis[ii])!=0; ii++){ |
| | @@ -91677,11 +91699,11 @@ |
| 91677 | 91699 | zDb = db->aDb[pC->iDb].zDbSName; |
| 91678 | 91700 | pTab = pOp->p4.pTab; |
| 91679 | 91701 | assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); |
| 91680 | 91702 | }else{ |
| 91681 | 91703 | pTab = 0; |
| 91682 | | - zDb = 0; /* Not needed. Silence a compiler warning. */ |
| 91704 | + zDb = 0; |
| 91683 | 91705 | } |
| 91684 | 91706 | |
| 91685 | 91707 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 91686 | 91708 | /* Invoke the pre-update hook, if any */ |
| 91687 | 91709 | if( pTab ){ |
| | @@ -91830,17 +91852,18 @@ |
| 91830 | 91852 | pTab = pOp->p4.pTab; |
| 91831 | 91853 | if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ |
| 91832 | 91854 | pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); |
| 91833 | 91855 | } |
| 91834 | 91856 | }else{ |
| 91835 | | - zDb = 0; /* Not needed. Silence a compiler warning. */ |
| 91836 | | - pTab = 0; /* Not needed. Silence a compiler warning. */ |
| 91857 | + zDb = 0; |
| 91858 | + pTab = 0; |
| 91837 | 91859 | } |
| 91838 | 91860 | |
| 91839 | 91861 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 91840 | 91862 | /* Invoke the pre-update-hook if required. */ |
| 91841 | | - if( db->xPreUpdateCallback && pOp->p4.pTab ){ |
| 91863 | + assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab ); |
| 91864 | + if( db->xPreUpdateCallback && pTab ){ |
| 91842 | 91865 | assert( !(opflags & OPFLAG_ISUPDATE) |
| 91843 | 91866 | || HasRowid(pTab)==0 |
| 91844 | 91867 | || (aMem[pOp->p3].flags & MEM_Int) |
| 91845 | 91868 | ); |
| 91846 | 91869 | sqlite3VdbePreUpdateHook(p, pC, |
| | @@ -91877,11 +91900,11 @@ |
| 91877 | 91900 | if( rc ) goto abort_due_to_error; |
| 91878 | 91901 | |
| 91879 | 91902 | /* Invoke the update-hook if required. */ |
| 91880 | 91903 | if( opflags & OPFLAG_NCHANGE ){ |
| 91881 | 91904 | p->nChange++; |
| 91882 | | - if( db->xUpdateCallback && HasRowid(pTab) ){ |
| 91905 | + if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){ |
| 91883 | 91906 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, |
| 91884 | 91907 | pC->movetoTarget); |
| 91885 | 91908 | assert( pC->iDb>=0 ); |
| 91886 | 91909 | } |
| 91887 | 91910 | } |
| | @@ -103680,13 +103703,13 @@ |
| 103680 | 103703 | case TK_UPLUS: { |
| 103681 | 103704 | rc = sqlite3ExprIsInteger(p->pLeft, pValue); |
| 103682 | 103705 | break; |
| 103683 | 103706 | } |
| 103684 | 103707 | case TK_UMINUS: { |
| 103685 | | - int v; |
| 103708 | + int v = 0; |
| 103686 | 103709 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ |
| 103687 | | - assert( v!=(-2147483647-1) ); |
| 103710 | + assert( ((unsigned int)v)!=0x80000000 ); |
| 103688 | 103711 | *pValue = -v; |
| 103689 | 103712 | rc = 1; |
| 103690 | 103713 | } |
| 103691 | 103714 | break; |
| 103692 | 103715 | } |
| | @@ -105692,11 +105715,11 @@ |
| 105692 | 105715 | if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 105693 | 105716 | if( !pColl ) pColl = db->pDfltColl; |
| 105694 | 105717 | sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); |
| 105695 | 105718 | } |
| 105696 | 105719 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC |
| 105697 | | - if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){ |
| 105720 | + if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){ |
| 105698 | 105721 | Expr *pArg = pFarg->a[0].pExpr; |
| 105699 | 105722 | if( pArg->op==TK_COLUMN ){ |
| 105700 | 105723 | sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); |
| 105701 | 105724 | }else{ |
| 105702 | 105725 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); |
| | @@ -112049,13 +112072,13 @@ |
| 112049 | 112072 | if( pParse->nErr ) goto attach_end; |
| 112050 | 112073 | memset(&sName, 0, sizeof(NameContext)); |
| 112051 | 112074 | sName.pParse = pParse; |
| 112052 | 112075 | |
| 112053 | 112076 | if( |
| 112054 | | - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || |
| 112055 | | - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || |
| 112056 | | - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) |
| 112077 | + SQLITE_OK!=resolveAttachExpr(&sName, pFilename) || |
| 112078 | + SQLITE_OK!=resolveAttachExpr(&sName, pDbname) || |
| 112079 | + SQLITE_OK!=resolveAttachExpr(&sName, pKey) |
| 112057 | 112080 | ){ |
| 112058 | 112081 | goto attach_end; |
| 112059 | 112082 | } |
| 112060 | 112083 | |
| 112061 | 112084 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| | @@ -128871,11 +128894,11 @@ |
| 128871 | 128894 | /* iArg: */ 0 }, |
| 128872 | 128895 | {/* zName: */ "table_list", |
| 128873 | 128896 | /* ePragTyp: */ PragTyp_TABLE_LIST, |
| 128874 | 128897 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, |
| 128875 | 128898 | /* ColNames: */ 15, 6, |
| 128876 | | - /* iArg: */ 1 }, |
| 128899 | + /* iArg: */ 0 }, |
| 128877 | 128900 | {/* zName: */ "table_xinfo", |
| 128878 | 128901 | /* ePragTyp: */ PragTyp_TABLE_INFO, |
| 128879 | 128902 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 128880 | 128903 | /* ColNames: */ 8, 7, |
| 128881 | 128904 | /* iArg: */ 1 }, |
| | @@ -134994,11 +135017,11 @@ |
| 134994 | 135017 | ** function is responsible for ensuring that this structure is eventually |
| 134995 | 135018 | ** freed. |
| 134996 | 135019 | */ |
| 134997 | 135020 | static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ |
| 134998 | 135021 | ExprList *pOrderBy = p->pOrderBy; |
| 134999 | | - int nOrderBy = p->pOrderBy->nExpr; |
| 135022 | + int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0; |
| 135000 | 135023 | sqlite3 *db = pParse->db; |
| 135001 | 135024 | KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); |
| 135002 | 135025 | if( pRet ){ |
| 135003 | 135026 | int i; |
| 135004 | 135027 | for(i=0; i<nOrderBy; i++){ |
| | @@ -135615,10 +135638,11 @@ |
| 135615 | 135638 | Select *pLoop; /* For looping through SELECT statements */ |
| 135616 | 135639 | CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ |
| 135617 | 135640 | int nCol; /* Number of columns in result set */ |
| 135618 | 135641 | |
| 135619 | 135642 | assert( p->pNext==0 ); |
| 135643 | + assert( p->pEList!=0 ); |
| 135620 | 135644 | nCol = p->pEList->nExpr; |
| 135621 | 135645 | pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); |
| 135622 | 135646 | if( !pKeyInfo ){ |
| 135623 | 135647 | rc = SQLITE_NOMEM_BKPT; |
| 135624 | 135648 | goto multi_select_end; |
| | @@ -135966,10 +135990,11 @@ |
| 135966 | 135990 | */ |
| 135967 | 135991 | if( op!=TK_ALL ){ |
| 135968 | 135992 | for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ |
| 135969 | 135993 | struct ExprList_item *pItem; |
| 135970 | 135994 | for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){ |
| 135995 | + assert( pItem!=0 ); |
| 135971 | 135996 | assert( pItem->u.x.iOrderByCol>0 ); |
| 135972 | 135997 | if( pItem->u.x.iOrderByCol==i ) break; |
| 135973 | 135998 | } |
| 135974 | 135999 | if( j==nOrderBy ){ |
| 135975 | 136000 | Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); |
| | @@ -135992,10 +136017,11 @@ |
| 135992 | 136017 | aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1)); |
| 135993 | 136018 | if( aPermute ){ |
| 135994 | 136019 | struct ExprList_item *pItem; |
| 135995 | 136020 | aPermute[0] = nOrderBy; |
| 135996 | 136021 | for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ |
| 136022 | + assert( pItem!=0 ); |
| 135997 | 136023 | assert( pItem->u.x.iOrderByCol>0 ); |
| 135998 | 136024 | assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); |
| 135999 | 136025 | aPermute[i] = pItem->u.x.iOrderByCol - 1; |
| 136000 | 136026 | } |
| 136001 | 136027 | pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); |
| | @@ -146974,11 +147000,11 @@ |
| 146974 | 147000 | x.pWInfo = pWInfo; |
| 146975 | 147001 | x.db = pWInfo->pParse->db; |
| 146976 | 147002 | for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){ |
| 146977 | 147003 | i16 iRef = pIdx->aiColumn[iIdxCol]; |
| 146978 | 147004 | if( iRef==XN_EXPR ){ |
| 146979 | | - assert( aColExpr->a[iIdxCol].pExpr!=0 ); |
| 147005 | + assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 ); |
| 146980 | 147006 | x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; |
| 146981 | 147007 | if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; |
| 146982 | 147008 | w.xExprCallback = whereIndexExprTransNode; |
| 146983 | 147009 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS |
| 146984 | 147010 | }else if( iRef>=0 |
| | @@ -150214,11 +150240,12 @@ |
| 150214 | 150240 | if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ |
| 150215 | 150241 | continue; |
| 150216 | 150242 | } |
| 150217 | 150243 | } |
| 150218 | 150244 | if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0 |
| 150219 | | - && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN |
| 150245 | + && (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0)) |
| 150246 | + && pX->op==TK_COLUMN |
| 150220 | 150247 | && pX->iTable==pScan->aiCur[0] |
| 150221 | 150248 | && pX->iColumn==pScan->aiColumn[0] |
| 150222 | 150249 | ){ |
| 150223 | 150250 | testcase( pTerm->eOperator & WO_IS ); |
| 150224 | 150251 | continue; |
| | @@ -153969,11 +153996,11 @@ |
| 153969 | 153996 | } |
| 153970 | 153997 | } /* End the loop over all WhereLoops from outer-most down to inner-most */ |
| 153971 | 153998 | if( obSat==obDone ) return (i8)nOrderBy; |
| 153972 | 153999 | if( !isOrderDistinct ){ |
| 153973 | 154000 | for(i=nOrderBy-1; i>0; i--){ |
| 153974 | | - Bitmask m = MASKBIT(i) - 1; |
| 154001 | + Bitmask m = ALWAYS(i<BMS) ? MASKBIT(i) - 1 : 0; |
| 153975 | 154002 | if( (obSat&m)==m ) return i; |
| 153976 | 154003 | } |
| 153977 | 154004 | return 0; |
| 153978 | 154005 | } |
| 153979 | 154006 | return -1; |
| | @@ -154494,13 +154521,13 @@ |
| 154494 | 154521 | pWC = &pWInfo->sWC; |
| 154495 | 154522 | pLoop = pBuilder->pNew; |
| 154496 | 154523 | pLoop->wsFlags = 0; |
| 154497 | 154524 | pLoop->nSkip = 0; |
| 154498 | 154525 | pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0); |
| 154526 | + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); |
| 154499 | 154527 | if( pTerm ){ |
| 154500 | 154528 | testcase( pTerm->eOperator & WO_IS ); |
| 154501 | | - assert( pTerm->prereqRight==0 ); |
| 154502 | 154529 | pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; |
| 154503 | 154530 | pLoop->aLTerm[0] = pTerm; |
| 154504 | 154531 | pLoop->nLTerm = 1; |
| 154505 | 154532 | pLoop->u.btree.nEq = 1; |
| 154506 | 154533 | /* TUNING: Cost of a rowid lookup is 10 */ |
| | @@ -167620,21 +167647,20 @@ |
| 167620 | 167647 | void (*xValue)(sqlite3_context*), |
| 167621 | 167648 | void (*xInverse)(sqlite3_context*,int,sqlite3_value **), |
| 167622 | 167649 | FuncDestructor *pDestructor |
| 167623 | 167650 | ){ |
| 167624 | 167651 | FuncDef *p; |
| 167625 | | - int nName; |
| 167626 | 167652 | int extraFlags; |
| 167627 | 167653 | |
| 167628 | 167654 | assert( sqlite3_mutex_held(db->mutex) ); |
| 167629 | 167655 | assert( xValue==0 || xSFunc==0 ); |
| 167630 | 167656 | if( zFunctionName==0 /* Must have a valid name */ |
| 167631 | 167657 | || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ |
| 167632 | 167658 | || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ |
| 167633 | 167659 | || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ |
| 167634 | 167660 | || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) |
| 167635 | | - || (255<(nName = sqlite3Strlen30( zFunctionName))) |
| 167661 | + || (255<sqlite3Strlen30(zFunctionName)) |
| 167636 | 167662 | ){ |
| 167637 | 167663 | return SQLITE_MISUSE_BKPT; |
| 167638 | 167664 | } |
| 167639 | 167665 | |
| 167640 | 167666 | assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); |
| | @@ -168897,11 +168923,11 @@ |
| 168897 | 168923 | ** This routine does the core work of extracting URI parameters from a |
| 168898 | 168924 | ** database filename for the sqlite3_uri_parameter() interface. |
| 168899 | 168925 | */ |
| 168900 | 168926 | static const char *uriParameter(const char *zFilename, const char *zParam){ |
| 168901 | 168927 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 168902 | | - while( zFilename[0] ){ |
| 168928 | + while( ALWAYS(zFilename!=0) && zFilename[0] ){ |
| 168903 | 168929 | int x = strcmp(zFilename, zParam); |
| 168904 | 168930 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 168905 | 168931 | if( x==0 ) return zFilename; |
| 168906 | 168932 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 168907 | 168933 | } |
| | @@ -170245,11 +170271,11 @@ |
| 170245 | 170271 | */ |
| 170246 | 170272 | SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){ |
| 170247 | 170273 | if( zFilename==0 || N<0 ) return 0; |
| 170248 | 170274 | zFilename = databaseName(zFilename); |
| 170249 | 170275 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 170250 | | - while( zFilename[0] && (N--)>0 ){ |
| 170276 | + while( ALWAYS(zFilename) && zFilename[0] && (N--)>0 ){ |
| 170251 | 170277 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 170252 | 170278 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 170253 | 170279 | } |
| 170254 | 170280 | return zFilename[0] ? zFilename : 0; |
| 170255 | 170281 | } |
| | @@ -170295,11 +170321,11 @@ |
| 170295 | 170321 | } |
| 170296 | 170322 | SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ |
| 170297 | 170323 | if( zFilename==0 ) return 0; |
| 170298 | 170324 | zFilename = databaseName(zFilename); |
| 170299 | 170325 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 170300 | | - while( zFilename[0] ){ |
| 170326 | + while( ALWAYS(zFilename) && zFilename[0] ){ |
| 170301 | 170327 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 170302 | 170328 | zFilename += sqlite3Strlen30(zFilename) + 1; |
| 170303 | 170329 | } |
| 170304 | 170330 | return zFilename + 1; |
| 170305 | 170331 | } |
| | @@ -171599,21 +171625,22 @@ |
| 171599 | 171625 | #ifndef SQLITE_AMALGAMATION |
| 171600 | 171626 | /* |
| 171601 | 171627 | ** Macros indicating that conditional expressions are always true or |
| 171602 | 171628 | ** false. |
| 171603 | 171629 | */ |
| 171604 | | -#ifdef SQLITE_COVERAGE_TEST |
| 171605 | | -# define ALWAYS(x) (1) |
| 171606 | | -# define NEVER(X) (0) |
| 171607 | | -#elif defined(SQLITE_DEBUG) |
| 171608 | | -# define ALWAYS(x) sqlite3Fts3Always((x)!=0) |
| 171609 | | -# define NEVER(x) sqlite3Fts3Never((x)!=0) |
| 171610 | | -SQLITE_PRIVATE int sqlite3Fts3Always(int b); |
| 171611 | | -SQLITE_PRIVATE int sqlite3Fts3Never(int b); |
| 171630 | +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
| 171631 | +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
| 171632 | +#endif |
| 171633 | +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
| 171634 | +# define ALWAYS(X) (1) |
| 171635 | +# define NEVER(X) (0) |
| 171636 | +#elif !defined(NDEBUG) |
| 171637 | +# define ALWAYS(X) ((X)?1:(assert(0),0)) |
| 171638 | +# define NEVER(X) ((X)?(assert(0),1):0) |
| 171612 | 171639 | #else |
| 171613 | | -# define ALWAYS(x) (x) |
| 171614 | | -# define NEVER(x) (x) |
| 171640 | +# define ALWAYS(X) (X) |
| 171641 | +# define NEVER(X) (X) |
| 171615 | 171642 | #endif |
| 171616 | 171643 | |
| 171617 | 171644 | /* |
| 171618 | 171645 | ** Internal types used by SQLite. |
| 171619 | 171646 | */ |
| | @@ -172125,17 +172152,10 @@ |
| 172125 | 172152 | static int fts3EvalNext(Fts3Cursor *pCsr); |
| 172126 | 172153 | static int fts3EvalStart(Fts3Cursor *pCsr); |
| 172127 | 172154 | static int fts3TermSegReaderCursor( |
| 172128 | 172155 | Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); |
| 172129 | 172156 | |
| 172130 | | -#ifndef SQLITE_AMALGAMATION |
| 172131 | | -# if defined(SQLITE_DEBUG) |
| 172132 | | -SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; } |
| 172133 | | -SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } |
| 172134 | | -# endif |
| 172135 | | -#endif |
| 172136 | | - |
| 172137 | 172157 | /* |
| 172138 | 172158 | ** This variable is set to false when running tests for which the on disk |
| 172139 | 172159 | ** structures should not be corrupt. Otherwise, true. If it is false, extra |
| 172140 | 172160 | ** assert() conditions in the fts3 code are activated - conditions that are |
| 172141 | 172161 | ** only true if it is guaranteed that the fts3 database is not corrupt. |
| | @@ -185824,11 +185844,11 @@ |
| 185824 | 185844 | |
| 185825 | 185845 | if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){ |
| 185826 | 185846 | return FTS_CORRUPT_VTAB; |
| 185827 | 185847 | } |
| 185828 | 185848 | blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); |
| 185829 | | - if( rc==SQLITE_OK ){ |
| 185849 | + if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){ |
| 185830 | 185850 | memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); |
| 185831 | 185851 | p->term.n = nPrefix+nSuffix; |
| 185832 | 185852 | p->iOff += nSuffix; |
| 185833 | 185853 | if( p->iChild==0 ){ |
| 185834 | 185854 | p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); |
| | @@ -186218,11 +186238,15 @@ |
| 186218 | 186238 | const char *zRhs, int nRhs /* RHS of comparison */ |
| 186219 | 186239 | ){ |
| 186220 | 186240 | int nCmp = MIN(nLhs, nRhs); |
| 186221 | 186241 | int res; |
| 186222 | 186242 | |
| 186223 | | - res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0); |
| 186243 | + if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){ |
| 186244 | + res = memcmp(zLhs, zRhs, nCmp); |
| 186245 | + }else{ |
| 186246 | + res = 0; |
| 186247 | + } |
| 186224 | 186248 | if( res==0 ) res = nLhs - nRhs; |
| 186225 | 186249 | |
| 186226 | 186250 | return res; |
| 186227 | 186251 | } |
| 186228 | 186252 | |
| | @@ -186862,11 +186886,11 @@ |
| 186862 | 186886 | const char *aHint = sqlite3_column_blob(pSelect, 0); |
| 186863 | 186887 | int nHint = sqlite3_column_bytes(pSelect, 0); |
| 186864 | 186888 | if( aHint ){ |
| 186865 | 186889 | blobGrowBuffer(pHint, nHint, &rc); |
| 186866 | 186890 | if( rc==SQLITE_OK ){ |
| 186867 | | - memcpy(pHint->a, aHint, nHint); |
| 186891 | + if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint); |
| 186868 | 186892 | pHint->n = nHint; |
| 186869 | 186893 | } |
| 186870 | 186894 | } |
| 186871 | 186895 | } |
| 186872 | 186896 | rc2 = sqlite3_reset(pSelect); |
| | @@ -188953,14 +188977,16 @@ |
| 188953 | 188977 | ** Advance the iterator passed as an argument to the next position. Return |
| 188954 | 188978 | ** 1 if the iterator is at EOF or if it now points to the start of the |
| 188955 | 188979 | ** position list for the next column. |
| 188956 | 188980 | */ |
| 188957 | 188981 | static int fts3LcsIteratorAdvance(LcsIterator *pIter){ |
| 188958 | | - char *pRead = pIter->pRead; |
| 188982 | + char *pRead; |
| 188959 | 188983 | sqlite3_int64 iRead; |
| 188960 | 188984 | int rc = 0; |
| 188961 | 188985 | |
| 188986 | + if( NEVER(pIter==0) ) return 1; |
| 188987 | + pRead = pIter->pRead; |
| 188962 | 188988 | pRead += sqlite3Fts3GetVarint(pRead, &iRead); |
| 188963 | 188989 | if( iRead==0 || iRead==1 ){ |
| 188964 | 188990 | pRead = 0; |
| 188965 | 188991 | rc = 1; |
| 188966 | 188992 | }else{ |
| | @@ -190478,10 +190504,23 @@ |
| 190478 | 190504 | ** but the definitions need to be repeated for separate compilation. */ |
| 190479 | 190505 | typedef sqlite3_uint64 u64; |
| 190480 | 190506 | typedef unsigned int u32; |
| 190481 | 190507 | typedef unsigned short int u16; |
| 190482 | 190508 | typedef unsigned char u8; |
| 190509 | +# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
| 190510 | +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
| 190511 | +# endif |
| 190512 | +# if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
| 190513 | +# define ALWAYS(X) (1) |
| 190514 | +# define NEVER(X) (0) |
| 190515 | +# elif !defined(NDEBUG) |
| 190516 | +# define ALWAYS(X) ((X)?1:(assert(0),0)) |
| 190517 | +# define NEVER(X) ((X)?(assert(0),1):0) |
| 190518 | +# else |
| 190519 | +# define ALWAYS(X) (X) |
| 190520 | +# define NEVER(X) (X) |
| 190521 | +# endif |
| 190483 | 190522 | #endif |
| 190484 | 190523 | |
| 190485 | 190524 | /* Objects */ |
| 190486 | 190525 | typedef struct JsonString JsonString; |
| 190487 | 190526 | typedef struct JsonNode JsonNode; |
| | @@ -190820,12 +190859,13 @@ |
| 190820 | 190859 | static void jsonRenderNode( |
| 190821 | 190860 | JsonNode *pNode, /* The node to render */ |
| 190822 | 190861 | JsonString *pOut, /* Write JSON here */ |
| 190823 | 190862 | sqlite3_value **aReplace /* Replacement values */ |
| 190824 | 190863 | ){ |
| 190864 | + assert( pNode!=0 ); |
| 190825 | 190865 | if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ |
| 190826 | | - if( pNode->jnFlags & JNODE_REPLACE ){ |
| 190866 | + if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){ |
| 190827 | 190867 | jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); |
| 190828 | 190868 | return; |
| 190829 | 190869 | } |
| 190830 | 190870 | pNode = pNode->u.pPatch; |
| 190831 | 190871 | } |
| | @@ -191141,11 +191181,11 @@ |
| 191141 | 191181 | u32 eType, /* Node type */ |
| 191142 | 191182 | u32 n, /* Content size or sub-node count */ |
| 191143 | 191183 | const char *zContent /* Content */ |
| 191144 | 191184 | ){ |
| 191145 | 191185 | JsonNode *p; |
| 191146 | | - if( pParse->nNode>=pParse->nAlloc ){ |
| 191186 | + if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){ |
| 191147 | 191187 | return jsonParseAddNodeExpand(pParse, eType, n, zContent); |
| 191148 | 191188 | } |
| 191149 | 191189 | p = &pParse->aNode[pParse->nNode]; |
| 191150 | 191190 | p->eType = (u8)eType; |
| 191151 | 191191 | p->jnFlags = 0; |
| | @@ -193099,10 +193139,13 @@ |
| 193099 | 193139 | #endif |
| 193100 | 193140 | #if defined(NDEBUG) && defined(SQLITE_DEBUG) |
| 193101 | 193141 | # undef NDEBUG |
| 193102 | 193142 | #endif |
| 193103 | 193143 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
| 193144 | +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
| 193145 | +#endif |
| 193146 | +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
| 193104 | 193147 | # define ALWAYS(X) (1) |
| 193105 | 193148 | # define NEVER(X) (0) |
| 193106 | 193149 | #elif !defined(NDEBUG) |
| 193107 | 193150 | # define ALWAYS(X) ((X)?1:(assert(0),0)) |
| 193108 | 193151 | # define NEVER(X) ((X)?(assert(0),1):0) |
| | @@ -193450,11 +193493,16 @@ |
| 193450 | 193493 | |
| 193451 | 193494 | /* The testcase() macro should already be defined in the amalgamation. If |
| 193452 | 193495 | ** it is not, make it a no-op. |
| 193453 | 193496 | */ |
| 193454 | 193497 | #ifndef SQLITE_AMALGAMATION |
| 193455 | | -# define testcase(X) |
| 193498 | +# ifdef SQLITE_COVERAGE_TEST |
| 193499 | + unsigned int sqlite3RtreeTestcase = 0; |
| 193500 | +# define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; } |
| 193501 | +# else |
| 193502 | +# define testcase(X) |
| 193503 | +# endif |
| 193456 | 193504 | #endif |
| 193457 | 193505 | |
| 193458 | 193506 | /* |
| 193459 | 193507 | ** Make sure that the compiler intrinsics we desire are enabled when |
| 193460 | 193508 | ** compiling with an appropriate version of MSVC unless prevented by |
| | @@ -195214,11 +195262,11 @@ |
| 195214 | 195262 | RtreeDValue fMinGrowth = RTREE_ZERO; |
| 195215 | 195263 | RtreeDValue fMinArea = RTREE_ZERO; |
| 195216 | 195264 | |
| 195217 | 195265 | int nCell = NCELL(pNode); |
| 195218 | 195266 | RtreeCell cell; |
| 195219 | | - RtreeNode *pChild; |
| 195267 | + RtreeNode *pChild = 0; |
| 195220 | 195268 | |
| 195221 | 195269 | RtreeCell *aCell = 0; |
| 195222 | 195270 | |
| 195223 | 195271 | /* Select the child node which will be enlarged the least if pCell |
| 195224 | 195272 | ** is inserted into it. Resolve ties by choosing the entry with |
| | @@ -195572,10 +195620,11 @@ |
| 195572 | 195620 | nodeRelease(pRtree, pChild->pParent); |
| 195573 | 195621 | nodeReference(pNode); |
| 195574 | 195622 | pChild->pParent = pNode; |
| 195575 | 195623 | } |
| 195576 | 195624 | } |
| 195625 | + if( NEVER(pNode==0) ) return SQLITE_ERROR; |
| 195577 | 195626 | return xSetMapping(pRtree, iRowid, pNode->iNode); |
| 195578 | 195627 | } |
| 195579 | 195628 | |
| 195580 | 195629 | static int SplitNode( |
| 195581 | 195630 | Rtree *pRtree, |
| | @@ -196876,10 +196925,11 @@ |
| 196876 | 196925 | tree.nDim = (u8)sqlite3_value_int(apArg[0]); |
| 196877 | 196926 | if( tree.nDim<1 || tree.nDim>5 ) return; |
| 196878 | 196927 | tree.nDim2 = tree.nDim*2; |
| 196879 | 196928 | tree.nBytesPerCell = 8 + 8 * tree.nDim; |
| 196880 | 196929 | node.zData = (u8 *)sqlite3_value_blob(apArg[1]); |
| 196930 | + if( node.zData==0 ) return; |
| 196881 | 196931 | nData = sqlite3_value_bytes(apArg[1]); |
| 196882 | 196932 | if( nData<4 ) return; |
| 196883 | 196933 | if( nData<NCELL(&node)*tree.nBytesPerCell ) return; |
| 196884 | 196934 | |
| 196885 | 196935 | pOut = sqlite3_str_new(0); |
| | @@ -197707,17 +197757,18 @@ |
| 197707 | 197757 | sqlite3_value *pVal, /* The value to decode */ |
| 197708 | 197758 | int *pRc /* Write error here */ |
| 197709 | 197759 | ){ |
| 197710 | 197760 | GeoPoly *p = 0; |
| 197711 | 197761 | int nByte; |
| 197762 | + testcase( pCtx==0 ); |
| 197712 | 197763 | if( sqlite3_value_type(pVal)==SQLITE_BLOB |
| 197713 | 197764 | && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) |
| 197714 | 197765 | ){ |
| 197715 | 197766 | const unsigned char *a = sqlite3_value_blob(pVal); |
| 197716 | 197767 | int nVertex; |
| 197717 | 197768 | if( a==0 ){ |
| 197718 | | - sqlite3_result_error_nomem(pCtx); |
| 197769 | + if( pCtx ) sqlite3_result_error_nomem(pCtx); |
| 197719 | 197770 | return 0; |
| 197720 | 197771 | } |
| 197721 | 197772 | nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; |
| 197722 | 197773 | if( (a[0]==0 || a[0]==1) |
| 197723 | 197774 | && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte |
| | @@ -198540,15 +198591,15 @@ |
| 198540 | 198591 | pActive = pSeg; |
| 198541 | 198592 | needSort = 1; |
| 198542 | 198593 | }else{ |
| 198543 | 198594 | /* Remove a segment */ |
| 198544 | 198595 | if( pActive==pThisEvent->pSeg ){ |
| 198545 | | - pActive = pActive->pNext; |
| 198596 | + pActive = ALWAYS(pActive) ? pActive->pNext : 0; |
| 198546 | 198597 | }else{ |
| 198547 | 198598 | for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ |
| 198548 | 198599 | if( pSeg->pNext==pThisEvent->pSeg ){ |
| 198549 | | - pSeg->pNext = pSeg->pNext->pNext; |
| 198600 | + pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0; |
| 198550 | 198601 | break; |
| 198551 | 198602 | } |
| 198552 | 198603 | } |
| 198553 | 198604 | } |
| 198554 | 198605 | } |
| | @@ -198788,10 +198839,11 @@ |
| 198788 | 198839 | rc = nodeAcquire(pRtree, 1, 0, &pRoot); |
| 198789 | 198840 | if( rc==SQLITE_OK && idxNum<=3 ){ |
| 198790 | 198841 | RtreeCoord bbox[4]; |
| 198791 | 198842 | RtreeConstraint *p; |
| 198792 | 198843 | assert( argc==1 ); |
| 198844 | + assert( argv[0]!=0 ); |
| 198793 | 198845 | geopolyBBox(0, argv[0], bbox, &rc); |
| 198794 | 198846 | if( rc ){ |
| 198795 | 198847 | goto geopoly_filter_end; |
| 198796 | 198848 | } |
| 198797 | 198849 | pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); |
| | @@ -199015,10 +199067,11 @@ |
| 199015 | 199067 | if( nData>1 /* not a DELETE */ |
| 199016 | 199068 | && (!oldRowidValid /* INSERT */ |
| 199017 | 199069 | || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ |
| 199018 | 199070 | || oldRowid!=newRowid) /* Rowid change */ |
| 199019 | 199071 | ){ |
| 199072 | + assert( aData[2]!=0 ); |
| 199020 | 199073 | geopolyBBox(0, aData[2], cell.aCoord, &rc); |
| 199021 | 199074 | if( rc ){ |
| 199022 | 199075 | if( rc==SQLITE_ERROR ){ |
| 199023 | 199076 | pVtab->zErrMsg = |
| 199024 | 199077 | sqlite3_mprintf("_shape does not contain a valid polygon"); |
| | @@ -207873,11 +207926,11 @@ |
| 207873 | 207926 | if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; |
| 207874 | 207927 | nVarint = sessionVarintLen(n); |
| 207875 | 207928 | |
| 207876 | 207929 | if( aBuf ){ |
| 207877 | 207930 | sessionVarintPut(&aBuf[1], n); |
| 207878 | | - if( n ) memcpy(&aBuf[nVarint + 1], z, n); |
| 207931 | + if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n); |
| 207879 | 207932 | } |
| 207880 | 207933 | |
| 207881 | 207934 | nByte = 1 + nVarint + n; |
| 207882 | 207935 | break; |
| 207883 | 207936 | } |
| | @@ -208478,20 +208531,36 @@ |
| 208478 | 208531 | "SELECT 2, 'stat', '', 0, '', 0" |
| 208479 | 208532 | ); |
| 208480 | 208533 | }else if( rc==SQLITE_ERROR ){ |
| 208481 | 208534 | zPragma = sqlite3_mprintf(""); |
| 208482 | 208535 | }else{ |
| 208536 | + *pazCol = 0; |
| 208537 | + *pabPK = 0; |
| 208538 | + *pnCol = 0; |
| 208539 | + if( pzTab ) *pzTab = 0; |
| 208483 | 208540 | return rc; |
| 208484 | 208541 | } |
| 208485 | 208542 | }else{ |
| 208486 | 208543 | zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); |
| 208487 | 208544 | } |
| 208488 | | - if( !zPragma ) return SQLITE_NOMEM; |
| 208545 | + if( !zPragma ){ |
| 208546 | + *pazCol = 0; |
| 208547 | + *pabPK = 0; |
| 208548 | + *pnCol = 0; |
| 208549 | + if( pzTab ) *pzTab = 0; |
| 208550 | + return SQLITE_NOMEM; |
| 208551 | + } |
| 208489 | 208552 | |
| 208490 | 208553 | rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); |
| 208491 | 208554 | sqlite3_free(zPragma); |
| 208492 | | - if( rc!=SQLITE_OK ) return rc; |
| 208555 | + if( rc!=SQLITE_OK ){ |
| 208556 | + *pazCol = 0; |
| 208557 | + *pabPK = 0; |
| 208558 | + *pnCol = 0; |
| 208559 | + if( pzTab ) *pzTab = 0; |
| 208560 | + return rc; |
| 208561 | + } |
| 208493 | 208562 | |
| 208494 | 208563 | nByte = nThis + 1; |
| 208495 | 208564 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 208496 | 208565 | nByte += sqlite3_column_bytes(pStmt, 1); |
| 208497 | 208566 | nDbCol++; |
| | @@ -208905,11 +208974,15 @@ |
| 208905 | 208974 | if( pSession->xTableFilter==0 |
| 208906 | 208975 | || pSession->xTableFilter(pSession->pFilterCtx, zName) |
| 208907 | 208976 | ){ |
| 208908 | 208977 | rc = sqlite3session_attach(pSession, zName); |
| 208909 | 208978 | if( rc==SQLITE_OK ){ |
| 208910 | | - for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext); |
| 208979 | + pRet = pSession->pTable; |
| 208980 | + while( ALWAYS(pRet) && pRet->pNext ){ |
| 208981 | + pRet = pRet->pNext; |
| 208982 | + } |
| 208983 | + assert( pRet!=0 ); |
| 208911 | 208984 | assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ); |
| 208912 | 208985 | } |
| 208913 | 208986 | } |
| 208914 | 208987 | } |
| 208915 | 208988 | |
| | @@ -209678,10 +209751,11 @@ |
| 209678 | 209751 | int bNoop = 1; /* Set to zero if any values are modified */ |
| 209679 | 209752 | int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */ |
| 209680 | 209753 | int i; /* Used to iterate through columns */ |
| 209681 | 209754 | u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ |
| 209682 | 209755 | |
| 209756 | + assert( abPK!=0 ); |
| 209683 | 209757 | sessionAppendByte(pBuf, SQLITE_UPDATE, &rc); |
| 209684 | 209758 | sessionAppendByte(pBuf, p->bIndirect, &rc); |
| 209685 | 209759 | for(i=0; i<sqlite3_column_count(pStmt); i++){ |
| 209686 | 209760 | int bChanged = 0; |
| 209687 | 209761 | int nAdvance; |
| | @@ -209982,16 +210056,18 @@ |
| 209982 | 210056 | sqlite3 *db = pSession->db; /* Source database handle */ |
| 209983 | 210057 | SessionTable *pTab; /* Used to iterate through attached tables */ |
| 209984 | 210058 | SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ |
| 209985 | 210059 | int rc; /* Return code */ |
| 209986 | 210060 | |
| 209987 | | - assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) ); |
| 210061 | + assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) ); |
| 210062 | + assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) ); |
| 209988 | 210063 | |
| 209989 | 210064 | /* Zero the output variables in case an error occurs. If this session |
| 209990 | 210065 | ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), |
| 209991 | 210066 | ** this call will be a no-op. */ |
| 209992 | 210067 | if( xOutput==0 ){ |
| 210068 | + assert( pnChangeset!=0 && ppChangeset!=0 ); |
| 209993 | 210069 | *pnChangeset = 0; |
| 209994 | 210070 | *ppChangeset = 0; |
| 209995 | 210071 | } |
| 209996 | 210072 | |
| 209997 | 210073 | if( pSession->rc ) return pSession->rc; |
| | @@ -210001,12 +210077,12 @@ |
| 210001 | 210077 | sqlite3_mutex_enter(sqlite3_db_mutex(db)); |
| 210002 | 210078 | |
| 210003 | 210079 | for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ |
| 210004 | 210080 | if( pTab->nEntry ){ |
| 210005 | 210081 | const char *zName = pTab->zName; |
| 210006 | | - int nCol; /* Number of columns in table */ |
| 210007 | | - u8 *abPK; /* Primary key array */ |
| 210082 | + int nCol = 0; /* Number of columns in table */ |
| 210083 | + u8 *abPK = 0; /* Primary key array */ |
| 210008 | 210084 | const char **azCol = 0; /* Table columns */ |
| 210009 | 210085 | int i; /* Used to iterate through hash buckets */ |
| 210010 | 210086 | sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ |
| 210011 | 210087 | int nRewind = buf.nBuf; /* Initial size of write buffer */ |
| 210012 | 210088 | int nNoop; /* Size of buffer after writing tbl header */ |
| | @@ -210040,10 +210116,11 @@ |
| 210040 | 210116 | sessionAppendByte(&buf, p->bIndirect, &rc); |
| 210041 | 210117 | for(iCol=0; iCol<nCol; iCol++){ |
| 210042 | 210118 | sessionAppendCol(&buf, pSel, iCol, &rc); |
| 210043 | 210119 | } |
| 210044 | 210120 | }else{ |
| 210121 | + assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */ |
| 210045 | 210122 | rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); |
| 210046 | 210123 | } |
| 210047 | 210124 | }else if( p->op!=SQLITE_INSERT ){ |
| 210048 | 210125 | rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); |
| 210049 | 210126 | } |
| | @@ -210100,11 +210177,14 @@ |
| 210100 | 210177 | SQLITE_API int sqlite3session_changeset( |
| 210101 | 210178 | sqlite3_session *pSession, /* Session object */ |
| 210102 | 210179 | int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ |
| 210103 | 210180 | void **ppChangeset /* OUT: Buffer containing changeset */ |
| 210104 | 210181 | ){ |
| 210105 | | - int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); |
| 210182 | + int rc; |
| 210183 | + |
| 210184 | + if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE; |
| 210185 | + rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); |
| 210106 | 210186 | assert( rc || pnChangeset==0 |
| 210107 | 210187 | || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize |
| 210108 | 210188 | ); |
| 210109 | 210189 | return rc; |
| 210110 | 210190 | } |
| | @@ -210115,10 +210195,11 @@ |
| 210115 | 210195 | SQLITE_API int sqlite3session_changeset_strm( |
| 210116 | 210196 | sqlite3_session *pSession, |
| 210117 | 210197 | int (*xOutput)(void *pOut, const void *pData, int nData), |
| 210118 | 210198 | void *pOut |
| 210119 | 210199 | ){ |
| 210200 | + if( xOutput==0 ) return SQLITE_MISUSE; |
| 210120 | 210201 | return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0); |
| 210121 | 210202 | } |
| 210122 | 210203 | |
| 210123 | 210204 | /* |
| 210124 | 210205 | ** Streaming version of sqlite3session_patchset(). |
| | @@ -210126,10 +210207,11 @@ |
| 210126 | 210207 | SQLITE_API int sqlite3session_patchset_strm( |
| 210127 | 210208 | sqlite3_session *pSession, |
| 210128 | 210209 | int (*xOutput)(void *pOut, const void *pData, int nData), |
| 210129 | 210210 | void *pOut |
| 210130 | 210211 | ){ |
| 210212 | + if( xOutput==0 ) return SQLITE_MISUSE; |
| 210131 | 210213 | return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0); |
| 210132 | 210214 | } |
| 210133 | 210215 | |
| 210134 | 210216 | /* |
| 210135 | 210217 | ** Obtain a patchset object containing all changes recorded by the |
| | @@ -210141,10 +210223,11 @@ |
| 210141 | 210223 | SQLITE_API int sqlite3session_patchset( |
| 210142 | 210224 | sqlite3_session *pSession, /* Session object */ |
| 210143 | 210225 | int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ |
| 210144 | 210226 | void **ppPatchset /* OUT: Buffer containing changeset */ |
| 210145 | 210227 | ){ |
| 210228 | + if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE; |
| 210146 | 210229 | return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset); |
| 210147 | 210230 | } |
| 210148 | 210231 | |
| 210149 | 210232 | /* |
| 210150 | 210233 | ** Enable or disable the session object passed as the first argument. |
| | @@ -211104,15 +211187,15 @@ |
| 211104 | 211187 | if( rc!=SQLITE_OK ) goto finished_invert; |
| 211105 | 211188 | } |
| 211106 | 211189 | } |
| 211107 | 211190 | |
| 211108 | 211191 | assert( rc==SQLITE_OK ); |
| 211109 | | - if( pnInverted ){ |
| 211192 | + if( pnInverted && ALWAYS(ppInverted) ){ |
| 211110 | 211193 | *pnInverted = sOut.nBuf; |
| 211111 | 211194 | *ppInverted = sOut.aBuf; |
| 211112 | 211195 | sOut.aBuf = 0; |
| 211113 | | - }else if( sOut.nBuf>0 ){ |
| 211196 | + }else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){ |
| 211114 | 211197 | rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); |
| 211115 | 211198 | } |
| 211116 | 211199 | |
| 211117 | 211200 | finished_invert: |
| 211118 | 211201 | sqlite3_free(sOut.aBuf); |
| | @@ -211564,11 +211647,11 @@ |
| 211564 | 211647 | ** in the code below. */ |
| 211565 | 211648 | assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new ); |
| 211566 | 211649 | |
| 211567 | 211650 | for(i=0; rc==SQLITE_OK && i<nCol; i++){ |
| 211568 | 211651 | if( !abPK || abPK[i] ){ |
| 211569 | | - sqlite3_value *pVal; |
| 211652 | + sqlite3_value *pVal = 0; |
| 211570 | 211653 | (void)xValue(pIter, i, &pVal); |
| 211571 | 211654 | if( pVal==0 ){ |
| 211572 | 211655 | /* The value in the changeset was "undefined". This indicates a |
| 211573 | 211656 | ** corrupt changeset blob. */ |
| 211574 | 211657 | rc = SQLITE_CORRUPT_BKPT; |
| | @@ -212707,13 +212790,13 @@ |
| 212707 | 212790 | } |
| 212708 | 212791 | |
| 212709 | 212792 | if( rc==SQLITE_OK ){ |
| 212710 | 212793 | if( xOutput ){ |
| 212711 | 212794 | if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf); |
| 212712 | | - }else{ |
| 212795 | + }else if( ppOut ){ |
| 212713 | 212796 | *ppOut = buf.aBuf; |
| 212714 | | - *pnOut = buf.nBuf; |
| 212797 | + if( pnOut ) *pnOut = buf.nBuf; |
| 212715 | 212798 | buf.aBuf = 0; |
| 212716 | 212799 | } |
| 212717 | 212800 | } |
| 212718 | 212801 | sqlite3_free(buf.aBuf); |
| 212719 | 212802 | |
| | @@ -213109,11 +213192,11 @@ |
| 213109 | 213192 | if( rc==SQLITE_OK ){ |
| 213110 | 213193 | if( xOutput ){ |
| 213111 | 213194 | if( sOut.nBuf>0 ){ |
| 213112 | 213195 | rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); |
| 213113 | 213196 | } |
| 213114 | | - }else{ |
| 213197 | + }else if( ppOut ){ |
| 213115 | 213198 | *ppOut = (void*)sOut.aBuf; |
| 213116 | 213199 | *pnOut = sOut.nBuf; |
| 213117 | 213200 | sOut.aBuf = 0; |
| 213118 | 213201 | } |
| 213119 | 213202 | } |
| | @@ -213852,12 +213935,24 @@ |
| 213852 | 213935 | #ifndef ArraySize |
| 213853 | 213936 | # define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0]))) |
| 213854 | 213937 | #endif |
| 213855 | 213938 | |
| 213856 | 213939 | #define testcase(x) |
| 213857 | | -#define ALWAYS(x) 1 |
| 213858 | | -#define NEVER(x) 0 |
| 213940 | + |
| 213941 | +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
| 213942 | +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
| 213943 | +#endif |
| 213944 | +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
| 213945 | +# define ALWAYS(X) (1) |
| 213946 | +# define NEVER(X) (0) |
| 213947 | +#elif !defined(NDEBUG) |
| 213948 | +# define ALWAYS(X) ((X)?1:(assert(0),0)) |
| 213949 | +# define NEVER(X) ((X)?(assert(0),1):0) |
| 213950 | +#else |
| 213951 | +# define ALWAYS(X) (X) |
| 213952 | +# define NEVER(X) (X) |
| 213953 | +#endif |
| 213859 | 213954 | |
| 213860 | 213955 | #define MIN(x,y) (((x) < (y)) ? (x) : (y)) |
| 213861 | 213956 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) |
| 213862 | 213957 | |
| 213863 | 213958 | /* |
| | @@ -217846,10 +217941,11 @@ |
| 217846 | 217941 | |
| 217847 | 217942 | z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol); |
| 217848 | 217943 | z = fts5ConfigSkipWhitespace(z); |
| 217849 | 217944 | if( z && *z=='=' ){ |
| 217850 | 217945 | bOption = 1; |
| 217946 | + assert( zOne!=0 ); |
| 217851 | 217947 | z++; |
| 217852 | 217948 | if( bMustBeCol ) z = 0; |
| 217853 | 217949 | } |
| 217854 | 217950 | z = fts5ConfigSkipWhitespace(z); |
| 217855 | 217951 | if( z && z[0] ){ |
| | @@ -217862,11 +217958,15 @@ |
| 217862 | 217958 | if( z==0 ){ |
| 217863 | 217959 | *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig); |
| 217864 | 217960 | rc = SQLITE_ERROR; |
| 217865 | 217961 | }else{ |
| 217866 | 217962 | if( bOption ){ |
| 217867 | | - rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr); |
| 217963 | + rc = fts5ConfigParseSpecial(pGlobal, pRet, |
| 217964 | + ALWAYS(zOne)?zOne:"", |
| 217965 | + zTwo?zTwo:"", |
| 217966 | + pzErr |
| 217967 | + ); |
| 217868 | 217968 | }else{ |
| 217869 | 217969 | rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); |
| 217870 | 217970 | zOne = 0; |
| 217871 | 217971 | } |
| 217872 | 217972 | } |
| | @@ -218679,10 +218779,11 @@ |
| 218679 | 218779 | static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){ |
| 218680 | 218780 | i64 iRet = 0; |
| 218681 | 218781 | int bRetValid = 0; |
| 218682 | 218782 | Fts5ExprTerm *p; |
| 218683 | 218783 | |
| 218784 | + assert( pTerm ); |
| 218684 | 218785 | assert( pTerm->pSynonym ); |
| 218685 | 218786 | assert( bDesc==0 || bDesc==1 ); |
| 218686 | 218787 | for(p=pTerm; p; p=p->pSynonym){ |
| 218687 | 218788 | if( 0==sqlite3Fts5IterEof(p->pIter) ){ |
| 218688 | 218789 | i64 iRowid = p->pIter->iRowid; |
| | @@ -220119,11 +220220,11 @@ |
| 220119 | 220220 | /* This happens when parsing a token or quoted phrase that contains |
| 220120 | 220221 | ** no token characters at all. (e.g ... MATCH '""'). */ |
| 220121 | 220222 | sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); |
| 220122 | 220223 | } |
| 220123 | 220224 | |
| 220124 | | - if( rc==SQLITE_OK ){ |
| 220225 | + if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ |
| 220125 | 220226 | /* All the allocations succeeded. Put the expression object together. */ |
| 220126 | 220227 | pNew->pIndex = pExpr->pIndex; |
| 220127 | 220228 | pNew->pConfig = pExpr->pConfig; |
| 220128 | 220229 | pNew->nPhrase = 1; |
| 220129 | 220230 | pNew->apExprPhrase[0] = sCtx.pPhrase; |
| | @@ -223638,10 +223739,11 @@ |
| 223638 | 223739 | fts5SegIterNextPage(p, pIter); |
| 223639 | 223740 | } |
| 223640 | 223741 | |
| 223641 | 223742 | if( p->rc==SQLITE_OK ){ |
| 223642 | 223743 | pIter->iLeafOffset = 4; |
| 223744 | + assert( pIter->pLeaf!=0 ); |
| 223643 | 223745 | assert_nc( pIter->pLeaf->nn>4 ); |
| 223644 | 223746 | assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 ); |
| 223645 | 223747 | pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; |
| 223646 | 223748 | fts5SegIterLoadTerm(p, pIter, 0); |
| 223647 | 223749 | fts5SegIterLoadNPos(p, pIter); |
| | @@ -224598,11 +224700,11 @@ |
| 224598 | 224700 | pIter->pNextLeaf = 0; |
| 224599 | 224701 | pIter->iLeafPgno = iLeafPgno-1; |
| 224600 | 224702 | fts5SegIterNextPage(p, pIter); |
| 224601 | 224703 | assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno ); |
| 224602 | 224704 | |
| 224603 | | - if( p->rc==SQLITE_OK ){ |
| 224705 | + if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){ |
| 224604 | 224706 | int iOff; |
| 224605 | 224707 | u8 *a = pIter->pLeaf->p; |
| 224606 | 224708 | int n = pIter->pLeaf->szLeaf; |
| 224607 | 224709 | |
| 224608 | 224710 | iOff = fts5LeafFirstRowidOff(pIter->pLeaf); |
| | @@ -225030,11 +225132,15 @@ |
| 225030 | 225132 | Fts5Index *p, |
| 225031 | 225133 | Fts5SegIter *pSeg, |
| 225032 | 225134 | Fts5Colset *pColset, |
| 225033 | 225135 | Fts5Buffer *pBuf |
| 225034 | 225136 | ){ |
| 225137 | + assert( pBuf!=0 ); |
| 225138 | + assert( pSeg!=0 ); |
| 225035 | 225139 | if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){ |
| 225140 | + assert( pBuf->p!=0 ); |
| 225141 | + assert( pBuf->nSpace >= pBuf->n+pSeg->nPos+FTS5_DATA_ZERO_PADDING ); |
| 225036 | 225142 | memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING); |
| 225037 | 225143 | if( pColset==0 ){ |
| 225038 | 225144 | fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); |
| 225039 | 225145 | }else{ |
| 225040 | 225146 | if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){ |
| | @@ -225254,10 +225360,11 @@ |
| 225254 | 225360 | pIter->base.nData = pIter->poslist.n; |
| 225255 | 225361 | } |
| 225256 | 225362 | } |
| 225257 | 225363 | |
| 225258 | 225364 | static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ |
| 225365 | + assert( pIter!=0 || (*pRc)!=SQLITE_OK ); |
| 225259 | 225366 | if( *pRc==SQLITE_OK ){ |
| 225260 | 225367 | Fts5Config *pConfig = pIter->pIndex->pConfig; |
| 225261 | 225368 | if( pConfig->eDetail==FTS5_DETAIL_NONE ){ |
| 225262 | 225369 | pIter->xSetOutputs = fts5IterSetOutputs_None; |
| 225263 | 225370 | } |
| | @@ -225325,11 +225432,14 @@ |
| 225325 | 225432 | }else{ |
| 225326 | 225433 | nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment); |
| 225327 | 225434 | } |
| 225328 | 225435 | } |
| 225329 | 225436 | *ppOut = pNew = fts5MultiIterAlloc(p, nSeg); |
| 225330 | | - if( pNew==0 ) return; |
| 225437 | + if( pNew==0 ){ |
| 225438 | + assert( p->rc!=SQLITE_OK ); |
| 225439 | + goto fts5MultiIterNew_post_check; |
| 225440 | + } |
| 225331 | 225441 | pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC)); |
| 225332 | 225442 | pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY)); |
| 225333 | 225443 | pNew->pColset = pColset; |
| 225334 | 225444 | if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){ |
| 225335 | 225445 | fts5IterSetOutputCb(&p->rc, pNew); |
| | @@ -225389,10 +225499,14 @@ |
| 225389 | 225499 | |
| 225390 | 225500 | }else{ |
| 225391 | 225501 | fts5MultiIterFree(pNew); |
| 225392 | 225502 | *ppOut = 0; |
| 225393 | 225503 | } |
| 225504 | + |
| 225505 | +fts5MultiIterNew_post_check: |
| 225506 | + assert( (*ppOut)!=0 || p->rc!=SQLITE_OK ); |
| 225507 | + return; |
| 225394 | 225508 | } |
| 225395 | 225509 | |
| 225396 | 225510 | /* |
| 225397 | 225511 | ** Create an Fts5Iter that iterates through the doclist provided |
| 225398 | 225512 | ** as the second argument. |
| | @@ -225436,11 +225550,12 @@ |
| 225436 | 225550 | /* |
| 225437 | 225551 | ** Return true if the iterator is at EOF or if an error has occurred. |
| 225438 | 225552 | ** False otherwise. |
| 225439 | 225553 | */ |
| 225440 | 225554 | static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){ |
| 225441 | | - assert( p->rc |
| 225555 | + assert( pIter!=0 || p->rc!=SQLITE_OK ); |
| 225556 | + assert( p->rc!=SQLITE_OK |
| 225442 | 225557 | || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof |
| 225443 | 225558 | ); |
| 225444 | 225559 | return (p->rc || pIter->base.bEof); |
| 225445 | 225560 | } |
| 225446 | 225561 | |
| | @@ -226240,10 +226355,11 @@ |
| 226240 | 226355 | |
| 226241 | 226356 | /* Flush the last leaf page to disk. Set the output segment b-tree height |
| 226242 | 226357 | ** and last leaf page number at the same time. */ |
| 226243 | 226358 | fts5WriteFinish(p, &writer, &pSeg->pgnoLast); |
| 226244 | 226359 | |
| 226360 | + assert( pIter!=0 || p->rc!=SQLITE_OK ); |
| 226245 | 226361 | if( fts5MultiIterEof(p, pIter) ){ |
| 226246 | 226362 | int i; |
| 226247 | 226363 | |
| 226248 | 226364 | /* Remove the redundant segments from the %_data table */ |
| 226249 | 226365 | for(i=0; i<nInput; i++){ |
| | @@ -226340,11 +226456,11 @@ |
| 226340 | 226456 | static void fts5IndexAutomerge( |
| 226341 | 226457 | Fts5Index *p, /* FTS5 backend object */ |
| 226342 | 226458 | Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */ |
| 226343 | 226459 | int nLeaf /* Number of output leaves just written */ |
| 226344 | 226460 | ){ |
| 226345 | | - if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){ |
| 226461 | + if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 && ALWAYS((*ppStruct)!=0) ){ |
| 226346 | 226462 | Fts5Structure *pStruct = *ppStruct; |
| 226347 | 226463 | u64 nWrite; /* Initial value of write-counter */ |
| 226348 | 226464 | int nWork; /* Number of work-quanta to perform */ |
| 226349 | 226465 | int nRem; /* Number of leaf pages left to write */ |
| 226350 | 226466 | |
| | @@ -227450,15 +227566,19 @@ |
| 227450 | 227566 | } |
| 227451 | 227567 | }else{ |
| 227452 | 227568 | /* Scan multiple terms in the main index */ |
| 227453 | 227569 | int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; |
| 227454 | 227570 | fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); |
| 227455 | | - assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); |
| 227456 | | - fts5IterSetOutputCb(&p->rc, pRet); |
| 227457 | | - if( p->rc==SQLITE_OK ){ |
| 227458 | | - Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; |
| 227459 | | - if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); |
| 227571 | + if( pRet==0 ){ |
| 227572 | + assert( p->rc!=SQLITE_OK ); |
| 227573 | + }else{ |
| 227574 | + assert( pRet->pColset==0 ); |
| 227575 | + fts5IterSetOutputCb(&p->rc, pRet); |
| 227576 | + if( p->rc==SQLITE_OK ){ |
| 227577 | + Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; |
| 227578 | + if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); |
| 227579 | + } |
| 227460 | 227580 | } |
| 227461 | 227581 | } |
| 227462 | 227582 | |
| 227463 | 227583 | if( p->rc ){ |
| 227464 | 227584 | sqlite3Fts5IterClose((Fts5IndexIter*)pRet); |
| | @@ -227702,11 +227822,11 @@ |
| 227702 | 227822 | int eDetail = p->pConfig->eDetail; |
| 227703 | 227823 | u64 cksum = *pCksum; |
| 227704 | 227824 | Fts5IndexIter *pIter = 0; |
| 227705 | 227825 | int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); |
| 227706 | 227826 | |
| 227707 | | - while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){ |
| 227827 | + while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ |
| 227708 | 227828 | i64 rowid = pIter->iRowid; |
| 227709 | 227829 | |
| 227710 | 227830 | if( eDetail==FTS5_DETAIL_NONE ){ |
| 227711 | 227831 | cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n); |
| 227712 | 227832 | }else{ |
| | @@ -228067,10 +228187,11 @@ |
| 228067 | 228187 | int eDetail = p->pConfig->eDetail; |
| 228068 | 228188 | u64 cksum2 = 0; /* Checksum based on contents of indexes */ |
| 228069 | 228189 | Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ |
| 228070 | 228190 | Fts5Iter *pIter; /* Used to iterate through entire index */ |
| 228071 | 228191 | Fts5Structure *pStruct; /* Index structure */ |
| 228192 | + int iLvl, iSeg; |
| 228072 | 228193 | |
| 228073 | 228194 | #ifdef SQLITE_DEBUG |
| 228074 | 228195 | /* Used by extra internal tests only run if NDEBUG is not defined */ |
| 228075 | 228196 | u64 cksum3 = 0; /* Checksum based on contents of indexes */ |
| 228076 | 228197 | Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */ |
| | @@ -228077,19 +228198,20 @@ |
| 228077 | 228198 | #endif |
| 228078 | 228199 | const int flags = FTS5INDEX_QUERY_NOOUTPUT; |
| 228079 | 228200 | |
| 228080 | 228201 | /* Load the FTS index structure */ |
| 228081 | 228202 | pStruct = fts5StructureRead(p); |
| 228203 | + if( pStruct==0 ){ |
| 228204 | + assert( p->rc!=SQLITE_OK ); |
| 228205 | + return fts5IndexReturn(p); |
| 228206 | + } |
| 228082 | 228207 | |
| 228083 | 228208 | /* Check that the internal nodes of each segment match the leaves */ |
| 228084 | | - if( pStruct ){ |
| 228085 | | - int iLvl, iSeg; |
| 228086 | | - for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ |
| 228087 | | - for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ |
| 228088 | | - Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; |
| 228089 | | - fts5IndexIntegrityCheckSegment(p, pSeg); |
| 228090 | | - } |
| 228209 | + for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ |
| 228210 | + for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ |
| 228211 | + Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; |
| 228212 | + fts5IndexIntegrityCheckSegment(p, pSeg); |
| 228091 | 228213 | } |
| 228092 | 228214 | } |
| 228093 | 228215 | |
| 228094 | 228216 | /* The cksum argument passed to this function is a checksum calculated |
| 228095 | 228217 | ** based on all expected entries in the FTS index (including prefix index |
| | @@ -230032,11 +230154,12 @@ |
| 230032 | 230154 | pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN); |
| 230033 | 230155 | rc = sqlite3Fts5StorageStmt( |
| 230034 | 230156 | pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg |
| 230035 | 230157 | ); |
| 230036 | 230158 | if( rc==SQLITE_OK ){ |
| 230037 | | - if( pCsr->ePlan==FTS5_PLAN_ROWID ){ |
| 230159 | + if( pRowidEq!=0 ){ |
| 230160 | + assert( pCsr->ePlan==FTS5_PLAN_ROWID ); |
| 230038 | 230161 | sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); |
| 230039 | 230162 | }else{ |
| 230040 | 230163 | sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); |
| 230041 | 230164 | sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid); |
| 230042 | 230165 | } |
| | @@ -231450,11 +231573,11 @@ |
| 231450 | 231573 | int nArg, /* Number of args */ |
| 231451 | 231574 | sqlite3_value **apUnused /* Function arguments */ |
| 231452 | 231575 | ){ |
| 231453 | 231576 | assert( nArg==0 ); |
| 231454 | 231577 | UNUSED_PARAM2(nArg, apUnused); |
| 231455 | | - sqlite3_result_text(pCtx, "fts5: 2021-10-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813", -1, SQLITE_TRANSIENT); |
| 231578 | + sqlite3_result_text(pCtx, "fts5: 2021-10-05 18:33:38 a7835bead85b1b18a8affd9835240b0baf9c7af887196bbdcc3f5d58055042fc", -1, SQLITE_TRANSIENT); |
| 231456 | 231579 | } |
| 231457 | 231580 | |
| 231458 | 231581 | /* |
| 231459 | 231582 | ** Return true if zName is the extension on one of the shadow tables used |
| 231460 | 231583 | ** by this module. |
| | @@ -232001,16 +232124,20 @@ |
| 232001 | 232124 | rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); |
| 232002 | 232125 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 232003 | 232126 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 232004 | 232127 | const char *zText; |
| 232005 | 232128 | int nText; |
| 232129 | + assert( pSeek==0 || apVal==0 ); |
| 232130 | + assert( pSeek!=0 || apVal!=0 ); |
| 232006 | 232131 | if( pSeek ){ |
| 232007 | 232132 | zText = (const char*)sqlite3_column_text(pSeek, iCol); |
| 232008 | 232133 | nText = sqlite3_column_bytes(pSeek, iCol); |
| 232009 | | - }else{ |
| 232134 | + }else if( ALWAYS(apVal) ){ |
| 232010 | 232135 | zText = (const char*)sqlite3_value_text(apVal[iCol-1]); |
| 232011 | 232136 | nText = sqlite3_value_bytes(apVal[iCol-1]); |
| 232137 | + }else{ |
| 232138 | + continue; |
| 232012 | 232139 | } |
| 232013 | 232140 | ctx.szCol = 0; |
| 232014 | 232141 | rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, |
| 232015 | 232142 | zText, nText, (void*)&ctx, fts5StorageInsertCallback |
| 232016 | 232143 | ); |
| | @@ -232642,12 +232769,13 @@ |
| 232642 | 232769 | sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */ |
| 232643 | 232770 | int rc; /* Return Code */ |
| 232644 | 232771 | |
| 232645 | 232772 | assert( p->pConfig->bColumnsize ); |
| 232646 | 232773 | rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); |
| 232647 | | - if( rc==SQLITE_OK ){ |
| 232774 | + if( pLookup ){ |
| 232648 | 232775 | int bCorrupt = 1; |
| 232776 | + assert( rc==SQLITE_OK ); |
| 232649 | 232777 | sqlite3_bind_int64(pLookup, 1, iRowid); |
| 232650 | 232778 | if( SQLITE_ROW==sqlite3_step(pLookup) ){ |
| 232651 | 232779 | const u8 *aBlob = sqlite3_column_blob(pLookup, 0); |
| 232652 | 232780 | int nBlob = sqlite3_column_bytes(pLookup, 0); |
| 232653 | 232781 | if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){ |
| | @@ -232656,10 +232784,12 @@ |
| 232656 | 232784 | } |
| 232657 | 232785 | rc = sqlite3_reset(pLookup); |
| 232658 | 232786 | if( bCorrupt && rc==SQLITE_OK ){ |
| 232659 | 232787 | rc = FTS5_CORRUPT; |
| 232660 | 232788 | } |
| 232789 | + }else{ |
| 232790 | + assert( rc!=SQLITE_OK ); |
| 232661 | 232791 | } |
| 232662 | 232792 | |
| 232663 | 232793 | return rc; |
| 232664 | 232794 | } |
| 232665 | 232795 | |
| 232666 | 232796 | |