| | @@ -673,11 +673,11 @@ |
| 673 | 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | 675 | */ |
| 676 | 676 | #define SQLITE_VERSION "3.7.15" |
| 677 | 677 | #define SQLITE_VERSION_NUMBER 3007015 |
| 678 | | -#define SQLITE_SOURCE_ID "2012-10-09 01:39:25 01dc032b5bbd9c9ebb1965f176ca5d732cda85ea" |
| 678 | +#define SQLITE_SOURCE_ID "2012-10-26 19:22:45 e24ba5bee4424e99d0859ef652164ae1397a2378" |
| 679 | 679 | |
| 680 | 680 | /* |
| 681 | 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | 683 | ** |
| | @@ -8439,10 +8439,12 @@ |
| 8439 | 8439 | SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int); |
| 8440 | 8440 | |
| 8441 | 8441 | SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); |
| 8442 | 8442 | SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); |
| 8443 | 8443 | |
| 8444 | +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); |
| 8445 | + |
| 8444 | 8446 | /* |
| 8445 | 8447 | ** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta |
| 8446 | 8448 | ** should be one of the following values. The integer values are assigned |
| 8447 | 8449 | ** to constants so that the offset of the corresponding field in an |
| 8448 | 8450 | ** SQLite database header may be found using the following formula: |
| | @@ -8953,11 +8955,11 @@ |
| 8953 | 8955 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); |
| 8954 | 8956 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 8955 | 8957 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); |
| 8956 | 8958 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| 8957 | 8959 | SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); |
| 8958 | | -SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); |
| 8960 | +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*); |
| 8959 | 8961 | SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); |
| 8960 | 8962 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 8961 | 8963 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 8962 | 8964 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 8963 | 8965 | #ifdef SQLITE_DEBUG |
| | @@ -9143,15 +9145,18 @@ |
| 9143 | 9145 | SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); |
| 9144 | 9146 | SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); |
| 9145 | 9147 | SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); |
| 9146 | 9148 | SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); |
| 9147 | 9149 | |
| 9148 | | -SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); |
| 9149 | | -SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); |
| 9150 | | -SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); |
| 9151 | | -SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); |
| 9152 | | -SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); |
| 9150 | +#ifndef SQLITE_OMIT_WAL |
| 9151 | +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); |
| 9152 | +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); |
| 9153 | +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); |
| 9154 | +SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); |
| 9155 | +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); |
| 9156 | +#endif |
| 9157 | + |
| 9153 | 9158 | #ifdef SQLITE_ENABLE_ZIPVFS |
| 9154 | 9159 | SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); |
| 9155 | 9160 | #endif |
| 9156 | 9161 | |
| 9157 | 9162 | /* Functions used to query pager state and configuration. */ |
| | @@ -12220,12 +12225,14 @@ |
| 12220 | 12225 | SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); |
| 12221 | 12226 | SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); |
| 12222 | 12227 | SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); |
| 12223 | 12228 | SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); |
| 12224 | 12229 | SQLITE_PRIVATE const char *sqlite3JournalModename(int); |
| 12225 | | -SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); |
| 12226 | | -SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); |
| 12230 | +#ifndef SQLITE_OMIT_WAL |
| 12231 | +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); |
| 12232 | +SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); |
| 12233 | +#endif |
| 12227 | 12234 | |
| 12228 | 12235 | /* Declarations for functions in fkey.c. All of these are replaced by |
| 12229 | 12236 | ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign |
| 12230 | 12237 | ** key functionality is available. If OMIT_TRIGGER is defined but |
| 12231 | 12238 | ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In |
| | @@ -13704,11 +13711,11 @@ |
| 13704 | 13711 | struct Vdbe *pVdbe; /* Used to iterate through VMs */ |
| 13705 | 13712 | int nByte = 0; /* Used to accumulate return value */ |
| 13706 | 13713 | |
| 13707 | 13714 | db->pnBytesFreed = &nByte; |
| 13708 | 13715 | for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ |
| 13709 | | - sqlite3VdbeDeleteObject(db, pVdbe); |
| 13716 | + sqlite3VdbeClearObject(db, pVdbe); |
| 13710 | 13717 | } |
| 13711 | 13718 | db->pnBytesFreed = 0; |
| 13712 | 13719 | |
| 13713 | 13720 | *pHighwater = 0; |
| 13714 | 13721 | *pCurrent = nByte; |
| | @@ -22374,11 +22381,11 @@ |
| 22374 | 22381 | pEntry->count--; |
| 22375 | 22382 | assert( pEntry->count>=0 ); |
| 22376 | 22383 | } |
| 22377 | 22384 | sqlite3_free( elem ); |
| 22378 | 22385 | pH->count--; |
| 22379 | | - if( pH->count<=0 ){ |
| 22386 | + if( pH->count==0 ){ |
| 22380 | 22387 | assert( pH->first==0 ); |
| 22381 | 22388 | assert( pH->count==0 ); |
| 22382 | 22389 | sqlite3HashClear(pH); |
| 22383 | 22390 | } |
| 22384 | 22391 | } |
| | @@ -22844,10 +22851,14 @@ |
| 22844 | 22851 | void *lockingContext; /* Locking style specific state */ |
| 22845 | 22852 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 22846 | 22853 | const char *zPath; /* Name of the file */ |
| 22847 | 22854 | unixShm *pShm; /* Shared memory segment information */ |
| 22848 | 22855 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 22856 | +#ifdef __QNXNTO__ |
| 22857 | + int sectorSize; /* Device sector size */ |
| 22858 | + int deviceCharacteristics; /* Precomputed device characteristics */ |
| 22859 | +#endif |
| 22849 | 22860 | #if SQLITE_ENABLE_LOCKING_STYLE |
| 22850 | 22861 | int openFlags; /* The flags specified at open() */ |
| 22851 | 22862 | #endif |
| 22852 | 22863 | #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) |
| 22853 | 22864 | unsigned fsFlags; /* cached details from statfs() */ |
| | @@ -24920,17 +24931,17 @@ |
| 24920 | 24931 | |
| 24921 | 24932 | /* |
| 24922 | 24933 | ** Close a file. Make sure the lock has been released before closing. |
| 24923 | 24934 | */ |
| 24924 | 24935 | static int dotlockClose(sqlite3_file *id) { |
| 24925 | | - int rc; |
| 24936 | + int rc = SQLITE_OK; |
| 24926 | 24937 | if( id ){ |
| 24927 | 24938 | unixFile *pFile = (unixFile*)id; |
| 24928 | 24939 | dotlockUnlock(id, NO_LOCK); |
| 24929 | 24940 | sqlite3_free(pFile->lockingContext); |
| 24941 | + rc = closeUnixFile(id); |
| 24930 | 24942 | } |
| 24931 | | - rc = closeUnixFile(id); |
| 24932 | 24943 | return rc; |
| 24933 | 24944 | } |
| 24934 | 24945 | /****************** End of the dot-file lock implementation ******************* |
| 24935 | 24946 | ******************************************************************************/ |
| 24936 | 24947 | |
| | @@ -25130,14 +25141,16 @@ |
| 25130 | 25141 | |
| 25131 | 25142 | /* |
| 25132 | 25143 | ** Close a file. |
| 25133 | 25144 | */ |
| 25134 | 25145 | static int flockClose(sqlite3_file *id) { |
| 25146 | + int rc = SQLITE_OK; |
| 25135 | 25147 | if( id ){ |
| 25136 | 25148 | flockUnlock(id, NO_LOCK); |
| 25149 | + rc = closeUnixFile(id); |
| 25137 | 25150 | } |
| 25138 | | - return closeUnixFile(id); |
| 25151 | + return rc; |
| 25139 | 25152 | } |
| 25140 | 25153 | |
| 25141 | 25154 | #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ |
| 25142 | 25155 | |
| 25143 | 25156 | /******************* End of the flock lock implementation ********************* |
| | @@ -26470,14 +26483,96 @@ |
| 26470 | 26483 | ** SQLite code assumes this function cannot fail. It also assumes that |
| 26471 | 26484 | ** if two files are created in the same file-system directory (i.e. |
| 26472 | 26485 | ** a database and its journal file) that the sector size will be the |
| 26473 | 26486 | ** same for both. |
| 26474 | 26487 | */ |
| 26475 | | -static int unixSectorSize(sqlite3_file *pFile){ |
| 26476 | | - (void)pFile; |
| 26488 | +#ifndef __QNXNTO__ |
| 26489 | +static int unixSectorSize(sqlite3_file *NotUsed){ |
| 26490 | + UNUSED_PARAMETER(NotUsed); |
| 26477 | 26491 | return SQLITE_DEFAULT_SECTOR_SIZE; |
| 26478 | 26492 | } |
| 26493 | +#endif |
| 26494 | + |
| 26495 | +/* |
| 26496 | +** The following version of unixSectorSize() is optimized for QNX. |
| 26497 | +*/ |
| 26498 | +#ifdef __QNXNTO__ |
| 26499 | +#include <sys/dcmd_blk.h> |
| 26500 | +#include <sys/statvfs.h> |
| 26501 | +static int unixSectorSize(sqlite3_file *id){ |
| 26502 | + unixFile *pFile = (unixFile*)id; |
| 26503 | + if( pFile->sectorSize == 0 ){ |
| 26504 | + struct statvfs fsInfo; |
| 26505 | + |
| 26506 | + /* Set defaults for non-supported filesystems */ |
| 26507 | + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; |
| 26508 | + pFile->deviceCharacteristics = 0; |
| 26509 | + if( fstatvfs(pFile->h, &fsInfo) == -1 ) { |
| 26510 | + return pFile->sectorSize; |
| 26511 | + } |
| 26512 | + |
| 26513 | + if( !strcmp(fsInfo.f_basetype, "tmp") ) { |
| 26514 | + pFile->sectorSize = fsInfo.f_bsize; |
| 26515 | + pFile->deviceCharacteristics = |
| 26516 | + SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */ |
| 26517 | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until |
| 26518 | + ** the write succeeds */ |
| 26519 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 26520 | + ** so it is ordered */ |
| 26521 | + 0; |
| 26522 | + }else if( strstr(fsInfo.f_basetype, "etfs") ){ |
| 26523 | + pFile->sectorSize = fsInfo.f_bsize; |
| 26524 | + pFile->deviceCharacteristics = |
| 26525 | + /* etfs cluster size writes are atomic */ |
| 26526 | + (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) | |
| 26527 | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until |
| 26528 | + ** the write succeeds */ |
| 26529 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 26530 | + ** so it is ordered */ |
| 26531 | + 0; |
| 26532 | + }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){ |
| 26533 | + pFile->sectorSize = fsInfo.f_bsize; |
| 26534 | + pFile->deviceCharacteristics = |
| 26535 | + SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */ |
| 26536 | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until |
| 26537 | + ** the write succeeds */ |
| 26538 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 26539 | + ** so it is ordered */ |
| 26540 | + 0; |
| 26541 | + }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ |
| 26542 | + pFile->sectorSize = fsInfo.f_bsize; |
| 26543 | + pFile->deviceCharacteristics = |
| 26544 | + /* full bitset of atomics from max sector size and smaller */ |
| 26545 | + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | |
| 26546 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 26547 | + ** so it is ordered */ |
| 26548 | + 0; |
| 26549 | + }else if( strstr(fsInfo.f_basetype, "dos") ){ |
| 26550 | + pFile->sectorSize = fsInfo.f_bsize; |
| 26551 | + pFile->deviceCharacteristics = |
| 26552 | + /* full bitset of atomics from max sector size and smaller */ |
| 26553 | + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | |
| 26554 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 26555 | + ** so it is ordered */ |
| 26556 | + 0; |
| 26557 | + }else{ |
| 26558 | + pFile->deviceCharacteristics = |
| 26559 | + SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ |
| 26560 | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until |
| 26561 | + ** the write succeeds */ |
| 26562 | + 0; |
| 26563 | + } |
| 26564 | + } |
| 26565 | + /* Last chance verification. If the sector size isn't a multiple of 512 |
| 26566 | + ** then it isn't valid.*/ |
| 26567 | + if( pFile->sectorSize % 512 != 0 ){ |
| 26568 | + pFile->deviceCharacteristics = 0; |
| 26569 | + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; |
| 26570 | + } |
| 26571 | + return pFile->sectorSize; |
| 26572 | +} |
| 26573 | +#endif /* __QNXNTO__ */ |
| 26479 | 26574 | |
| 26480 | 26575 | /* |
| 26481 | 26576 | ** Return the device characteristics for the file. |
| 26482 | 26577 | ** |
| 26483 | 26578 | ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. |
| | @@ -26490,15 +26585,19 @@ |
| 26490 | 26585 | ** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control |
| 26491 | 26586 | ** available to turn it off and URI query parameter available to turn it off. |
| 26492 | 26587 | */ |
| 26493 | 26588 | static int unixDeviceCharacteristics(sqlite3_file *id){ |
| 26494 | 26589 | unixFile *p = (unixFile*)id; |
| 26590 | + int rc = 0; |
| 26591 | +#ifdef __QNXNTO__ |
| 26592 | + if( p->sectorSize==0 ) unixSectorSize(id); |
| 26593 | + rc = p->deviceCharacteristics; |
| 26594 | +#endif |
| 26495 | 26595 | if( p->ctrlFlags & UNIXFILE_PSOW ){ |
| 26496 | | - return SQLITE_IOCAP_POWERSAFE_OVERWRITE; |
| 26497 | | - }else{ |
| 26498 | | - return 0; |
| 26596 | + rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; |
| 26499 | 26597 | } |
| 26598 | + return rc; |
| 26500 | 26599 | } |
| 26501 | 26600 | |
| 26502 | 26601 | #ifndef SQLITE_OMIT_WAL |
| 26503 | 26602 | |
| 26504 | 26603 | |
| | @@ -26932,11 +27031,11 @@ |
| 26932 | 27031 | while(pShmNode->nRegion<=iRegion){ |
| 26933 | 27032 | void *pMem; |
| 26934 | 27033 | if( pShmNode->h>=0 ){ |
| 26935 | 27034 | pMem = mmap(0, szRegion, |
| 26936 | 27035 | pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 26937 | | - MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 27036 | + MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion |
| 26938 | 27037 | ); |
| 26939 | 27038 | if( pMem==MAP_FAILED ){ |
| 26940 | 27039 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| 26941 | 27040 | goto shmpage_out; |
| 26942 | 27041 | } |
| | @@ -32130,11 +32229,12 @@ |
| 32130 | 32229 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ |
| 32131 | 32230 | #endif |
| 32132 | 32231 | if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32133 | 32232 | break; |
| 32134 | 32233 | } |
| 32135 | | - if( nWrite<=0 ){ |
| 32234 | + assert( nWrite==0 || nWrite<=(DWORD)nRem ); |
| 32235 | + if( nWrite==0 || nWrite>(DWORD)nRem ){ |
| 32136 | 32236 | lastErrno = osGetLastError(); |
| 32137 | 32237 | break; |
| 32138 | 32238 | } |
| 32139 | 32239 | #if !SQLITE_OS_WINCE |
| 32140 | 32240 | offset += nWrite; |
| | @@ -42790,11 +42890,11 @@ |
| 42790 | 42890 | UNUSED_PARAMETER(isDirectMode); |
| 42791 | 42891 | #else |
| 42792 | 42892 | # define DIRECT_MODE isDirectMode |
| 42793 | 42893 | #endif |
| 42794 | 42894 | |
| 42795 | | - if( !pPager->changeCountDone && pPager->dbSize>0 ){ |
| 42895 | + if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ |
| 42796 | 42896 | PgHdr *pPgHdr; /* Reference to page 1 */ |
| 42797 | 42897 | |
| 42798 | 42898 | assert( !pPager->tempFile && isOpen(pPager->fd) ); |
| 42799 | 42899 | |
| 42800 | 42900 | /* Open page 1 of the file for writing. */ |
| | @@ -43010,19 +43110,18 @@ |
| 43010 | 43110 | #endif |
| 43011 | 43111 | if( rc!=SQLITE_OK ) goto commit_phase_one_exit; |
| 43012 | 43112 | |
| 43013 | 43113 | /* If this transaction has made the database smaller, then all pages |
| 43014 | 43114 | ** being discarded by the truncation must be written to the journal |
| 43015 | | - ** file. This can only happen in auto-vacuum mode. |
| 43115 | + ** file. |
| 43016 | 43116 | ** |
| 43017 | 43117 | ** Before reading the pages with page numbers larger than the |
| 43018 | 43118 | ** current value of Pager.dbSize, set dbSize back to the value |
| 43019 | 43119 | ** that it took at the start of the transaction. Otherwise, the |
| 43020 | 43120 | ** calls to sqlite3PagerGet() return zeroed pages instead of |
| 43021 | 43121 | ** reading data from the database file. |
| 43022 | 43122 | */ |
| 43023 | | - #ifndef SQLITE_OMIT_AUTOVACUUM |
| 43024 | 43123 | if( pPager->dbSize<pPager->dbOrigSize |
| 43025 | 43124 | && pPager->journalMode!=PAGER_JOURNALMODE_OFF |
| 43026 | 43125 | ){ |
| 43027 | 43126 | Pgno i; /* Iterator variable */ |
| 43028 | 43127 | const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */ |
| | @@ -43038,11 +43137,10 @@ |
| 43038 | 43137 | if( rc!=SQLITE_OK ) goto commit_phase_one_exit; |
| 43039 | 43138 | } |
| 43040 | 43139 | } |
| 43041 | 43140 | pPager->dbSize = dbSize; |
| 43042 | 43141 | } |
| 43043 | | - #endif |
| 43044 | 43142 | |
| 43045 | 43143 | /* Write the master journal name into the journal file. If a master |
| 43046 | 43144 | ** journal file name has already been written to the journal file, |
| 43047 | 43145 | ** or if zMaster is NULL (no master journal), then this call is a no-op. |
| 43048 | 43146 | */ |
| | @@ -44041,10 +44139,12 @@ |
| 44041 | 44139 | } |
| 44042 | 44140 | } |
| 44043 | 44141 | return rc; |
| 44044 | 44142 | } |
| 44045 | 44143 | |
| 44144 | +#endif /* !SQLITE_OMIT_WAL */ |
| 44145 | + |
| 44046 | 44146 | #ifdef SQLITE_ENABLE_ZIPVFS |
| 44047 | 44147 | /* |
| 44048 | 44148 | ** A read-lock must be held on the pager when this function is called. If |
| 44049 | 44149 | ** the pager is in WAL mode and the WAL file currently contains one or more |
| 44050 | 44150 | ** frames, return the size in bytes of the page images stored within the |
| | @@ -44070,12 +44170,10 @@ |
| 44070 | 44170 | CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); |
| 44071 | 44171 | return aData; |
| 44072 | 44172 | } |
| 44073 | 44173 | #endif /* SQLITE_HAS_CODEC */ |
| 44074 | 44174 | |
| 44075 | | -#endif /* !SQLITE_OMIT_WAL */ |
| 44076 | | - |
| 44077 | 44175 | #endif /* SQLITE_OMIT_DISKIO */ |
| 44078 | 44176 | |
| 44079 | 44177 | /************** End of pager.c ***********************************************/ |
| 44080 | 44178 | /************** Begin file wal.c *********************************************/ |
| 44081 | 44179 | /* |
| | @@ -46595,11 +46693,11 @@ |
| 46595 | 46693 | ** committed. As a result, the call to xUndo may not fail. |
| 46596 | 46694 | */ |
| 46597 | 46695 | assert( walFramePgno(pWal, iFrame)!=1 ); |
| 46598 | 46696 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); |
| 46599 | 46697 | } |
| 46600 | | - walCleanupHash(pWal); |
| 46698 | + if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); |
| 46601 | 46699 | } |
| 46602 | 46700 | assert( rc==SQLITE_OK ); |
| 46603 | 46701 | return rc; |
| 46604 | 46702 | } |
| 46605 | 46703 | |
| | @@ -50648,10 +50746,24 @@ |
| 50648 | 50746 | #endif |
| 50649 | 50747 | pBt->nPage = 1; |
| 50650 | 50748 | data[31] = 1; |
| 50651 | 50749 | return SQLITE_OK; |
| 50652 | 50750 | } |
| 50751 | + |
| 50752 | +/* |
| 50753 | +** Initialize the first page of the database file (creating a database |
| 50754 | +** consisting of a single page and no schema objects). Return SQLITE_OK |
| 50755 | +** if successful, or an SQLite error code otherwise. |
| 50756 | +*/ |
| 50757 | +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ |
| 50758 | + int rc; |
| 50759 | + sqlite3BtreeEnter(p); |
| 50760 | + p->pBt->nPage = 0; |
| 50761 | + rc = newDatabase(p->pBt); |
| 50762 | + sqlite3BtreeLeave(p); |
| 50763 | + return rc; |
| 50764 | +} |
| 50653 | 50765 | |
| 50654 | 50766 | /* |
| 50655 | 50767 | ** Attempt to start a new transaction. A write-transaction |
| 50656 | 50768 | ** is started if the second argument is nonzero, otherwise a read- |
| 50657 | 50769 | ** transaction. If the second argument is 2 or more and exclusive |
| | @@ -53848,11 +53960,11 @@ |
| 53848 | 53960 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 53849 | 53961 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| 53850 | 53962 | assert( pPage->nOverflow==1 ); |
| 53851 | 53963 | |
| 53852 | 53964 | /* This error condition is now caught prior to reaching this function */ |
| 53853 | | - if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT; |
| 53965 | + if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; |
| 53854 | 53966 | |
| 53855 | 53967 | /* Allocate a new page. This page will become the right-sibling of |
| 53856 | 53968 | ** pPage. Make the parent page writable, so that the new divider cell |
| 53857 | 53969 | ** may be inserted. If both these operations are successful, proceed. |
| 53858 | 53970 | */ |
| | @@ -56866,11 +56978,17 @@ |
| 56866 | 56978 | ** is to make sure that the schema-version really does change in |
| 56867 | 56979 | ** the case where the source and destination databases have the |
| 56868 | 56980 | ** same schema version. |
| 56869 | 56981 | */ |
| 56870 | 56982 | if( rc==SQLITE_DONE ){ |
| 56871 | | - rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); |
| 56983 | + if( nSrcPage==0 ){ |
| 56984 | + rc = sqlite3BtreeNewDb(p->pDest); |
| 56985 | + nSrcPage = 1; |
| 56986 | + } |
| 56987 | + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ |
| 56988 | + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); |
| 56989 | + } |
| 56872 | 56990 | if( rc==SQLITE_OK ){ |
| 56873 | 56991 | if( p->pDestDb ){ |
| 56874 | 56992 | sqlite3ResetAllSchemasOfConnection(p->pDestDb); |
| 56875 | 56993 | } |
| 56876 | 56994 | if( destMode==PAGER_JOURNALMODE_WAL ){ |
| | @@ -56900,10 +57018,11 @@ |
| 56900 | 57018 | nDestTruncate--; |
| 56901 | 57019 | } |
| 56902 | 57020 | }else{ |
| 56903 | 57021 | nDestTruncate = nSrcPage * (pgszSrc/pgszDest); |
| 56904 | 57022 | } |
| 57023 | + assert( nDestTruncate>0 ); |
| 56905 | 57024 | sqlite3PagerTruncateImage(pDestPager, nDestTruncate); |
| 56906 | 57025 | |
| 56907 | 57026 | if( pgszSrc<pgszDest ){ |
| 56908 | 57027 | /* If the source page-size is smaller than the destination page-size, |
| 56909 | 57028 | ** two extra things may need to happen: |
| | @@ -56918,11 +57037,12 @@ |
| 56918 | 57037 | sqlite3_file * const pFile = sqlite3PagerFile(pDestPager); |
| 56919 | 57038 | i64 iOff; |
| 56920 | 57039 | i64 iEnd; |
| 56921 | 57040 | |
| 56922 | 57041 | assert( pFile ); |
| 56923 | | - assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || ( |
| 57042 | + assert( nDestTruncate==0 |
| 57043 | + || (i64)nDestTruncate*(i64)pgszDest >= iSize || ( |
| 56924 | 57044 | nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) |
| 56925 | 57045 | && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest |
| 56926 | 57046 | )); |
| 56927 | 57047 | |
| 56928 | 57048 | /* This call ensures that all data required to recreate the original |
| | @@ -60769,16 +60889,18 @@ |
| 60769 | 60889 | } |
| 60770 | 60890 | } |
| 60771 | 60891 | } |
| 60772 | 60892 | |
| 60773 | 60893 | /* |
| 60774 | | -** Free all memory associated with the Vdbe passed as the second argument. |
| 60894 | +** Free all memory associated with the Vdbe passed as the second argument, |
| 60895 | +** except for object itself, which is preserved. |
| 60896 | +** |
| 60775 | 60897 | ** The difference between this function and sqlite3VdbeDelete() is that |
| 60776 | 60898 | ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with |
| 60777 | | -** the database connection. |
| 60899 | +** the database connection and frees the object itself. |
| 60778 | 60900 | */ |
| 60779 | | -SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ |
| 60901 | +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ |
| 60780 | 60902 | SubProgram *pSub, *pNext; |
| 60781 | 60903 | int i; |
| 60782 | 60904 | assert( p->db==0 || p->db==db ); |
| 60783 | 60905 | releaseMemArray(p->aVar, p->nVar); |
| 60784 | 60906 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); |
| | @@ -60795,11 +60917,10 @@ |
| 60795 | 60917 | sqlite3DbFree(db, p->pFree); |
| 60796 | 60918 | #if defined(SQLITE_ENABLE_TREE_EXPLAIN) |
| 60797 | 60919 | sqlite3DbFree(db, p->zExplain); |
| 60798 | 60920 | sqlite3DbFree(db, p->pExplain); |
| 60799 | 60921 | #endif |
| 60800 | | - sqlite3DbFree(db, p); |
| 60801 | 60922 | } |
| 60802 | 60923 | |
| 60803 | 60924 | /* |
| 60804 | 60925 | ** Delete an entire VDBE. |
| 60805 | 60926 | */ |
| | @@ -60807,10 +60928,11 @@ |
| 60807 | 60928 | sqlite3 *db; |
| 60808 | 60929 | |
| 60809 | 60930 | if( NEVER(p==0) ) return; |
| 60810 | 60931 | db = p->db; |
| 60811 | 60932 | assert( sqlite3_mutex_held(db->mutex) ); |
| 60933 | + sqlite3VdbeClearObject(db, p); |
| 60812 | 60934 | if( p->pPrev ){ |
| 60813 | 60935 | p->pPrev->pNext = p->pNext; |
| 60814 | 60936 | }else{ |
| 60815 | 60937 | assert( db->pVdbe==p ); |
| 60816 | 60938 | db->pVdbe = p->pNext; |
| | @@ -60818,11 +60940,11 @@ |
| 60818 | 60940 | if( p->pNext ){ |
| 60819 | 60941 | p->pNext->pPrev = p->pPrev; |
| 60820 | 60942 | } |
| 60821 | 60943 | p->magic = VDBE_MAGIC_DEAD; |
| 60822 | 60944 | p->db = 0; |
| 60823 | | - sqlite3VdbeDeleteObject(db, p); |
| 60945 | + sqlite3DbFree(db, p); |
| 60824 | 60946 | } |
| 60825 | 60947 | |
| 60826 | 60948 | /* |
| 60827 | 60949 | ** Make sure the cursor p is ready to read or write the row to which it |
| 60828 | 60950 | ** was last positioned. Return an error code if an OOM fault or I/O error |
| | @@ -70730,12 +70852,15 @@ |
| 70730 | 70852 | if( iBuf==0 ){ |
| 70731 | 70853 | int nRead; /* Bytes to read from disk */ |
| 70732 | 70854 | int rc; /* sqlite3OsRead() return code */ |
| 70733 | 70855 | |
| 70734 | 70856 | /* Determine how many bytes of data to read. */ |
| 70735 | | - nRead = (int)(p->iEof - p->iReadOff); |
| 70736 | | - if( nRead>p->nBuffer ) nRead = p->nBuffer; |
| 70857 | + if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ |
| 70858 | + nRead = p->nBuffer; |
| 70859 | + }else{ |
| 70860 | + nRead = (int)(p->iEof - p->iReadOff); |
| 70861 | + } |
| 70737 | 70862 | assert( nRead>0 ); |
| 70738 | 70863 | |
| 70739 | 70864 | /* Read data from the file. Return early if an error occurs. */ |
| 70740 | 70865 | rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff); |
| 70741 | 70866 | assert( rc!=SQLITE_IOERR_SHORT_READ ); |
| | @@ -72415,11 +72540,11 @@ |
| 72415 | 72540 | Schema *pSchema = 0; /* Schema of the expression */ |
| 72416 | 72541 | int isTrigger = 0; |
| 72417 | 72542 | |
| 72418 | 72543 | assert( pNC ); /* the name context cannot be NULL. */ |
| 72419 | 72544 | assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ |
| 72420 | | - assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 72545 | + assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 72421 | 72546 | |
| 72422 | 72547 | /* Initialize the node to no-match */ |
| 72423 | 72548 | pExpr->iTable = -1; |
| 72424 | 72549 | pExpr->pTab = 0; |
| 72425 | 72550 | ExprSetIrreducible(pExpr); |
| | @@ -82417,10 +82542,11 @@ |
| 82417 | 82542 | } |
| 82418 | 82543 | if( iLargest==0 ){ |
| 82419 | 82544 | return; |
| 82420 | 82545 | }else{ |
| 82421 | 82546 | int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
| 82547 | + assert( iDb>=0 && iDb<pParse->db->nDb ); |
| 82422 | 82548 | destroyRootPage(pParse, iLargest, iDb); |
| 82423 | 82549 | iDestroyed = iLargest; |
| 82424 | 82550 | } |
| 82425 | 82551 | } |
| 82426 | 82552 | #endif |
| | @@ -92962,17 +93088,16 @@ |
| 92962 | 93088 | pParse->nMem = 2; |
| 92963 | 93089 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC); |
| 92964 | 93090 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC); |
| 92965 | 93091 | for(i=0; i<db->nDb; i++){ |
| 92966 | 93092 | Btree *pBt; |
| 92967 | | - Pager *pPager; |
| 92968 | 93093 | const char *zState = "unknown"; |
| 92969 | 93094 | int j; |
| 92970 | 93095 | if( db->aDb[i].zName==0 ) continue; |
| 92971 | 93096 | sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC); |
| 92972 | 93097 | pBt = db->aDb[i].pBt; |
| 92973 | | - if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ |
| 93098 | + if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ |
| 92974 | 93099 | zState = "closed"; |
| 92975 | 93100 | }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, |
| 92976 | 93101 | SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ |
| 92977 | 93102 | zState = azLockName[j]; |
| 92978 | 93103 | } |
| | @@ -97007,14 +97132,13 @@ |
| 97007 | 97132 | ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". |
| 97008 | 97133 | */ |
| 97009 | 97134 | pList = pParent->pEList; |
| 97010 | 97135 | for(i=0; i<pList->nExpr; i++){ |
| 97011 | 97136 | if( pList->a[i].zName==0 ){ |
| 97012 | | - const char *zSpan = pList->a[i].zSpan; |
| 97013 | | - if( ALWAYS(zSpan) ){ |
| 97014 | | - pList->a[i].zName = sqlite3DbStrDup(db, zSpan); |
| 97015 | | - } |
| 97137 | + char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan); |
| 97138 | + sqlite3Dequote(zName); |
| 97139 | + pList->a[i].zName = zName; |
| 97016 | 97140 | } |
| 97017 | 97141 | } |
| 97018 | 97142 | substExprList(db, pParent->pEList, iParent, pSub->pEList); |
| 97019 | 97143 | if( isAgg ){ |
| 97020 | 97144 | substExprList(db, pParent->pGroupBy, iParent, pSub->pEList); |
| | @@ -100655,10 +100779,11 @@ |
| 100655 | 100779 | */ |
| 100656 | 100780 | SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){ |
| 100657 | 100781 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 100658 | 100782 | if( v ){ |
| 100659 | 100783 | sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); |
| 100784 | + sqlite3VdbeUsesBtree(v, 0); |
| 100660 | 100785 | } |
| 100661 | 100786 | return; |
| 100662 | 100787 | } |
| 100663 | 100788 | |
| 100664 | 100789 | /* |
| | @@ -101182,13 +101307,12 @@ |
| 101182 | 101307 | */ |
| 101183 | 101308 | SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ |
| 101184 | 101309 | if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); |
| 101185 | 101310 | if( p->azModuleArg ){ |
| 101186 | 101311 | int i; |
| 101187 | | - assert( p->nModuleArg<2 || p->azModuleArg[1]==0 ); |
| 101188 | 101312 | for(i=0; i<p->nModuleArg; i++){ |
| 101189 | | - sqlite3DbFree(db, p->azModuleArg[i]); |
| 101313 | + if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); |
| 101190 | 101314 | } |
| 101191 | 101315 | sqlite3DbFree(db, p->azModuleArg); |
| 101192 | 101316 | } |
| 101193 | 101317 | } |
| 101194 | 101318 | |
| | @@ -101415,11 +101539,10 @@ |
| 101415 | 101539 | return SQLITE_NOMEM; |
| 101416 | 101540 | } |
| 101417 | 101541 | pVTable->db = db; |
| 101418 | 101542 | pVTable->pMod = pMod; |
| 101419 | 101543 | |
| 101420 | | - assert( pTab->azModuleArg[1]==0 ); |
| 101421 | 101544 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 101422 | 101545 | pTab->azModuleArg[1] = db->aDb[iDb].zName; |
| 101423 | 101546 | |
| 101424 | 101547 | /* Invoke the virtual table constructor */ |
| 101425 | 101548 | assert( &db->pVtabCtx ); |
| | @@ -101429,11 +101552,10 @@ |
| 101429 | 101552 | pPriorCtx = db->pVtabCtx; |
| 101430 | 101553 | db->pVtabCtx = &sCtx; |
| 101431 | 101554 | rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); |
| 101432 | 101555 | db->pVtabCtx = pPriorCtx; |
| 101433 | 101556 | if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; |
| 101434 | | - pTab->azModuleArg[1] = 0; |
| 101435 | 101557 | |
| 101436 | 101558 | if( SQLITE_OK!=rc ){ |
| 101437 | 101559 | if( zErr==0 ){ |
| 101438 | 101560 | *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); |
| 101439 | 101561 | }else { |
| | @@ -103838,11 +103960,13 @@ |
| 103838 | 103960 | } |
| 103839 | 103961 | if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){ |
| 103840 | 103962 | /* Automatic indices are disabled at run-time */ |
| 103841 | 103963 | return; |
| 103842 | 103964 | } |
| 103843 | | - if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ |
| 103965 | + if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 |
| 103966 | + && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0 |
| 103967 | + ){ |
| 103844 | 103968 | /* We already have some kind of index in use for this query. */ |
| 103845 | 103969 | return; |
| 103846 | 103970 | } |
| 103847 | 103971 | if( pSrc->notIndexed ){ |
| 103848 | 103972 | /* The NOT INDEXED clause appears in the SQL. */ |
| | @@ -104794,18 +104918,10 @@ |
| 104794 | 104918 | ** by the index pIdx and other indices in outer loops. |
| 104795 | 104919 | ** |
| 104796 | 104920 | ** The table being queried has a cursor number of "base". pIdx is the |
| 104797 | 104921 | ** index that is postulated for use to access the table. |
| 104798 | 104922 | ** |
| 104799 | | -** nEqCol is the number of columns of pIdx that are used as equality |
| 104800 | | -** constraints and where the other side of the == is an ordered column |
| 104801 | | -** or constant. An "order column" in the previous sentence means a column |
| 104802 | | -** in table from an outer loop whose values will always appear in the |
| 104803 | | -** correct order due to othre index, or because the outer loop generates |
| 104804 | | -** a unique result. Any of the first nEqCol columns of pIdx may be missing |
| 104805 | | -** from the ORDER BY clause and the match can still be a success. |
| 104806 | | -** |
| 104807 | 104923 | ** The *pbRev value is set to 0 order 1 depending on whether or not |
| 104808 | 104924 | ** pIdx should be run in the forward order or in reverse order. |
| 104809 | 104925 | */ |
| 104810 | 104926 | static int isSortingIndex( |
| 104811 | 104927 | WhereBestIdx *p, /* Best index search context */ |
| | @@ -104917,41 +105033,50 @@ |
| 104917 | 105033 | } |
| 104918 | 105034 | |
| 104919 | 105035 | /* termSortOrder is 0 or 1 for whether or not the access loop should |
| 104920 | 105036 | ** run forward or backwards (respectively) in order to satisfy this |
| 104921 | 105037 | ** term of the ORDER BY clause. */ |
| 105038 | + assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 ); |
| 105039 | + assert( iSortOrder==0 || iSortOrder==1 ); |
| 104922 | 105040 | termSortOrder = iSortOrder ^ pOBItem->sortOrder; |
| 104923 | 105041 | |
| 104924 | 105042 | /* If X is the column in the index and ORDER BY clause, check to see |
| 104925 | 105043 | ** if there are any X= or X IS NULL constraints in the WHERE clause. */ |
| 104926 | 105044 | pConstraint = findTerm(p->pWC, base, iColumn, p->notReady, |
| 104927 | 105045 | WO_EQ|WO_ISNULL|WO_IN, pIdx); |
| 104928 | 105046 | if( pConstraint==0 ){ |
| 104929 | 105047 | isEq = 0; |
| 104930 | 105048 | }else if( pConstraint->eOperator==WO_IN ){ |
| 105049 | + /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY |
| 105050 | + ** because we do not know in what order the values on the RHS of the IN |
| 105051 | + ** operator will occur. */ |
| 104931 | 105052 | break; |
| 104932 | 105053 | }else if( pConstraint->eOperator==WO_ISNULL ){ |
| 104933 | 105054 | uniqueNotNull = 0; |
| 104934 | | - isEq = 1; |
| 105055 | + isEq = 1; /* "X IS NULL" means X has only a single value */ |
| 104935 | 105056 | }else if( pConstraint->prereqRight==0 ){ |
| 104936 | | - isEq = 1; |
| 105057 | + isEq = 1; /* Constraint "X=constant" means X has only a single value */ |
| 104937 | 105058 | }else{ |
| 104938 | 105059 | Expr *pRight = pConstraint->pExpr->pRight; |
| 104939 | 105060 | if( pRight->op==TK_COLUMN ){ |
| 104940 | 105061 | WHERETRACE((" .. isOrderedColumn(tab=%d,col=%d)", |
| 104941 | 105062 | pRight->iTable, pRight->iColumn)); |
| 104942 | 105063 | isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn); |
| 104943 | 105064 | WHERETRACE((" -> isEq=%d\n", isEq)); |
| 105065 | + |
| 105066 | + /* If the constraint is of the form X=Y where Y is an ordered value |
| 105067 | + ** in an outer loop, then make sure the sort order of Y matches the |
| 105068 | + ** sort order required for X. */ |
| 104944 | 105069 | if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){ |
| 105070 | + testcase( isEq==2 ); |
| 105071 | + testcase( isEq==3 ); |
| 104945 | 105072 | break; |
| 104946 | 105073 | } |
| 104947 | 105074 | }else{ |
| 104948 | | - isEq = 0; |
| 105075 | + isEq = 0; /* "X=expr" places no ordering constraints on X */ |
| 104949 | 105076 | } |
| 104950 | 105077 | } |
| 104951 | | - assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 ); |
| 104952 | | - assert( iSortOrder==0 || iSortOrder==1 ); |
| 104953 | 105078 | if( !isMatch ){ |
| 104954 | 105079 | if( isEq==0 ){ |
| 104955 | 105080 | break; |
| 104956 | 105081 | }else{ |
| 104957 | 105082 | continue; |
| | @@ -104966,11 +105091,14 @@ |
| 104966 | 105091 | j++; |
| 104967 | 105092 | pOBItem++; |
| 104968 | 105093 | if( iColumn<0 ){ |
| 104969 | 105094 | seenRowid = 1; |
| 104970 | 105095 | break; |
| 104971 | | - }else if( pTab->aCol[iColumn].notNull==0 && isEq==0 ){ |
| 105096 | + }else if( pTab->aCol[iColumn].notNull==0 && isEq!=1 ){ |
| 105097 | + testcase( isEq==0 ); |
| 105098 | + testcase( isEq==2 ); |
| 105099 | + testcase( isEq==3 ); |
| 104972 | 105100 | uniqueNotNull = 0; |
| 104973 | 105101 | } |
| 104974 | 105102 | } |
| 104975 | 105103 | |
| 104976 | 105104 | /* If we have not found at least one ORDER BY term that matches the |
| | @@ -106624,11 +106752,11 @@ |
| 106624 | 106752 | sqlite3WhereEnd(pSubWInfo); |
| 106625 | 106753 | } |
| 106626 | 106754 | } |
| 106627 | 106755 | } |
| 106628 | 106756 | pLevel->u.pCovidx = pCov; |
| 106629 | | - pLevel->iIdxCur = iCovCur; |
| 106757 | + if( pCov ) pLevel->iIdxCur = iCovCur; |
| 106630 | 106758 | if( pAndExpr ){ |
| 106631 | 106759 | pAndExpr->pLeft = 0; |
| 106632 | 106760 | sqlite3ExprDelete(pParse->db, pAndExpr); |
| 106633 | 106761 | } |
| 106634 | 106762 | sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); |
| | @@ -110720,10 +110848,11 @@ |
| 110720 | 110848 | /* (324) anylist ::= */ yytestcase(yyruleno==324); |
| 110721 | 110849 | /* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325); |
| 110722 | 110850 | /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326); |
| 110723 | 110851 | break; |
| 110724 | 110852 | }; |
| 110853 | + assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) ); |
| 110725 | 110854 | yygoto = yyRuleInfo[yyruleno].lhs; |
| 110726 | 110855 | yysize = yyRuleInfo[yyruleno].nrhs; |
| 110727 | 110856 | yypParser->yyidx -= yysize; |
| 110728 | 110857 | yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); |
| 110729 | 110858 | if( yyact < YYNSTATE ){ |
| | @@ -121244,39 +121373,43 @@ |
| 121244 | 121373 | /* Allocate temporary working space. */ |
| 121245 | 121374 | for(p=pExpr; p->pLeft; p=p->pLeft){ |
| 121246 | 121375 | nTmp += p->pRight->pPhrase->doclist.nList; |
| 121247 | 121376 | } |
| 121248 | 121377 | nTmp += p->pPhrase->doclist.nList; |
| 121249 | | - aTmp = sqlite3_malloc(nTmp*2); |
| 121250 | | - if( !aTmp ){ |
| 121251 | | - *pRc = SQLITE_NOMEM; |
| 121378 | + if( nTmp==0 ){ |
| 121252 | 121379 | res = 0; |
| 121253 | 121380 | }else{ |
| 121254 | | - char *aPoslist = p->pPhrase->doclist.pList; |
| 121255 | | - int nToken = p->pPhrase->nToken; |
| 121256 | | - |
| 121257 | | - for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ |
| 121258 | | - Fts3Phrase *pPhrase = p->pRight->pPhrase; |
| 121259 | | - int nNear = p->nNear; |
| 121260 | | - res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); |
| 121261 | | - } |
| 121262 | | - |
| 121263 | | - aPoslist = pExpr->pRight->pPhrase->doclist.pList; |
| 121264 | | - nToken = pExpr->pRight->pPhrase->nToken; |
| 121265 | | - for(p=pExpr->pLeft; p && res; p=p->pLeft){ |
| 121266 | | - int nNear; |
| 121267 | | - Fts3Phrase *pPhrase; |
| 121268 | | - assert( p->pParent && p->pParent->pLeft==p ); |
| 121269 | | - nNear = p->pParent->nNear; |
| 121270 | | - pPhrase = ( |
| 121271 | | - p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase |
| 121272 | | - ); |
| 121273 | | - res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); |
| 121274 | | - } |
| 121275 | | - } |
| 121276 | | - |
| 121277 | | - sqlite3_free(aTmp); |
| 121381 | + aTmp = sqlite3_malloc(nTmp*2); |
| 121382 | + if( !aTmp ){ |
| 121383 | + *pRc = SQLITE_NOMEM; |
| 121384 | + res = 0; |
| 121385 | + }else{ |
| 121386 | + char *aPoslist = p->pPhrase->doclist.pList; |
| 121387 | + int nToken = p->pPhrase->nToken; |
| 121388 | + |
| 121389 | + for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ |
| 121390 | + Fts3Phrase *pPhrase = p->pRight->pPhrase; |
| 121391 | + int nNear = p->nNear; |
| 121392 | + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); |
| 121393 | + } |
| 121394 | + |
| 121395 | + aPoslist = pExpr->pRight->pPhrase->doclist.pList; |
| 121396 | + nToken = pExpr->pRight->pPhrase->nToken; |
| 121397 | + for(p=pExpr->pLeft; p && res; p=p->pLeft){ |
| 121398 | + int nNear; |
| 121399 | + Fts3Phrase *pPhrase; |
| 121400 | + assert( p->pParent && p->pParent->pLeft==p ); |
| 121401 | + nNear = p->pParent->nNear; |
| 121402 | + pPhrase = ( |
| 121403 | + p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase |
| 121404 | + ); |
| 121405 | + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); |
| 121406 | + } |
| 121407 | + } |
| 121408 | + |
| 121409 | + sqlite3_free(aTmp); |
| 121410 | + } |
| 121278 | 121411 | } |
| 121279 | 121412 | |
| 121280 | 121413 | return res; |
| 121281 | 121414 | } |
| 121282 | 121415 | |
| | @@ -122510,11 +122643,11 @@ |
| 122510 | 122643 | int nConsumed = 0; |
| 122511 | 122644 | |
| 122512 | 122645 | rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); |
| 122513 | 122646 | if( rc==SQLITE_OK ){ |
| 122514 | 122647 | const char *zToken; |
| 122515 | | - int nToken, iStart, iEnd, iPosition; |
| 122648 | + int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; |
| 122516 | 122649 | int nByte; /* total space to allocate */ |
| 122517 | 122650 | |
| 122518 | 122651 | rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); |
| 122519 | 122652 | if( rc==SQLITE_OK ){ |
| 122520 | 122653 | nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; |
| | @@ -122625,11 +122758,11 @@ |
| 122625 | 122758 | pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); |
| 122626 | 122759 | if( rc==SQLITE_OK ){ |
| 122627 | 122760 | int ii; |
| 122628 | 122761 | for(ii=0; rc==SQLITE_OK; ii++){ |
| 122629 | 122762 | const char *zByte; |
| 122630 | | - int nByte, iBegin, iEnd, iPos; |
| 122763 | + int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0; |
| 122631 | 122764 | rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); |
| 122632 | 122765 | if( rc==SQLITE_OK ){ |
| 122633 | 122766 | Fts3PhraseToken *pToken; |
| 122634 | 122767 | |
| 122635 | 122768 | p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); |
| | @@ -124622,14 +124755,14 @@ |
| 124622 | 124755 | int nInput; |
| 124623 | 124756 | |
| 124624 | 124757 | const char *azArg[64]; |
| 124625 | 124758 | |
| 124626 | 124759 | const char *zToken; |
| 124627 | | - int nToken; |
| 124628 | | - int iStart; |
| 124629 | | - int iEnd; |
| 124630 | | - int iPos; |
| 124760 | + int nToken = 0; |
| 124761 | + int iStart = 0; |
| 124762 | + int iEnd = 0; |
| 124763 | + int iPos = 0; |
| 124631 | 124764 | int i; |
| 124632 | 124765 | |
| 124633 | 124766 | Tcl_Obj *pRet; |
| 124634 | 124767 | |
| 124635 | 124768 | if( argc<2 ){ |
| | @@ -125875,17 +126008,17 @@ |
| 125875 | 126008 | const char *zText, /* Text of document to be inserted */ |
| 125876 | 126009 | int iCol, /* Column into which text is being inserted */ |
| 125877 | 126010 | u32 *pnWord /* OUT: Number of tokens inserted */ |
| 125878 | 126011 | ){ |
| 125879 | 126012 | int rc; |
| 125880 | | - int iStart; |
| 125881 | | - int iEnd; |
| 125882 | | - int iPos; |
| 126013 | + int iStart = 0; |
| 126014 | + int iEnd = 0; |
| 126015 | + int iPos = 0; |
| 125883 | 126016 | int nWord = 0; |
| 125884 | 126017 | |
| 125885 | 126018 | char const *zToken; |
| 125886 | | - int nToken; |
| 126019 | + int nToken = 0; |
| 125887 | 126020 | |
| 125888 | 126021 | sqlite3_tokenizer *pTokenizer = p->pTokenizer; |
| 125889 | 126022 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; |
| 125890 | 126023 | sqlite3_tokenizer_cursor *pCsr; |
| 125891 | 126024 | int (*xNext)(sqlite3_tokenizer_cursor *pCursor, |
| | @@ -130030,13 +130163,13 @@ |
| 130030 | 130163 | sqlite3_tokenizer_cursor *pT = 0; |
| 130031 | 130164 | |
| 130032 | 130165 | rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT); |
| 130033 | 130166 | while( rc==SQLITE_OK ){ |
| 130034 | 130167 | char const *zToken; /* Buffer containing token */ |
| 130035 | | - int nToken; /* Number of bytes in token */ |
| 130036 | | - int iDum1, iDum2; /* Dummy variables */ |
| 130037 | | - int iPos; /* Position of token in zText */ |
| 130168 | + int nToken = 0; /* Number of bytes in token */ |
| 130169 | + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ |
| 130170 | + int iPos = 0; /* Position of token in zText */ |
| 130038 | 130171 | |
| 130039 | 130172 | rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); |
| 130040 | 130173 | if( rc==SQLITE_OK ){ |
| 130041 | 130174 | int i; |
| 130042 | 130175 | cksum2 = cksum2 ^ fts3ChecksumEntry( |
| | @@ -130199,13 +130332,13 @@ |
| 130199 | 130332 | sqlite3_tokenizer_cursor *pTC = 0; |
| 130200 | 130333 | |
| 130201 | 130334 | rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); |
| 130202 | 130335 | while( rc==SQLITE_OK ){ |
| 130203 | 130336 | char const *zToken; /* Buffer containing token */ |
| 130204 | | - int nToken; /* Number of bytes in token */ |
| 130205 | | - int iDum1, iDum2; /* Dummy variables */ |
| 130206 | | - int iPos; /* Position of token in zText */ |
| 130337 | + int nToken = 0; /* Number of bytes in token */ |
| 130338 | + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ |
| 130339 | + int iPos = 0; /* Position of token in zText */ |
| 130207 | 130340 | |
| 130208 | 130341 | rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); |
| 130209 | 130342 | for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 130210 | 130343 | Fts3PhraseToken *pPT = pDef->pToken; |
| 130211 | 130344 | if( (pDef->iCol>=p->nColumn || pDef->iCol==i) |
| | @@ -131069,11 +131202,11 @@ |
| 131069 | 131202 | rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); |
| 131070 | 131203 | if( rc!=SQLITE_OK ){ |
| 131071 | 131204 | return rc; |
| 131072 | 131205 | } |
| 131073 | 131206 | while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ |
| 131074 | | - const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3; |
| 131207 | + const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0; |
| 131075 | 131208 | rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); |
| 131076 | 131209 | } |
| 131077 | 131210 | pMod->xClose(pC); |
| 131078 | 131211 | if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; } |
| 131079 | 131212 | |
| | @@ -131113,12 +131246,10 @@ |
| 131113 | 131246 | int iPos = pFragment->iPos; /* First token of snippet */ |
| 131114 | 131247 | u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */ |
| 131115 | 131248 | int iCol = pFragment->iCol+1; /* Query column to extract text from */ |
| 131116 | 131249 | sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ |
| 131117 | 131250 | sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ |
| 131118 | | - const char *ZDUMMY; /* Dummy argument used with tokenizer */ |
| 131119 | | - int DUMMY1; /* Dummy argument used with tokenizer */ |
| 131120 | 131251 | |
| 131121 | 131252 | zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); |
| 131122 | 131253 | if( zDoc==0 ){ |
| 131123 | 131254 | if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ |
| 131124 | 131255 | return SQLITE_NOMEM; |
| | @@ -131133,14 +131264,27 @@ |
| 131133 | 131264 | if( rc!=SQLITE_OK ){ |
| 131134 | 131265 | return rc; |
| 131135 | 131266 | } |
| 131136 | 131267 | |
| 131137 | 131268 | while( rc==SQLITE_OK ){ |
| 131138 | | - int iBegin; /* Offset in zDoc of start of token */ |
| 131139 | | - int iFin; /* Offset in zDoc of end of token */ |
| 131140 | | - int isHighlight; /* True for highlighted terms */ |
| 131269 | + const char *ZDUMMY; /* Dummy argument used with tokenizer */ |
| 131270 | + int DUMMY1 = -1; /* Dummy argument used with tokenizer */ |
| 131271 | + int iBegin = 0; /* Offset in zDoc of start of token */ |
| 131272 | + int iFin = 0; /* Offset in zDoc of end of token */ |
| 131273 | + int isHighlight = 0; /* True for highlighted terms */ |
| 131141 | 131274 | |
| 131275 | + /* Variable DUMMY1 is initialized to a negative value above. Elsewhere |
| 131276 | + ** in the FTS code the variable that the third argument to xNext points to |
| 131277 | + ** is initialized to zero before the first (*but not necessarily |
| 131278 | + ** subsequent*) call to xNext(). This is done for a particular application |
| 131279 | + ** that needs to know whether or not the tokenizer is being used for |
| 131280 | + ** snippet generation or for some other purpose. |
| 131281 | + ** |
| 131282 | + ** Extreme care is required when writing code to depend on this |
| 131283 | + ** initialization. It is not a documented part of the tokenizer interface. |
| 131284 | + ** If a tokenizer is used directly by any code outside of FTS, this |
| 131285 | + ** convention might not be respected. */ |
| 131142 | 131286 | rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent); |
| 131143 | 131287 | if( rc!=SQLITE_OK ){ |
| 131144 | 131288 | if( rc==SQLITE_DONE ){ |
| 131145 | 131289 | /* Special case - the last token of the snippet is also the last token |
| 131146 | 131290 | ** of the column. Append any punctuation that occurred between the end |
| | @@ -131826,12 +131970,10 @@ |
| 131826 | 131970 | sqlite3_context *pCtx, /* SQLite function call context */ |
| 131827 | 131971 | Fts3Cursor *pCsr /* Cursor object */ |
| 131828 | 131972 | ){ |
| 131829 | 131973 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 131830 | 131974 | sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; |
| 131831 | | - const char *ZDUMMY; /* Dummy argument used with xNext() */ |
| 131832 | | - int NDUMMY; /* Dummy argument used with xNext() */ |
| 131833 | 131975 | int rc; /* Return Code */ |
| 131834 | 131976 | int nToken; /* Number of tokens in query */ |
| 131835 | 131977 | int iCol; /* Column currently being processed */ |
| 131836 | 131978 | StrBuffer res = {0, 0, 0}; /* Result string */ |
| 131837 | 131979 | TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */ |
| | @@ -131860,13 +132002,15 @@ |
| 131860 | 132002 | /* Loop through the table columns, appending offset information to |
| 131861 | 132003 | ** string-buffer res for each column. |
| 131862 | 132004 | */ |
| 131863 | 132005 | for(iCol=0; iCol<pTab->nColumn; iCol++){ |
| 131864 | 132006 | sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ |
| 131865 | | - int iStart; |
| 131866 | | - int iEnd; |
| 131867 | | - int iCurrent; |
| 132007 | + const char *ZDUMMY; /* Dummy argument used with xNext() */ |
| 132008 | + int NDUMMY = 0; /* Dummy argument used with xNext() */ |
| 132009 | + int iStart = 0; |
| 132010 | + int iEnd = 0; |
| 132011 | + int iCurrent = 0; |
| 131868 | 132012 | const char *zDoc; |
| 131869 | 132013 | int nDoc; |
| 131870 | 132014 | |
| 131871 | 132015 | /* Initialize the contents of sCtx.aTerm[] for column iCol. There is |
| 131872 | 132016 | ** no way that this operation can fail, so the return code from |
| | @@ -136745,19 +136889,19 @@ |
| 136745 | 136889 | nInput = strlen(zInput); |
| 136746 | 136890 | } |
| 136747 | 136891 | nChar = nInput+1; |
| 136748 | 136892 | pCsr = (IcuCursor *)sqlite3_malloc( |
| 136749 | 136893 | sizeof(IcuCursor) + /* IcuCursor */ |
| 136750 | | - nChar * sizeof(UChar) + /* IcuCursor.aChar[] */ |
| 136894 | + ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ |
| 136751 | 136895 | (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ |
| 136752 | 136896 | ); |
| 136753 | 136897 | if( !pCsr ){ |
| 136754 | 136898 | return SQLITE_NOMEM; |
| 136755 | 136899 | } |
| 136756 | 136900 | memset(pCsr, 0, sizeof(IcuCursor)); |
| 136757 | 136901 | pCsr->aChar = (UChar *)&pCsr[1]; |
| 136758 | | - pCsr->aOffset = (int *)&pCsr->aChar[nChar]; |
| 136902 | + pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; |
| 136759 | 136903 | |
| 136760 | 136904 | pCsr->aOffset[iOut] = iInput; |
| 136761 | 136905 | U8_NEXT(zInput, iInput, nInput, c); |
| 136762 | 136906 | while( c>0 ){ |
| 136763 | 136907 | int isError = 0; |
| 136764 | 136908 | |