| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.21.0. By combining all the individual C code files into this |
| 3 | +** version 3.22.0. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -1145,13 +1145,13 @@ |
| 1145 | 1145 | ** |
| 1146 | 1146 | ** See also: [sqlite3_libversion()], |
| 1147 | 1147 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 1148 | 1148 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 1149 | 1149 | */ |
| 1150 | | -#define SQLITE_VERSION "3.21.0" |
| 1151 | | -#define SQLITE_VERSION_NUMBER 3021000 |
| 1152 | | -#define SQLITE_SOURCE_ID "2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de48827" |
| 1150 | +#define SQLITE_VERSION "3.22.0" |
| 1151 | +#define SQLITE_VERSION_NUMBER 3022000 |
| 1152 | +#define SQLITE_SOURCE_ID "2017-11-14 19:34:22 00ec95fcd02bb415dabd7f25fee24856d45d6916c18b2728e97e9bb9b8322ba3" |
| 1153 | 1153 | |
| 1154 | 1154 | /* |
| 1155 | 1155 | ** CAPI3REF: Run-Time Library Version Numbers |
| 1156 | 1156 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 1157 | 1157 | ** |
| | @@ -1530,15 +1530,17 @@ |
| 1530 | 1530 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 1531 | 1531 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1532 | 1532 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1533 | 1533 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 1534 | 1534 | #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) |
| 1535 | +#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) |
| 1535 | 1536 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1536 | 1537 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1537 | 1538 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1538 | 1539 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 1539 | 1540 | #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) |
| 1541 | +#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) |
| 1540 | 1542 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| 1541 | 1543 | #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) |
| 1542 | 1544 | #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) |
| 1543 | 1545 | #define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) |
| 1544 | 1546 | #define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) |
| | @@ -2153,16 +2155,22 @@ |
| 2153 | 2155 | ** An instance of the sqlite3_vfs object defines the interface between |
| 2154 | 2156 | ** the SQLite core and the underlying operating system. The "vfs" |
| 2155 | 2157 | ** in the name of the object stands for "virtual file system". See |
| 2156 | 2158 | ** the [VFS | VFS documentation] for further information. |
| 2157 | 2159 | ** |
| 2158 | | -** The value of the iVersion field is initially 1 but may be larger in |
| 2159 | | -** future versions of SQLite. Additional fields may be appended to this |
| 2160 | | -** object when the iVersion value is increased. Note that the structure |
| 2161 | | -** of the sqlite3_vfs object changes in the transaction between |
| 2162 | | -** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not |
| 2163 | | -** modified. |
| 2160 | +** The VFS interface is sometimes extended by adding new methods onto |
| 2161 | +** the end. Each time such an extension occurs, the iVersion field |
| 2162 | +** is incremented. The iVersion value started out as 1 in |
| 2163 | +** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2 |
| 2164 | +** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased |
| 2165 | +** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields |
| 2166 | +** may be appended to the sqlite3_vfs object and the iVersion value |
| 2167 | +** may increase again in future versions of SQLite. |
| 2168 | +** Note that the structure |
| 2169 | +** of the sqlite3_vfs object changes in the transition from |
| 2170 | +** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] |
| 2171 | +** and yet the iVersion field was not modified. |
| 2164 | 2172 | ** |
| 2165 | 2173 | ** The szOsFile field is the size of the subclassed [sqlite3_file] |
| 2166 | 2174 | ** structure used by this VFS. mxPathname is the maximum length of |
| 2167 | 2175 | ** a pathname in this VFS. |
| 2168 | 2176 | ** |
| | @@ -16177,11 +16185,11 @@ |
| 16177 | 16185 | /* |
| 16178 | 16186 | ** The following are the meanings of bits in the Expr.flags field. |
| 16179 | 16187 | */ |
| 16180 | 16188 | #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ |
| 16181 | 16189 | #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ |
| 16182 | | - /* 0x000004 // available for use */ |
| 16190 | +#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ |
| 16183 | 16191 | /* 0x000008 // available for use */ |
| 16184 | 16192 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 16185 | 16193 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| 16186 | 16194 | #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ |
| 16187 | 16195 | #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ |
| | @@ -16201,13 +16209,14 @@ |
| 16201 | 16209 | #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ |
| 16202 | 16210 | #define EP_Alias 0x400000 /* Is an alias for a result set column */ |
| 16203 | 16211 | #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ |
| 16204 | 16212 | |
| 16205 | 16213 | /* |
| 16206 | | -** Combinations of two or more EP_* flags |
| 16214 | +** The EP_Propagate mask is a set of properties that automatically propagate |
| 16215 | +** upwards into parent nodes. |
| 16207 | 16216 | */ |
| 16208 | | -#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ |
| 16217 | +#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) |
| 16209 | 16218 | |
| 16210 | 16219 | /* |
| 16211 | 16220 | ** These macros can be used to test, set, or clear bits in the |
| 16212 | 16221 | ** Expr.flags field. |
| 16213 | 16222 | */ |
| | @@ -16483,10 +16492,11 @@ |
| 16483 | 16492 | #define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ |
| 16484 | 16493 | #define NC_HasAgg 0x0010 /* One or more aggregate functions seen */ |
| 16485 | 16494 | #define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ |
| 16486 | 16495 | #define NC_VarSelect 0x0040 /* A correlated subquery has been seen */ |
| 16487 | 16496 | #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ |
| 16497 | +#define NC_Complex 0x2000 /* True if a function or subquery seen */ |
| 16488 | 16498 | |
| 16489 | 16499 | /* |
| 16490 | 16500 | ** An instance of the following structure contains all information |
| 16491 | 16501 | ** needed to generate code for a single SELECT statement. |
| 16492 | 16502 | ** |
| | @@ -16553,10 +16563,11 @@ |
| 16553 | 16563 | #define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */ |
| 16554 | 16564 | #define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ |
| 16555 | 16565 | #define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ |
| 16556 | 16566 | #define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ |
| 16557 | 16567 | #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ |
| 16568 | +#define SF_ComplexResult 0x40000 /* Result set contains subquery or function */ |
| 16558 | 16569 | |
| 16559 | 16570 | |
| 16560 | 16571 | /* |
| 16561 | 16572 | ** The results of a SELECT can be distributed in several ways, as defined |
| 16562 | 16573 | ** by one of the following macros. The "SRT" prefix means "SELECT Result |
| | @@ -17536,12 +17547,12 @@ |
| 17536 | 17547 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); |
| 17537 | 17548 | SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); |
| 17538 | 17549 | #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) |
| 17539 | 17550 | SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*); |
| 17540 | 17551 | #endif |
| 17541 | | -SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); |
| 17542 | | -SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); |
| 17552 | +SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*, Expr*); |
| 17553 | +SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,Expr*); |
| 17543 | 17554 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); |
| 17544 | 17555 | SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); |
| 17545 | 17556 | SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); |
| 17546 | 17557 | SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); |
| 17547 | 17558 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); |
| | @@ -17661,11 +17672,11 @@ |
| 17661 | 17672 | SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); |
| 17662 | 17673 | SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); |
| 17663 | 17674 | SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); |
| 17664 | 17675 | |
| 17665 | 17676 | #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) |
| 17666 | | -SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int); |
| 17677 | +SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,Expr*,int); |
| 17667 | 17678 | #endif |
| 17668 | 17679 | |
| 17669 | 17680 | #ifndef SQLITE_OMIT_TRIGGER |
| 17670 | 17681 | SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, |
| 17671 | 17682 | Expr*,int, int); |
| | @@ -26625,12 +26636,19 @@ |
| 26625 | 26636 | sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); |
| 26626 | 26637 | va_start(ap,zFormat); |
| 26627 | 26638 | sqlite3VXPrintf(&acc, zFormat, ap); |
| 26628 | 26639 | va_end(ap); |
| 26629 | 26640 | sqlite3StrAccumFinish(&acc); |
| 26641 | +#ifdef SQLITE_OS_TRACE_PROC |
| 26642 | + { |
| 26643 | + extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf); |
| 26644 | + SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf)); |
| 26645 | + } |
| 26646 | +#else |
| 26630 | 26647 | fprintf(stdout,"%s", zBuf); |
| 26631 | 26648 | fflush(stdout); |
| 26649 | +#endif |
| 26632 | 26650 | } |
| 26633 | 26651 | #endif |
| 26634 | 26652 | |
| 26635 | 26653 | |
| 26636 | 26654 | /* |
| | @@ -28516,16 +28534,16 @@ |
| 28516 | 28534 | } |
| 28517 | 28535 | |
| 28518 | 28536 | /* copy max significant digits to significand */ |
| 28519 | 28537 | while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ |
| 28520 | 28538 | s = s*10 + (*z - '0'); |
| 28521 | | - z+=incr, nDigits++; |
| 28539 | + z+=incr; nDigits++; |
| 28522 | 28540 | } |
| 28523 | 28541 | |
| 28524 | 28542 | /* skip non-significant significand digits |
| 28525 | 28543 | ** (increase exponent by d to shift decimal left) */ |
| 28526 | | - while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++; |
| 28544 | + while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; } |
| 28527 | 28545 | if( z>=zEnd ) goto do_atof_calc; |
| 28528 | 28546 | |
| 28529 | 28547 | /* if decimal point is present */ |
| 28530 | 28548 | if( *z=='.' ){ |
| 28531 | 28549 | z+=incr; |
| | @@ -28534,11 +28552,11 @@ |
| 28534 | 28552 | while( z<zEnd && sqlite3Isdigit(*z) ){ |
| 28535 | 28553 | if( s<((LARGEST_INT64-9)/10) ){ |
| 28536 | 28554 | s = s*10 + (*z - '0'); |
| 28537 | 28555 | d--; |
| 28538 | 28556 | } |
| 28539 | | - z+=incr, nDigits++; |
| 28557 | + z+=incr; nDigits++; |
| 28540 | 28558 | } |
| 28541 | 28559 | } |
| 28542 | 28560 | if( z>=zEnd ) goto do_atof_calc; |
| 28543 | 28561 | |
| 28544 | 28562 | /* if exponent is present */ |
| | @@ -30881,11 +30899,15 @@ |
| 30881 | 30899 | #else |
| 30882 | 30900 | { "lstat", (sqlite3_syscall_ptr)0, 0 }, |
| 30883 | 30901 | #endif |
| 30884 | 30902 | #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) |
| 30885 | 30903 | |
| 30904 | +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) |
| 30886 | 30905 | { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, |
| 30906 | +#else |
| 30907 | + { "ioctl", (sqlite3_syscall_ptr)0, 0 }, |
| 30908 | +#endif |
| 30887 | 30909 | #define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) |
| 30888 | 30910 | |
| 30889 | 30911 | }; /* End of the overrideable system calls */ |
| 30890 | 30912 | |
| 30891 | 30913 | |
| | @@ -34472,10 +34494,11 @@ |
| 34472 | 34494 | char *zFilename; /* Name of the mmapped file */ |
| 34473 | 34495 | int h; /* Open file descriptor */ |
| 34474 | 34496 | int szRegion; /* Size of shared-memory regions */ |
| 34475 | 34497 | u16 nRegion; /* Size of array apRegion */ |
| 34476 | 34498 | u8 isReadonly; /* True if read-only */ |
| 34499 | + u8 isUnlocked; /* True if no DMS lock held */ |
| 34477 | 34500 | char **apRegion; /* Array of mapped shared-memory regions */ |
| 34478 | 34501 | int nRef; /* Number of unixShm objects pointing to this */ |
| 34479 | 34502 | unixShm *pFirst; /* All unixShm objects pointing to this */ |
| 34480 | 34503 | #ifdef SQLITE_DEBUG |
| 34481 | 34504 | u8 exclMask; /* Mask of exclusive locks held */ |
| | @@ -34633,10 +34656,68 @@ |
| 34633 | 34656 | } |
| 34634 | 34657 | p->pInode->pShmNode = 0; |
| 34635 | 34658 | sqlite3_free(p); |
| 34636 | 34659 | } |
| 34637 | 34660 | } |
| 34661 | + |
| 34662 | +/* |
| 34663 | +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to |
| 34664 | +** take it now. Return SQLITE_OK if successful, or an SQLite error |
| 34665 | +** code otherwise. |
| 34666 | +** |
| 34667 | +** If the DMS cannot be locked because this is a readonly_shm=1 |
| 34668 | +** connection and no other process already holds a lock, return |
| 34669 | +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. |
| 34670 | +*/ |
| 34671 | +static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ |
| 34672 | + struct flock lock; |
| 34673 | + int rc = SQLITE_OK; |
| 34674 | + |
| 34675 | + /* Use F_GETLK to determine the locks other processes are holding |
| 34676 | + ** on the DMS byte. If it indicates that another process is holding |
| 34677 | + ** a SHARED lock, then this process may also take a SHARED lock |
| 34678 | + ** and proceed with opening the *-shm file. |
| 34679 | + ** |
| 34680 | + ** Or, if no other process is holding any lock, then this process |
| 34681 | + ** is the first to open it. In this case take an EXCLUSIVE lock on the |
| 34682 | + ** DMS byte and truncate the *-shm file to zero bytes in size. Then |
| 34683 | + ** downgrade to a SHARED lock on the DMS byte. |
| 34684 | + ** |
| 34685 | + ** If another process is holding an EXCLUSIVE lock on the DMS byte, |
| 34686 | + ** return SQLITE_BUSY to the caller (it will try again). An earlier |
| 34687 | + ** version of this code attempted the SHARED lock at this point. But |
| 34688 | + ** this introduced a subtle race condition: if the process holding |
| 34689 | + ** EXCLUSIVE failed just before truncating the *-shm file, then this |
| 34690 | + ** process might open and use the *-shm file without truncating it. |
| 34691 | + ** And if the *-shm file has been corrupted by a power failure or |
| 34692 | + ** system crash, the database itself may also become corrupt. */ |
| 34693 | + lock.l_whence = SEEK_SET; |
| 34694 | + lock.l_start = UNIX_SHM_DMS; |
| 34695 | + lock.l_len = 1; |
| 34696 | + lock.l_type = F_WRLCK; |
| 34697 | + if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) { |
| 34698 | + rc = SQLITE_IOERR_LOCK; |
| 34699 | + }else if( lock.l_type==F_UNLCK ){ |
| 34700 | + if( pShmNode->isReadonly ){ |
| 34701 | + pShmNode->isUnlocked = 1; |
| 34702 | + rc = SQLITE_READONLY_CANTINIT; |
| 34703 | + }else{ |
| 34704 | + rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); |
| 34705 | + if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){ |
| 34706 | + rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename); |
| 34707 | + } |
| 34708 | + } |
| 34709 | + }else if( lock.l_type==F_WRLCK ){ |
| 34710 | + rc = SQLITE_BUSY; |
| 34711 | + } |
| 34712 | + |
| 34713 | + if( rc==SQLITE_OK ){ |
| 34714 | + assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK ); |
| 34715 | + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); |
| 34716 | + } |
| 34717 | + return rc; |
| 34718 | +} |
| 34638 | 34719 | |
| 34639 | 34720 | /* |
| 34640 | 34721 | ** Open a shared-memory area associated with open database file pDbFd. |
| 34641 | 34722 | ** This particular implementation uses mmapped files. |
| 34642 | 34723 | ** |
| | @@ -34672,13 +34753,13 @@ |
| 34672 | 34753 | ** file is created. The shared memory will be simulated with heap memory. |
| 34673 | 34754 | */ |
| 34674 | 34755 | static int unixOpenSharedMemory(unixFile *pDbFd){ |
| 34675 | 34756 | struct unixShm *p = 0; /* The connection to be opened */ |
| 34676 | 34757 | struct unixShmNode *pShmNode; /* The underlying mmapped file */ |
| 34677 | | - int rc; /* Result code */ |
| 34758 | + int rc = SQLITE_OK; /* Result code */ |
| 34678 | 34759 | unixInodeInfo *pInode; /* The inode of fd */ |
| 34679 | | - char *zShmFilename; /* Name of the file used for SHM */ |
| 34760 | + char *zShm; /* Name of the file used for SHM */ |
| 34680 | 34761 | int nShmFilename; /* Size of the SHM filename in bytes */ |
| 34681 | 34762 | |
| 34682 | 34763 | /* Allocate space for the new unixShm object. */ |
| 34683 | 34764 | p = sqlite3_malloc64( sizeof(*p) ); |
| 34684 | 34765 | if( p==0 ) return SQLITE_NOMEM_BKPT; |
| | @@ -34715,18 +34796,18 @@ |
| 34715 | 34796 | if( pShmNode==0 ){ |
| 34716 | 34797 | rc = SQLITE_NOMEM_BKPT; |
| 34717 | 34798 | goto shm_open_err; |
| 34718 | 34799 | } |
| 34719 | 34800 | memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); |
| 34720 | | - zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; |
| 34801 | + zShm = pShmNode->zFilename = (char*)&pShmNode[1]; |
| 34721 | 34802 | #ifdef SQLITE_SHM_DIRECTORY |
| 34722 | | - sqlite3_snprintf(nShmFilename, zShmFilename, |
| 34803 | + sqlite3_snprintf(nShmFilename, zShm, |
| 34723 | 34804 | SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", |
| 34724 | 34805 | (u32)sStat.st_ino, (u32)sStat.st_dev); |
| 34725 | 34806 | #else |
| 34726 | | - sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); |
| 34727 | | - sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); |
| 34807 | + sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); |
| 34808 | + sqlite3FileSuffix3(pDbFd->zPath, zShm); |
| 34728 | 34809 | #endif |
| 34729 | 34810 | pShmNode->h = -1; |
| 34730 | 34811 | pDbFd->pInode->pShmNode = pShmNode; |
| 34731 | 34812 | pShmNode->pInode = pDbFd->pInode; |
| 34732 | 34813 | if( sqlite3GlobalConfig.bCoreMutex ){ |
| | @@ -34736,40 +34817,30 @@ |
| 34736 | 34817 | goto shm_open_err; |
| 34737 | 34818 | } |
| 34738 | 34819 | } |
| 34739 | 34820 | |
| 34740 | 34821 | if( pInode->bProcessLock==0 ){ |
| 34741 | | - int openFlags = O_RDWR | O_CREAT; |
| 34742 | | - if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ |
| 34743 | | - openFlags = O_RDONLY; |
| 34744 | | - pShmNode->isReadonly = 1; |
| 34822 | + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ |
| 34823 | + pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777)); |
| 34745 | 34824 | } |
| 34746 | | - pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); |
| 34747 | 34825 | if( pShmNode->h<0 ){ |
| 34748 | | - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 34749 | | - goto shm_open_err; |
| 34826 | + pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777)); |
| 34827 | + if( pShmNode->h<0 ){ |
| 34828 | + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); |
| 34829 | + goto shm_open_err; |
| 34830 | + } |
| 34831 | + pShmNode->isReadonly = 1; |
| 34750 | 34832 | } |
| 34751 | 34833 | |
| 34752 | 34834 | /* If this process is running as root, make sure that the SHM file |
| 34753 | 34835 | ** is owned by the same user that owns the original database. Otherwise, |
| 34754 | 34836 | ** the original owner will not be able to connect. |
| 34755 | 34837 | */ |
| 34756 | 34838 | robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); |
| 34757 | | - |
| 34758 | | - /* Check to see if another process is holding the dead-man switch. |
| 34759 | | - ** If not, truncate the file to zero length. |
| 34760 | | - */ |
| 34761 | | - rc = SQLITE_OK; |
| 34762 | | - if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ |
| 34763 | | - if( robust_ftruncate(pShmNode->h, 0) ){ |
| 34764 | | - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); |
| 34765 | | - } |
| 34766 | | - } |
| 34767 | | - if( rc==SQLITE_OK ){ |
| 34768 | | - rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); |
| 34769 | | - } |
| 34770 | | - if( rc ) goto shm_open_err; |
| 34839 | + |
| 34840 | + rc = unixLockSharedMemory(pDbFd, pShmNode); |
| 34841 | + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; |
| 34771 | 34842 | } |
| 34772 | 34843 | } |
| 34773 | 34844 | |
| 34774 | 34845 | /* Make the new connection a child of the unixShmNode */ |
| 34775 | 34846 | p->pShmNode = pShmNode; |
| | @@ -34789,11 +34860,11 @@ |
| 34789 | 34860 | */ |
| 34790 | 34861 | sqlite3_mutex_enter(pShmNode->mutex); |
| 34791 | 34862 | p->pNext = pShmNode->pFirst; |
| 34792 | 34863 | pShmNode->pFirst = p; |
| 34793 | 34864 | sqlite3_mutex_leave(pShmNode->mutex); |
| 34794 | | - return SQLITE_OK; |
| 34865 | + return rc; |
| 34795 | 34866 | |
| 34796 | 34867 | /* Jump here on any error */ |
| 34797 | 34868 | shm_open_err: |
| 34798 | 34869 | unixShmPurge(pDbFd); /* This call frees pShmNode if required */ |
| 34799 | 34870 | sqlite3_free(p); |
| | @@ -34841,10 +34912,15 @@ |
| 34841 | 34912 | } |
| 34842 | 34913 | |
| 34843 | 34914 | p = pDbFd->pShm; |
| 34844 | 34915 | pShmNode = p->pShmNode; |
| 34845 | 34916 | sqlite3_mutex_enter(pShmNode->mutex); |
| 34917 | + if( pShmNode->isUnlocked ){ |
| 34918 | + rc = unixLockSharedMemory(pDbFd, pShmNode); |
| 34919 | + if( rc!=SQLITE_OK ) goto shmpage_out; |
| 34920 | + pShmNode->isUnlocked = 0; |
| 34921 | + } |
| 34846 | 34922 | assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); |
| 34847 | 34923 | assert( pShmNode->pInode==pDbFd->pInode ); |
| 34848 | 34924 | assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); |
| 34849 | 34925 | assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); |
| 34850 | 34926 | |
| | @@ -41915,10 +41991,13 @@ |
| 41915 | 41991 | char *zFilename; /* Name of the file */ |
| 41916 | 41992 | winFile hFile; /* File handle from winOpen */ |
| 41917 | 41993 | |
| 41918 | 41994 | int szRegion; /* Size of shared-memory regions */ |
| 41919 | 41995 | int nRegion; /* Size of array apRegion */ |
| 41996 | + u8 isReadonly; /* True if read-only */ |
| 41997 | + u8 isUnlocked; /* True if no DMS lock held */ |
| 41998 | + |
| 41920 | 41999 | struct ShmRegion { |
| 41921 | 42000 | HANDLE hMap; /* File handle from CreateFileMapping */ |
| 41922 | 42001 | void *pMap; |
| 41923 | 42002 | } *aRegion; |
| 41924 | 42003 | DWORD lastErrno; /* The Windows errno from the last I/O error */ |
| | @@ -42061,10 +42140,41 @@ |
| 42061 | 42140 | }else{ |
| 42062 | 42141 | pp = &p->pNext; |
| 42063 | 42142 | } |
| 42064 | 42143 | } |
| 42065 | 42144 | } |
| 42145 | + |
| 42146 | +/* |
| 42147 | +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to |
| 42148 | +** take it now. Return SQLITE_OK if successful, or an SQLite error |
| 42149 | +** code otherwise. |
| 42150 | +** |
| 42151 | +** If the DMS cannot be locked because this is a readonly_shm=1 |
| 42152 | +** connection and no other process already holds a lock, return |
| 42153 | +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. |
| 42154 | +*/ |
| 42155 | +static int winLockSharedMemory(winShmNode *pShmNode){ |
| 42156 | + int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); |
| 42157 | + |
| 42158 | + if( rc==SQLITE_OK ){ |
| 42159 | + if( pShmNode->isReadonly ){ |
| 42160 | + pShmNode->isUnlocked = 1; |
| 42161 | + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
| 42162 | + return SQLITE_READONLY_CANTINIT; |
| 42163 | + }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ |
| 42164 | + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
| 42165 | + return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
| 42166 | + "winLockSharedMemory", pShmNode->zFilename); |
| 42167 | + } |
| 42168 | + } |
| 42169 | + |
| 42170 | + if( rc==SQLITE_OK ){ |
| 42171 | + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
| 42172 | + } |
| 42173 | + |
| 42174 | + return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); |
| 42175 | +} |
| 42066 | 42176 | |
| 42067 | 42177 | /* |
| 42068 | 42178 | ** Open the shared-memory area associated with database file pDbFd. |
| 42069 | 42179 | ** |
| 42070 | 42180 | ** When opening a new shared-memory file, if no other instances of that |
| | @@ -42071,13 +42181,14 @@ |
| 42071 | 42181 | ** file are currently open, in this process or in other processes, then |
| 42072 | 42182 | ** the file must be truncated to zero length or have its header cleared. |
| 42073 | 42183 | */ |
| 42074 | 42184 | static int winOpenSharedMemory(winFile *pDbFd){ |
| 42075 | 42185 | struct winShm *p; /* The connection to be opened */ |
| 42076 | | - struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ |
| 42077 | | - int rc; /* Result code */ |
| 42078 | | - struct winShmNode *pNew; /* Newly allocated winShmNode */ |
| 42186 | + winShmNode *pShmNode = 0; /* The underlying mmapped file */ |
| 42187 | + int rc = SQLITE_OK; /* Result code */ |
| 42188 | + int rc2 = SQLITE_ERROR; /* winOpen result code */ |
| 42189 | + winShmNode *pNew; /* Newly allocated winShmNode */ |
| 42079 | 42190 | int nName; /* Size of zName in bytes */ |
| 42080 | 42191 | |
| 42081 | 42192 | assert( pDbFd->pShm==0 ); /* Not previously opened */ |
| 42082 | 42193 | |
| 42083 | 42194 | /* Allocate space for the new sqlite3_shm object. Also speculatively |
| | @@ -42120,34 +42231,33 @@ |
| 42120 | 42231 | rc = SQLITE_IOERR_NOMEM_BKPT; |
| 42121 | 42232 | goto shm_open_err; |
| 42122 | 42233 | } |
| 42123 | 42234 | } |
| 42124 | 42235 | |
| 42125 | | - rc = winOpen(pDbFd->pVfs, |
| 42126 | | - pShmNode->zFilename, /* Name of the file (UTF-8) */ |
| 42127 | | - (sqlite3_file*)&pShmNode->hFile, /* File handle here */ |
| 42128 | | - SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 42129 | | - 0); |
| 42130 | | - if( SQLITE_OK!=rc ){ |
| 42131 | | - goto shm_open_err; |
| 42132 | | - } |
| 42133 | | - |
| 42134 | | - /* Check to see if another process is holding the dead-man switch. |
| 42135 | | - ** If not, truncate the file to zero length. |
| 42136 | | - */ |
| 42137 | | - if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 42138 | | - rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 42139 | | - if( rc!=SQLITE_OK ){ |
| 42140 | | - rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
| 42141 | | - "winOpenShm", pDbFd->zPath); |
| 42142 | | - } |
| 42143 | | - } |
| 42144 | | - if( rc==SQLITE_OK ){ |
| 42145 | | - winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
| 42146 | | - rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); |
| 42147 | | - } |
| 42148 | | - if( rc ) goto shm_open_err; |
| 42236 | + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ |
| 42237 | + rc2 = winOpen(pDbFd->pVfs, |
| 42238 | + pShmNode->zFilename, |
| 42239 | + (sqlite3_file*)&pShmNode->hFile, |
| 42240 | + SQLITE_OPEN_WAL|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, |
| 42241 | + 0); |
| 42242 | + } |
| 42243 | + if( rc2!=SQLITE_OK ){ |
| 42244 | + rc2 = winOpen(pDbFd->pVfs, |
| 42245 | + pShmNode->zFilename, |
| 42246 | + (sqlite3_file*)&pShmNode->hFile, |
| 42247 | + SQLITE_OPEN_WAL|SQLITE_OPEN_READONLY, |
| 42248 | + 0); |
| 42249 | + if( rc2!=SQLITE_OK ){ |
| 42250 | + rc = winLogError(rc2, osGetLastError(), "winOpenShm", |
| 42251 | + pShmNode->zFilename); |
| 42252 | + goto shm_open_err; |
| 42253 | + } |
| 42254 | + pShmNode->isReadonly = 1; |
| 42255 | + } |
| 42256 | + |
| 42257 | + rc = winLockSharedMemory(pShmNode); |
| 42258 | + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; |
| 42149 | 42259 | } |
| 42150 | 42260 | |
| 42151 | 42261 | /* Make the new connection a child of the winShmNode */ |
| 42152 | 42262 | p->pShmNode = pShmNode; |
| 42153 | 42263 | #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) |
| | @@ -42166,11 +42276,11 @@ |
| 42166 | 42276 | */ |
| 42167 | 42277 | sqlite3_mutex_enter(pShmNode->mutex); |
| 42168 | 42278 | p->pNext = pShmNode->pFirst; |
| 42169 | 42279 | pShmNode->pFirst = p; |
| 42170 | 42280 | sqlite3_mutex_leave(pShmNode->mutex); |
| 42171 | | - return SQLITE_OK; |
| 42281 | + return rc; |
| 42172 | 42282 | |
| 42173 | 42283 | /* Jump here on any error */ |
| 42174 | 42284 | shm_open_err: |
| 42175 | 42285 | winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
| 42176 | 42286 | winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ |
| | @@ -42370,10 +42480,12 @@ |
| 42370 | 42480 | void volatile **pp /* OUT: Mapped memory */ |
| 42371 | 42481 | ){ |
| 42372 | 42482 | winFile *pDbFd = (winFile*)fd; |
| 42373 | 42483 | winShm *pShm = pDbFd->pShm; |
| 42374 | 42484 | winShmNode *pShmNode; |
| 42485 | + DWORD protect = PAGE_READWRITE; |
| 42486 | + DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; |
| 42375 | 42487 | int rc = SQLITE_OK; |
| 42376 | 42488 | |
| 42377 | 42489 | if( !pShm ){ |
| 42378 | 42490 | rc = winOpenSharedMemory(pDbFd); |
| 42379 | 42491 | if( rc!=SQLITE_OK ) return rc; |
| | @@ -42380,10 +42492,15 @@ |
| 42380 | 42492 | pShm = pDbFd->pShm; |
| 42381 | 42493 | } |
| 42382 | 42494 | pShmNode = pShm->pShmNode; |
| 42383 | 42495 | |
| 42384 | 42496 | sqlite3_mutex_enter(pShmNode->mutex); |
| 42497 | + if( pShmNode->isUnlocked ){ |
| 42498 | + rc = winLockSharedMemory(pShmNode); |
| 42499 | + if( rc!=SQLITE_OK ) goto shmpage_out; |
| 42500 | + pShmNode->isUnlocked = 0; |
| 42501 | + } |
| 42385 | 42502 | assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); |
| 42386 | 42503 | |
| 42387 | 42504 | if( pShmNode->nRegion<=iRegion ){ |
| 42388 | 42505 | struct ShmRegion *apNew; /* New aRegion[] array */ |
| 42389 | 42506 | int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ |
| | @@ -42425,40 +42542,45 @@ |
| 42425 | 42542 | if( !apNew ){ |
| 42426 | 42543 | rc = SQLITE_IOERR_NOMEM_BKPT; |
| 42427 | 42544 | goto shmpage_out; |
| 42428 | 42545 | } |
| 42429 | 42546 | pShmNode->aRegion = apNew; |
| 42547 | + |
| 42548 | + if( pShmNode->isReadonly ){ |
| 42549 | + protect = PAGE_READONLY; |
| 42550 | + flags = FILE_MAP_READ; |
| 42551 | + } |
| 42430 | 42552 | |
| 42431 | 42553 | while( pShmNode->nRegion<=iRegion ){ |
| 42432 | 42554 | HANDLE hMap = NULL; /* file-mapping handle */ |
| 42433 | 42555 | void *pMap = 0; /* Mapped memory region */ |
| 42434 | 42556 | |
| 42435 | 42557 | #if SQLITE_OS_WINRT |
| 42436 | 42558 | hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, |
| 42437 | | - NULL, PAGE_READWRITE, nByte, NULL |
| 42559 | + NULL, protect, nByte, NULL |
| 42438 | 42560 | ); |
| 42439 | 42561 | #elif defined(SQLITE_WIN32_HAS_WIDE) |
| 42440 | 42562 | hMap = osCreateFileMappingW(pShmNode->hFile.h, |
| 42441 | | - NULL, PAGE_READWRITE, 0, nByte, NULL |
| 42563 | + NULL, protect, 0, nByte, NULL |
| 42442 | 42564 | ); |
| 42443 | 42565 | #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA |
| 42444 | 42566 | hMap = osCreateFileMappingA(pShmNode->hFile.h, |
| 42445 | | - NULL, PAGE_READWRITE, 0, nByte, NULL |
| 42567 | + NULL, protect, 0, nByte, NULL |
| 42446 | 42568 | ); |
| 42447 | 42569 | #endif |
| 42448 | 42570 | OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", |
| 42449 | 42571 | osGetCurrentProcessId(), pShmNode->nRegion, nByte, |
| 42450 | 42572 | hMap ? "ok" : "failed")); |
| 42451 | 42573 | if( hMap ){ |
| 42452 | 42574 | int iOffset = pShmNode->nRegion*szRegion; |
| 42453 | 42575 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 42454 | 42576 | #if SQLITE_OS_WINRT |
| 42455 | | - pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 42577 | + pMap = osMapViewOfFileFromApp(hMap, flags, |
| 42456 | 42578 | iOffset - iOffsetShift, szRegion + iOffsetShift |
| 42457 | 42579 | ); |
| 42458 | 42580 | #else |
| 42459 | | - pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 42581 | + pMap = osMapViewOfFile(hMap, flags, |
| 42460 | 42582 | 0, iOffset - iOffsetShift, szRegion + iOffsetShift |
| 42461 | 42583 | ); |
| 42462 | 42584 | #endif |
| 42463 | 42585 | OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", |
| 42464 | 42586 | osGetCurrentProcessId(), pShmNode->nRegion, iOffset, |
| | @@ -42485,10 +42607,11 @@ |
| 42485 | 42607 | char *p = (char *)pShmNode->aRegion[iRegion].pMap; |
| 42486 | 42608 | *pp = (void *)&p[iOffsetShift]; |
| 42487 | 42609 | }else{ |
| 42488 | 42610 | *pp = 0; |
| 42489 | 42611 | } |
| 42612 | + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; |
| 42490 | 42613 | sqlite3_mutex_leave(pShmNode->mutex); |
| 42491 | 42614 | return rc; |
| 42492 | 42615 | } |
| 42493 | 42616 | |
| 42494 | 42617 | #else |
| | @@ -45254,20 +45377,19 @@ |
| 45254 | 45377 | ** Make sure the page is marked as clean. If it isn't clean already, |
| 45255 | 45378 | ** make it so. |
| 45256 | 45379 | */ |
| 45257 | 45380 | SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ |
| 45258 | 45381 | assert( sqlite3PcachePageSanity(p) ); |
| 45259 | | - if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ |
| 45260 | | - assert( (p->flags & PGHDR_CLEAN)==0 ); |
| 45261 | | - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); |
| 45262 | | - p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); |
| 45263 | | - p->flags |= PGHDR_CLEAN; |
| 45264 | | - pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); |
| 45265 | | - assert( sqlite3PcachePageSanity(p) ); |
| 45266 | | - if( p->nRef==0 ){ |
| 45267 | | - pcacheUnpin(p); |
| 45268 | | - } |
| 45382 | + assert( (p->flags & PGHDR_DIRTY)!=0 ); |
| 45383 | + assert( (p->flags & PGHDR_CLEAN)==0 ); |
| 45384 | + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); |
| 45385 | + p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); |
| 45386 | + p->flags |= PGHDR_CLEAN; |
| 45387 | + pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); |
| 45388 | + assert( sqlite3PcachePageSanity(p) ); |
| 45389 | + if( p->nRef==0 ){ |
| 45390 | + pcacheUnpin(p); |
| 45269 | 45391 | } |
| 45270 | 45392 | } |
| 45271 | 45393 | |
| 45272 | 45394 | /* |
| 45273 | 45395 | ** Make every page in the cache clean. |
| | @@ -55243,10 +55365,14 @@ |
| 55243 | 55365 | ** Conceptually, the wal-index is shared memory, though VFS implementations |
| 55244 | 55366 | ** might choose to implement the wal-index using a mmapped file. Because |
| 55245 | 55367 | ** the wal-index is shared memory, SQLite does not support journal_mode=WAL |
| 55246 | 55368 | ** on a network filesystem. All users of the database must be able to |
| 55247 | 55369 | ** share memory. |
| 55370 | +** |
| 55371 | +** In the default unix and windows implementation, the wal-index is a mmapped |
| 55372 | +** file whose name is the database name with a "-shm" suffix added. For that |
| 55373 | +** reason, the wal-index is sometimes called the "shm" file. |
| 55248 | 55374 | ** |
| 55249 | 55375 | ** The wal-index is transient. After a crash, the wal-index can (and should |
| 55250 | 55376 | ** be) reconstructed from the original WAL file. In fact, the VFS is required |
| 55251 | 55377 | ** to either truncate or zero the header of the wal-index when the last |
| 55252 | 55378 | ** connection to it closes. Because the wal-index is transient, it can |
| | @@ -55383,13 +55509,22 @@ |
| 55383 | 55509 | */ |
| 55384 | 55510 | #define WAL_MAX_VERSION 3007000 |
| 55385 | 55511 | #define WALINDEX_MAX_VERSION 3007000 |
| 55386 | 55512 | |
| 55387 | 55513 | /* |
| 55388 | | -** Indices of various locking bytes. WAL_NREADER is the number |
| 55514 | +** Index numbers for various locking bytes. WAL_NREADER is the number |
| 55389 | 55515 | ** of available reader locks and should be at least 3. The default |
| 55390 | 55516 | ** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. |
| 55517 | +** |
| 55518 | +** Technically, the various VFSes are free to implement these locks however |
| 55519 | +** they see fit. However, compatibility is encouraged so that VFSes can |
| 55520 | +** interoperate. The standard implemention used on both unix and windows |
| 55521 | +** is for the index number to indicate a byte offset into the |
| 55522 | +** WalCkptInfo.aLock[] array in the wal-index header. In other words, all |
| 55523 | +** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which |
| 55524 | +** should be 120) is the location in the shm file for the first locking |
| 55525 | +** byte. |
| 55391 | 55526 | */ |
| 55392 | 55527 | #define WAL_WRITE_LOCK 0 |
| 55393 | 55528 | #define WAL_ALL_BUT_WRITE 1 |
| 55394 | 55529 | #define WAL_CKPT_LOCK 1 |
| 55395 | 55530 | #define WAL_RECOVER_LOCK 2 |
| | @@ -55509,11 +55644,10 @@ |
| 55509 | 55644 | |
| 55510 | 55645 | /* Size of header before each frame in wal */ |
| 55511 | 55646 | #define WAL_FRAME_HDRSIZE 24 |
| 55512 | 55647 | |
| 55513 | 55648 | /* Size of write ahead log header, including checksum. */ |
| 55514 | | -/* #define WAL_HDRSIZE 24 */ |
| 55515 | 55649 | #define WAL_HDRSIZE 32 |
| 55516 | 55650 | |
| 55517 | 55651 | /* WAL magic value. Either this value, or the same value with the least |
| 55518 | 55652 | ** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit |
| 55519 | 55653 | ** big-endian format in the first 4 bytes of a WAL file. |
| | @@ -55555,10 +55689,11 @@ |
| 55555 | 55689 | u8 ckptLock; /* True if holding a checkpoint lock */ |
| 55556 | 55690 | u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ |
| 55557 | 55691 | u8 truncateOnCommit; /* True to truncate WAL file on commit */ |
| 55558 | 55692 | u8 syncHeader; /* Fsync the WAL header if true */ |
| 55559 | 55693 | u8 padToSectorBoundary; /* Pad transactions out to the next sector */ |
| 55694 | + u8 bShmUnreliable; /* SHM content is read-only and unreliable */ |
| 55560 | 55695 | WalIndexHdr hdr; /* Wal-index header for current transaction */ |
| 55561 | 55696 | u32 minFrame; /* Ignore wal frames before this one */ |
| 55562 | 55697 | u32 iReCksum; /* On commit, recalculate checksums from here */ |
| 55563 | 55698 | const char *zWalName; /* Name of WAL file */ |
| 55564 | 55699 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| | @@ -55643,10 +55778,15 @@ |
| 55643 | 55778 | |
| 55644 | 55779 | /* |
| 55645 | 55780 | ** Obtain a pointer to the iPage'th page of the wal-index. The wal-index |
| 55646 | 55781 | ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are |
| 55647 | 55782 | ** numbered from zero. |
| 55783 | +** |
| 55784 | +** If the wal-index is currently smaller the iPage pages then the size |
| 55785 | +** of the wal-index might be increased, but only if it is safe to do |
| 55786 | +** so. It is safe to enlarge the wal-index if pWal->writeLock is true |
| 55787 | +** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. |
| 55648 | 55788 | ** |
| 55649 | 55789 | ** If this call is successful, *ppPage is set to point to the wal-index |
| 55650 | 55790 | ** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, |
| 55651 | 55791 | ** then an SQLite error code is returned and *ppPage is set to 0. |
| 55652 | 55792 | */ |
| | @@ -55675,13 +55815,17 @@ |
| 55675 | 55815 | if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; |
| 55676 | 55816 | }else{ |
| 55677 | 55817 | rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, |
| 55678 | 55818 | pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] |
| 55679 | 55819 | ); |
| 55680 | | - if( rc==SQLITE_READONLY ){ |
| 55820 | + assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 ); |
| 55821 | + testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK ); |
| 55822 | + if( (rc&0xff)==SQLITE_READONLY ){ |
| 55681 | 55823 | pWal->readOnly |= WAL_SHM_RDONLY; |
| 55682 | | - rc = SQLITE_OK; |
| 55824 | + if( rc==SQLITE_READONLY ){ |
| 55825 | + rc = SQLITE_OK; |
| 55826 | + } |
| 55683 | 55827 | } |
| 55684 | 55828 | } |
| 55685 | 55829 | } |
| 55686 | 55830 | |
| 55687 | 55831 | *ppPage = pWal->apWiData[iPage]; |
| | @@ -56199,11 +56343,10 @@ |
| 56199 | 56343 | static int walIndexRecover(Wal *pWal){ |
| 56200 | 56344 | int rc; /* Return Code */ |
| 56201 | 56345 | i64 nSize; /* Size of log file */ |
| 56202 | 56346 | u32 aFrameCksum[2] = {0, 0}; |
| 56203 | 56347 | int iLock; /* Lock offset to lock for checkpoint */ |
| 56204 | | - int nLock; /* Number of locks to hold */ |
| 56205 | 56348 | |
| 56206 | 56349 | /* Obtain an exclusive lock on all byte in the locking range not already |
| 56207 | 56350 | ** locked by the caller. The caller is guaranteed to have locked the |
| 56208 | 56351 | ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte. |
| 56209 | 56352 | ** If successful, the same bytes that are locked here are unlocked before |
| | @@ -56212,15 +56355,21 @@ |
| 56212 | 56355 | assert( pWal->ckptLock==1 || pWal->ckptLock==0 ); |
| 56213 | 56356 | assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); |
| 56214 | 56357 | assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); |
| 56215 | 56358 | assert( pWal->writeLock ); |
| 56216 | 56359 | iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; |
| 56217 | | - nLock = SQLITE_SHM_NLOCK - iLock; |
| 56218 | | - rc = walLockExclusive(pWal, iLock, nLock); |
| 56360 | + rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); |
| 56361 | + if( rc==SQLITE_OK ){ |
| 56362 | + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 56363 | + if( rc!=SQLITE_OK ){ |
| 56364 | + walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); |
| 56365 | + } |
| 56366 | + } |
| 56219 | 56367 | if( rc ){ |
| 56220 | 56368 | return rc; |
| 56221 | 56369 | } |
| 56370 | + |
| 56222 | 56371 | WALTRACE(("WAL%p: recovery begin...\n", pWal)); |
| 56223 | 56372 | |
| 56224 | 56373 | memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); |
| 56225 | 56374 | |
| 56226 | 56375 | rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); |
| | @@ -56354,25 +56503,27 @@ |
| 56354 | 56503 | } |
| 56355 | 56504 | } |
| 56356 | 56505 | |
| 56357 | 56506 | recovery_error: |
| 56358 | 56507 | WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); |
| 56359 | | - walUnlockExclusive(pWal, iLock, nLock); |
| 56508 | + walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); |
| 56509 | + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 56360 | 56510 | return rc; |
| 56361 | 56511 | } |
| 56362 | 56512 | |
| 56363 | 56513 | /* |
| 56364 | 56514 | ** Close an open wal-index. |
| 56365 | 56515 | */ |
| 56366 | 56516 | static void walIndexClose(Wal *pWal, int isDelete){ |
| 56367 | | - if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ |
| 56517 | + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){ |
| 56368 | 56518 | int i; |
| 56369 | 56519 | for(i=0; i<pWal->nWiData; i++){ |
| 56370 | 56520 | sqlite3_free((void *)pWal->apWiData[i]); |
| 56371 | 56521 | pWal->apWiData[i] = 0; |
| 56372 | 56522 | } |
| 56373 | | - }else{ |
| 56523 | + } |
| 56524 | + if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ |
| 56374 | 56525 | sqlite3OsShmUnmap(pWal->pDbFd, isDelete); |
| 56375 | 56526 | } |
| 56376 | 56527 | } |
| 56377 | 56528 | |
| 56378 | 56529 | /* |
| | @@ -57161,10 +57312,16 @@ |
| 57161 | 57312 | |
| 57162 | 57313 | /* The header was successfully read. Return zero. */ |
| 57163 | 57314 | return 0; |
| 57164 | 57315 | } |
| 57165 | 57316 | |
| 57317 | +/* |
| 57318 | +** This is the value that walTryBeginRead returns when it needs to |
| 57319 | +** be retried. |
| 57320 | +*/ |
| 57321 | +#define WAL_RETRY (-1) |
| 57322 | + |
| 57166 | 57323 | /* |
| 57167 | 57324 | ** Read the wal-index header from the wal-index and into pWal->hdr. |
| 57168 | 57325 | ** If the wal-header appears to be corrupt, try to reconstruct the |
| 57169 | 57326 | ** wal-index from the WAL before returning. |
| 57170 | 57327 | ** |
| | @@ -57184,13 +57341,33 @@ |
| 57184 | 57341 | ** wal-index header) is mapped. Return early if an error occurs here. |
| 57185 | 57342 | */ |
| 57186 | 57343 | assert( pChanged ); |
| 57187 | 57344 | rc = walIndexPage(pWal, 0, &page0); |
| 57188 | 57345 | if( rc!=SQLITE_OK ){ |
| 57189 | | - return rc; |
| 57190 | | - }; |
| 57191 | | - assert( page0 || pWal->writeLock==0 ); |
| 57346 | + assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */ |
| 57347 | + if( rc==SQLITE_READONLY_CANTINIT ){ |
| 57348 | + /* The SQLITE_READONLY_CANTINIT return means that the shared-memory |
| 57349 | + ** was openable but is not writable, and this thread is unable to |
| 57350 | + ** confirm that another write-capable connection has the shared-memory |
| 57351 | + ** open, and hence the content of the shared-memory is unreliable, |
| 57352 | + ** since the shared-memory might be inconsistent with the WAL file |
| 57353 | + ** and there is no writer on hand to fix it. */ |
| 57354 | + assert( page0==0 ); |
| 57355 | + assert( pWal->writeLock==0 ); |
| 57356 | + assert( pWal->readOnly & WAL_SHM_RDONLY ); |
| 57357 | + pWal->bShmUnreliable = 1; |
| 57358 | + pWal->exclusiveMode = WAL_HEAPMEMORY_MODE; |
| 57359 | + *pChanged = 1; |
| 57360 | + }else{ |
| 57361 | + return rc; /* Any other non-OK return is just an error */ |
| 57362 | + } |
| 57363 | + }else{ |
| 57364 | + /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock |
| 57365 | + ** is zero, which prevents the SHM from growing */ |
| 57366 | + testcase( page0!=0 ); |
| 57367 | + } |
| 57368 | + assert( page0!=0 || pWal->writeLock==0 ); |
| 57192 | 57369 | |
| 57193 | 57370 | /* If the first page of the wal-index has been mapped, try to read the |
| 57194 | 57371 | ** wal-index header immediately, without holding any lock. This usually |
| 57195 | 57372 | ** works, but may fail if the wal-index header is corrupt or currently |
| 57196 | 57373 | ** being modified by another thread or process. |
| | @@ -57200,11 +57377,11 @@ |
| 57200 | 57377 | /* If the first attempt failed, it might have been due to a race |
| 57201 | 57378 | ** with a writer. So get a WRITE lock and try again. |
| 57202 | 57379 | */ |
| 57203 | 57380 | assert( badHdr==0 || pWal->writeLock==0 ); |
| 57204 | 57381 | if( badHdr ){ |
| 57205 | | - if( pWal->readOnly & WAL_SHM_RDONLY ){ |
| 57382 | + if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){ |
| 57206 | 57383 | if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ |
| 57207 | 57384 | walUnlockShared(pWal, WAL_WRITE_LOCK); |
| 57208 | 57385 | rc = SQLITE_READONLY_RECOVERY; |
| 57209 | 57386 | } |
| 57210 | 57387 | }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ |
| | @@ -57230,19 +57407,197 @@ |
| 57230 | 57407 | ** this version of SQLite cannot understand. |
| 57231 | 57408 | */ |
| 57232 | 57409 | if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ |
| 57233 | 57410 | rc = SQLITE_CANTOPEN_BKPT; |
| 57234 | 57411 | } |
| 57412 | + if( pWal->bShmUnreliable ){ |
| 57413 | + if( rc!=SQLITE_OK ){ |
| 57414 | + walIndexClose(pWal, 0); |
| 57415 | + pWal->bShmUnreliable = 0; |
| 57416 | + assert( pWal->nWiData>0 && pWal->apWiData[0]==0 ); |
| 57417 | + /* walIndexRecover() might have returned SHORT_READ if a concurrent |
| 57418 | + ** writer truncated the WAL out from under it. If that happens, it |
| 57419 | + ** indicates that a writer has fixed the SHM file for us, so retry */ |
| 57420 | + if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY; |
| 57421 | + } |
| 57422 | + pWal->exclusiveMode = WAL_NORMAL_MODE; |
| 57423 | + } |
| 57235 | 57424 | |
| 57236 | 57425 | return rc; |
| 57237 | 57426 | } |
| 57238 | 57427 | |
| 57239 | 57428 | /* |
| 57240 | | -** This is the value that walTryBeginRead returns when it needs to |
| 57241 | | -** be retried. |
| 57429 | +** Open a transaction in a connection where the shared-memory is read-only |
| 57430 | +** and where we cannot verify that there is a separate write-capable connection |
| 57431 | +** on hand to keep the shared-memory up-to-date with the WAL file. |
| 57432 | +** |
| 57433 | +** This can happen, for example, when the shared-memory is implemented by |
| 57434 | +** memory-mapping a *-shm file, where a prior writer has shut down and |
| 57435 | +** left the *-shm file on disk, and now the present connection is trying |
| 57436 | +** to use that database but lacks write permission on the *-shm file. |
| 57437 | +** Other scenarios are also possible, depending on the VFS implementation. |
| 57438 | +** |
| 57439 | +** Precondition: |
| 57440 | +** |
| 57441 | +** The *-wal file has been read and an appropriate wal-index has been |
| 57442 | +** constructed in pWal->apWiData[] using heap memory instead of shared |
| 57443 | +** memory. |
| 57444 | +** |
| 57445 | +** If this function returns SQLITE_OK, then the read transaction has |
| 57446 | +** been successfully opened. In this case output variable (*pChanged) |
| 57447 | +** is set to true before returning if the caller should discard the |
| 57448 | +** contents of the page cache before proceeding. Or, if it returns |
| 57449 | +** WAL_RETRY, then the heap memory wal-index has been discarded and |
| 57450 | +** the caller should retry opening the read transaction from the |
| 57451 | +** beginning (including attempting to map the *-shm file). |
| 57452 | +** |
| 57453 | +** If an error occurs, an SQLite error code is returned. |
| 57242 | 57454 | */ |
| 57243 | | -#define WAL_RETRY (-1) |
| 57455 | +static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ |
| 57456 | + i64 szWal; /* Size of wal file on disk in bytes */ |
| 57457 | + i64 iOffset; /* Current offset when reading wal file */ |
| 57458 | + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ |
| 57459 | + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ |
| 57460 | + int szFrame; /* Number of bytes in buffer aFrame[] */ |
| 57461 | + u8 *aData; /* Pointer to data part of aFrame buffer */ |
| 57462 | + volatile void *pDummy; /* Dummy argument for xShmMap */ |
| 57463 | + int rc; /* Return code */ |
| 57464 | + u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */ |
| 57465 | + |
| 57466 | + assert( pWal->bShmUnreliable ); |
| 57467 | + assert( pWal->readOnly & WAL_SHM_RDONLY ); |
| 57468 | + assert( pWal->nWiData>0 && pWal->apWiData[0] ); |
| 57469 | + |
| 57470 | + /* Take WAL_READ_LOCK(0). This has the effect of preventing any |
| 57471 | + ** writers from running a checkpoint, but does not stop them |
| 57472 | + ** from running recovery. */ |
| 57473 | + rc = walLockShared(pWal, WAL_READ_LOCK(0)); |
| 57474 | + if( rc!=SQLITE_OK ){ |
| 57475 | + if( rc==SQLITE_BUSY ) rc = WAL_RETRY; |
| 57476 | + goto begin_unreliable_shm_out; |
| 57477 | + } |
| 57478 | + pWal->readLock = 0; |
| 57479 | + |
| 57480 | + /* Check to see if a separate writer has attached to the shared-memory area, |
| 57481 | + ** thus making the shared-memory "reliable" again. Do this by invoking |
| 57482 | + ** the xShmMap() routine of the VFS and looking to see if the return |
| 57483 | + ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT. |
| 57484 | + ** |
| 57485 | + ** If the shared-memory is now "reliable" return WAL_RETRY, which will |
| 57486 | + ** cause the heap-memory WAL-index to be discarded and the actual |
| 57487 | + ** shared memory to be used in its place. |
| 57488 | + ** |
| 57489 | + ** This step is important because, even though this connection is holding |
| 57490 | + ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might |
| 57491 | + ** have already checkpointed the WAL file and, while the current |
| 57492 | + ** is active, wrap the WAL and start overwriting frames that this |
| 57493 | + ** process wants to use. |
| 57494 | + ** |
| 57495 | + ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has |
| 57496 | + ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY |
| 57497 | + ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations, |
| 57498 | + ** even if some external agent does a "chmod" to make the shared-memory |
| 57499 | + ** writable by us, until sqlite3OsShmUnmap() has been called. |
| 57500 | + ** This is a requirement on the VFS implementation. |
| 57501 | + */ |
| 57502 | + rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); |
| 57503 | + assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */ |
| 57504 | + if( rc!=SQLITE_READONLY_CANTINIT ){ |
| 57505 | + rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); |
| 57506 | + goto begin_unreliable_shm_out; |
| 57507 | + } |
| 57508 | + |
| 57509 | + /* We reach this point only if the real shared-memory is still unreliable. |
| 57510 | + ** Assume the in-memory WAL-index substitute is correct and load it |
| 57511 | + ** into pWal->hdr. |
| 57512 | + */ |
| 57513 | + memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); |
| 57514 | + |
| 57515 | + /* Make sure some writer hasn't come in and changed the WAL file out |
| 57516 | + ** from under us, then disconnected, while we were not looking. |
| 57517 | + */ |
| 57518 | + rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); |
| 57519 | + if( rc!=SQLITE_OK ){ |
| 57520 | + goto begin_unreliable_shm_out; |
| 57521 | + } |
| 57522 | + if( szWal<WAL_HDRSIZE ){ |
| 57523 | + /* If the wal file is too small to contain a wal-header and the |
| 57524 | + ** wal-index header has mxFrame==0, then it must be safe to proceed |
| 57525 | + ** reading the database file only. However, the page cache cannot |
| 57526 | + ** be trusted, as a read/write connection may have connected, written |
| 57527 | + ** the db, run a checkpoint, truncated the wal file and disconnected |
| 57528 | + ** since this client's last read transaction. */ |
| 57529 | + *pChanged = 1; |
| 57530 | + rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY); |
| 57531 | + goto begin_unreliable_shm_out; |
| 57532 | + } |
| 57533 | + |
| 57534 | + /* Check the salt keys at the start of the wal file still match. */ |
| 57535 | + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); |
| 57536 | + if( rc!=SQLITE_OK ){ |
| 57537 | + goto begin_unreliable_shm_out; |
| 57538 | + } |
| 57539 | + if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){ |
| 57540 | + /* Some writer has wrapped the WAL file while we were not looking. |
| 57541 | + ** Return WAL_RETRY which will cause the in-memory WAL-index to be |
| 57542 | + ** rebuilt. */ |
| 57543 | + rc = WAL_RETRY; |
| 57544 | + goto begin_unreliable_shm_out; |
| 57545 | + } |
| 57546 | + |
| 57547 | + /* Allocate a buffer to read frames into */ |
| 57548 | + szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE; |
| 57549 | + aFrame = (u8 *)sqlite3_malloc64(szFrame); |
| 57550 | + if( aFrame==0 ){ |
| 57551 | + rc = SQLITE_NOMEM_BKPT; |
| 57552 | + goto begin_unreliable_shm_out; |
| 57553 | + } |
| 57554 | + aData = &aFrame[WAL_FRAME_HDRSIZE]; |
| 57555 | + |
| 57556 | + /* Check to see if a complete transaction has been appended to the |
| 57557 | + ** wal file since the heap-memory wal-index was created. If so, the |
| 57558 | + ** heap-memory wal-index is discarded and WAL_RETRY returned to |
| 57559 | + ** the caller. */ |
| 57560 | + aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; |
| 57561 | + aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; |
| 57562 | + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage); |
| 57563 | + iOffset+szFrame<=szWal; |
| 57564 | + iOffset+=szFrame |
| 57565 | + ){ |
| 57566 | + u32 pgno; /* Database page number for frame */ |
| 57567 | + u32 nTruncate; /* dbsize field from frame header */ |
| 57568 | + |
| 57569 | + /* Read and decode the next log frame. */ |
| 57570 | + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); |
| 57571 | + if( rc!=SQLITE_OK ) break; |
| 57572 | + if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; |
| 57573 | + |
| 57574 | + /* If nTruncate is non-zero, then a complete transaction has been |
| 57575 | + ** appended to this wal file. Set rc to WAL_RETRY and break out of |
| 57576 | + ** the loop. */ |
| 57577 | + if( nTruncate ){ |
| 57578 | + rc = WAL_RETRY; |
| 57579 | + break; |
| 57580 | + } |
| 57581 | + } |
| 57582 | + pWal->hdr.aFrameCksum[0] = aSaveCksum[0]; |
| 57583 | + pWal->hdr.aFrameCksum[1] = aSaveCksum[1]; |
| 57584 | + |
| 57585 | + begin_unreliable_shm_out: |
| 57586 | + sqlite3_free(aFrame); |
| 57587 | + if( rc!=SQLITE_OK ){ |
| 57588 | + int i; |
| 57589 | + for(i=0; i<pWal->nWiData; i++){ |
| 57590 | + sqlite3_free((void*)pWal->apWiData[i]); |
| 57591 | + pWal->apWiData[i] = 0; |
| 57592 | + } |
| 57593 | + pWal->bShmUnreliable = 0; |
| 57594 | + sqlite3WalEndReadTransaction(pWal); |
| 57595 | + *pChanged = 1; |
| 57596 | + } |
| 57597 | + return rc; |
| 57598 | +} |
| 57244 | 57599 | |
| 57245 | 57600 | /* |
| 57246 | 57601 | ** Attempt to start a read transaction. This might fail due to a race or |
| 57247 | 57602 | ** other transient condition. When that happens, it returns WAL_RETRY to |
| 57248 | 57603 | ** indicate to the caller that it is safe to retry immediately. |
| | @@ -57254,11 +57609,11 @@ |
| 57254 | 57609 | ** The useWal parameter is true to force the use of the WAL and disable |
| 57255 | 57610 | ** the case where the WAL is bypassed because it has been completely |
| 57256 | 57611 | ** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() |
| 57257 | 57612 | ** to make a copy of the wal-index header into pWal->hdr. If the |
| 57258 | 57613 | ** wal-index header has changed, *pChanged is set to 1 (as an indication |
| 57259 | | -** to the caller that the local paget cache is obsolete and needs to be |
| 57614 | +** to the caller that the local page cache is obsolete and needs to be |
| 57260 | 57615 | ** flushed.) When useWal==1, the wal-index header is assumed to already |
| 57261 | 57616 | ** be loaded and the pChanged parameter is unused. |
| 57262 | 57617 | ** |
| 57263 | 57618 | ** The caller must set the cnt parameter to the number of prior calls to |
| 57264 | 57619 | ** this routine during the current read attempt that returned WAL_RETRY. |
| | @@ -57300,10 +57655,13 @@ |
| 57300 | 57655 | int rc = SQLITE_OK; /* Return code */ |
| 57301 | 57656 | u32 mxFrame; /* Wal frame to lock to */ |
| 57302 | 57657 | |
| 57303 | 57658 | assert( pWal->readLock<0 ); /* Not currently locked */ |
| 57304 | 57659 | |
| 57660 | + /* useWal may only be set for read/write connections */ |
| 57661 | + assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 ); |
| 57662 | + |
| 57305 | 57663 | /* Take steps to avoid spinning forever if there is a protocol error. |
| 57306 | 57664 | ** |
| 57307 | 57665 | ** Circumstances that cause a RETRY should only last for the briefest |
| 57308 | 57666 | ** instances of time. No I/O or other system calls are done while the |
| 57309 | 57667 | ** locks are held, so the locks should not be held for very long. But |
| | @@ -57328,11 +57686,14 @@ |
| 57328 | 57686 | if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; |
| 57329 | 57687 | sqlite3OsSleep(pWal->pVfs, nDelay); |
| 57330 | 57688 | } |
| 57331 | 57689 | |
| 57332 | 57690 | if( !useWal ){ |
| 57333 | | - rc = walIndexReadHdr(pWal, pChanged); |
| 57691 | + assert( rc==SQLITE_OK ); |
| 57692 | + if( pWal->bShmUnreliable==0 ){ |
| 57693 | + rc = walIndexReadHdr(pWal, pChanged); |
| 57694 | + } |
| 57334 | 57695 | if( rc==SQLITE_BUSY ){ |
| 57335 | 57696 | /* If there is not a recovery running in another thread or process |
| 57336 | 57697 | ** then convert BUSY errors to WAL_RETRY. If recovery is known to |
| 57337 | 57698 | ** be running, convert BUSY to BUSY_RECOVERY. There is a race here |
| 57338 | 57699 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| | @@ -57357,14 +57718,19 @@ |
| 57357 | 57718 | } |
| 57358 | 57719 | } |
| 57359 | 57720 | if( rc!=SQLITE_OK ){ |
| 57360 | 57721 | return rc; |
| 57361 | 57722 | } |
| 57723 | + else if( pWal->bShmUnreliable ){ |
| 57724 | + return walBeginShmUnreliable(pWal, pChanged); |
| 57725 | + } |
| 57362 | 57726 | } |
| 57363 | 57727 | |
| 57728 | + assert( pWal->nWiData>0 ); |
| 57729 | + assert( pWal->apWiData[0]!=0 ); |
| 57364 | 57730 | pInfo = walCkptInfo(pWal); |
| 57365 | | - if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame |
| 57731 | + if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame |
| 57366 | 57732 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 57367 | 57733 | && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0 |
| 57368 | 57734 | || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr))) |
| 57369 | 57735 | #endif |
| 57370 | 57736 | ){ |
| | @@ -57434,11 +57800,11 @@ |
| 57434 | 57800 | } |
| 57435 | 57801 | } |
| 57436 | 57802 | } |
| 57437 | 57803 | if( mxI==0 ){ |
| 57438 | 57804 | assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); |
| 57439 | | - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; |
| 57805 | + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; |
| 57440 | 57806 | } |
| 57441 | 57807 | |
| 57442 | 57808 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); |
| 57443 | 57809 | if( rc ){ |
| 57444 | 57810 | return rc==SQLITE_BUSY ? WAL_RETRY : rc; |
| | @@ -57706,11 +58072,11 @@ |
| 57706 | 58072 | ** no data will be read from the wal under any circumstances. Return early |
| 57707 | 58073 | ** in this case as an optimization. Likewise, if pWal->readLock==0, |
| 57708 | 58074 | ** then the WAL is ignored by the reader so return early, as if the |
| 57709 | 58075 | ** WAL were empty. |
| 57710 | 58076 | */ |
| 57711 | | - if( iLast==0 || pWal->readLock==0 ){ |
| 58077 | + if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){ |
| 57712 | 58078 | *piRead = 0; |
| 57713 | 58079 | return SQLITE_OK; |
| 57714 | 58080 | } |
| 57715 | 58081 | |
| 57716 | 58082 | /* Search the hash table or tables for an entry matching page number |
| | @@ -57769,12 +58135,12 @@ |
| 57769 | 58135 | ** of the wal-index file content. Make sure the results agree with the |
| 57770 | 58136 | ** result obtained using the hash indexes above. */ |
| 57771 | 58137 | { |
| 57772 | 58138 | u32 iRead2 = 0; |
| 57773 | 58139 | u32 iTest; |
| 57774 | | - assert( pWal->minFrame>0 ); |
| 57775 | | - for(iTest=iLast; iTest>=pWal->minFrame; iTest--){ |
| 58140 | + assert( pWal->bShmUnreliable || pWal->minFrame>0 ); |
| 58141 | + for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){ |
| 57776 | 58142 | if( walFramePgno(pWal, iTest)==pgno ){ |
| 57777 | 58143 | iRead2 = iTest; |
| 57778 | 58144 | break; |
| 57779 | 58145 | } |
| 57780 | 58146 | } |
| | @@ -58546,28 +58912,28 @@ |
| 58546 | 58912 | */ |
| 58547 | 58913 | assert( pWal->readLock>=0 || pWal->lockError ); |
| 58548 | 58914 | assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); |
| 58549 | 58915 | |
| 58550 | 58916 | if( op==0 ){ |
| 58551 | | - if( pWal->exclusiveMode ){ |
| 58552 | | - pWal->exclusiveMode = 0; |
| 58917 | + if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){ |
| 58918 | + pWal->exclusiveMode = WAL_NORMAL_MODE; |
| 58553 | 58919 | if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ |
| 58554 | | - pWal->exclusiveMode = 1; |
| 58920 | + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; |
| 58555 | 58921 | } |
| 58556 | | - rc = pWal->exclusiveMode==0; |
| 58922 | + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; |
| 58557 | 58923 | }else{ |
| 58558 | 58924 | /* Already in locking_mode=NORMAL */ |
| 58559 | 58925 | rc = 0; |
| 58560 | 58926 | } |
| 58561 | 58927 | }else if( op>0 ){ |
| 58562 | | - assert( pWal->exclusiveMode==0 ); |
| 58928 | + assert( pWal->exclusiveMode==WAL_NORMAL_MODE ); |
| 58563 | 58929 | assert( pWal->readLock>=0 ); |
| 58564 | 58930 | walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); |
| 58565 | | - pWal->exclusiveMode = 1; |
| 58931 | + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; |
| 58566 | 58932 | rc = 1; |
| 58567 | 58933 | }else{ |
| 58568 | | - rc = pWal->exclusiveMode==0; |
| 58934 | + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; |
| 58569 | 58935 | } |
| 58570 | 58936 | return rc; |
| 58571 | 58937 | } |
| 58572 | 58938 | |
| 58573 | 58939 | /* |
| | @@ -70766,30 +71132,28 @@ |
| 70766 | 71132 | ** |
| 70767 | 71133 | ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK |
| 70768 | 71134 | ** otherwise. |
| 70769 | 71135 | */ |
| 70770 | 71136 | SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ |
| 70771 | | - int rc = SQLITE_OK; |
| 70772 | | - if( ALWAYS(pFunc && pFunc->xFinalize) ){ |
| 70773 | | - sqlite3_context ctx; |
| 70774 | | - Mem t; |
| 70775 | | - assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); |
| 70776 | | - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 70777 | | - memset(&ctx, 0, sizeof(ctx)); |
| 70778 | | - memset(&t, 0, sizeof(t)); |
| 70779 | | - t.flags = MEM_Null; |
| 70780 | | - t.db = pMem->db; |
| 70781 | | - ctx.pOut = &t; |
| 70782 | | - ctx.pMem = pMem; |
| 70783 | | - ctx.pFunc = pFunc; |
| 70784 | | - pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ |
| 70785 | | - assert( (pMem->flags & MEM_Dyn)==0 ); |
| 70786 | | - if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); |
| 70787 | | - memcpy(pMem, &t, sizeof(t)); |
| 70788 | | - rc = ctx.isError; |
| 70789 | | - } |
| 70790 | | - return rc; |
| 71137 | + sqlite3_context ctx; |
| 71138 | + Mem t; |
| 71139 | + assert( pFunc!=0 ); |
| 71140 | + assert( pFunc->xFinalize!=0 ); |
| 71141 | + assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); |
| 71142 | + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 71143 | + memset(&ctx, 0, sizeof(ctx)); |
| 71144 | + memset(&t, 0, sizeof(t)); |
| 71145 | + t.flags = MEM_Null; |
| 71146 | + t.db = pMem->db; |
| 71147 | + ctx.pOut = &t; |
| 71148 | + ctx.pMem = pMem; |
| 71149 | + ctx.pFunc = pFunc; |
| 71150 | + pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ |
| 71151 | + assert( (pMem->flags & MEM_Dyn)==0 ); |
| 71152 | + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); |
| 71153 | + memcpy(pMem, &t, sizeof(t)); |
| 71154 | + return ctx.isError; |
| 70791 | 71155 | } |
| 70792 | 71156 | |
| 70793 | 71157 | /* |
| 70794 | 71158 | ** If the memory cell contains a value that must be freed by |
| 70795 | 71159 | ** invoking the external callback in Mem.xDel, then this routine |
| | @@ -75224,11 +75588,11 @@ |
| 75224 | 75588 | ** Delete an entire VDBE. |
| 75225 | 75589 | */ |
| 75226 | 75590 | SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ |
| 75227 | 75591 | sqlite3 *db; |
| 75228 | 75592 | |
| 75229 | | - if( NEVER(p==0) ) return; |
| 75593 | + assert( p!=0 ); |
| 75230 | 75594 | db = p->db; |
| 75231 | 75595 | assert( sqlite3_mutex_held(db->mutex) ); |
| 75232 | 75596 | sqlite3VdbeClearObject(db, p); |
| 75233 | 75597 | if( p->pPrev ){ |
| 75234 | 75598 | p->pPrev->pNext = p->pNext; |
| | @@ -90209,20 +90573,19 @@ |
| 90209 | 90573 | SrcList *pSrc; |
| 90210 | 90574 | int i; |
| 90211 | 90575 | struct SrcList_item *pItem; |
| 90212 | 90576 | |
| 90213 | 90577 | pSrc = p->pSrc; |
| 90214 | | - if( ALWAYS(pSrc) ){ |
| 90215 | | - for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ |
| 90216 | | - if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ |
| 90217 | | - return WRC_Abort; |
| 90218 | | - } |
| 90219 | | - if( pItem->fg.isTabFunc |
| 90220 | | - && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) |
| 90221 | | - ){ |
| 90222 | | - return WRC_Abort; |
| 90223 | | - } |
| 90578 | + assert( pSrc!=0 ); |
| 90579 | + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ |
| 90580 | + if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ |
| 90581 | + return WRC_Abort; |
| 90582 | + } |
| 90583 | + if( pItem->fg.isTabFunc |
| 90584 | + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) |
| 90585 | + ){ |
| 90586 | + return WRC_Abort; |
| 90224 | 90587 | } |
| 90225 | 90588 | } |
| 90226 | 90589 | return WRC_Continue; |
| 90227 | 90590 | } |
| 90228 | 90591 | |
| | @@ -90861,11 +91224,12 @@ |
| 90861 | 91224 | */ |
| 90862 | 91225 | case TK_ROW: { |
| 90863 | 91226 | SrcList *pSrcList = pNC->pSrcList; |
| 90864 | 91227 | struct SrcList_item *pItem; |
| 90865 | 91228 | assert( pSrcList && pSrcList->nSrc==1 ); |
| 90866 | | - pItem = pSrcList->a; |
| 91229 | + pItem = pSrcList->a; |
| 91230 | + assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 ); |
| 90867 | 91231 | pExpr->op = TK_COLUMN; |
| 90868 | 91232 | pExpr->pTab = pItem->pTab; |
| 90869 | 91233 | pExpr->iTable = pItem->iCursor; |
| 90870 | 91234 | pExpr->iColumn = -1; |
| 90871 | 91235 | pExpr->affinity = SQLITE_AFF_INTEGER; |
| | @@ -92751,10 +93115,11 @@ |
| 92751 | 93115 | if( pNew==0 ){ |
| 92752 | 93116 | sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ |
| 92753 | 93117 | return 0; |
| 92754 | 93118 | } |
| 92755 | 93119 | pNew->x.pList = pList; |
| 93120 | + ExprSetProperty(pNew, EP_HasFunc); |
| 92756 | 93121 | assert( !ExprHasProperty(pNew, EP_xIsSelect) ); |
| 92757 | 93122 | sqlite3ExprSetHeightAndFlags(pParse, pNew); |
| 92758 | 93123 | return pNew; |
| 92759 | 93124 | } |
| 92760 | 93125 | |
| | @@ -104548,13 +104913,14 @@ |
| 104548 | 104913 | (pOn ? "ON" : "USING") |
| 104549 | 104914 | ); |
| 104550 | 104915 | goto append_from_error; |
| 104551 | 104916 | } |
| 104552 | 104917 | p = sqlite3SrcListAppend(db, p, pTable, pDatabase); |
| 104553 | | - if( p==0 || NEVER(p->nSrc==0) ){ |
| 104918 | + if( p==0 ){ |
| 104554 | 104919 | goto append_from_error; |
| 104555 | 104920 | } |
| 104921 | + assert( p->nSrc>0 ); |
| 104556 | 104922 | pItem = &p->a[p->nSrc-1]; |
| 104557 | 104923 | assert( pAlias!=0 ); |
| 104558 | 104924 | if( pAlias->n ){ |
| 104559 | 104925 | pItem->zAlias = sqlite3NameFromToken(db, pAlias); |
| 104560 | 104926 | } |
| | @@ -105717,10 +106083,13 @@ |
| 105717 | 106083 | */ |
| 105718 | 106084 | SQLITE_PRIVATE void sqlite3MaterializeView( |
| 105719 | 106085 | Parse *pParse, /* Parsing context */ |
| 105720 | 106086 | Table *pView, /* View definition */ |
| 105721 | 106087 | Expr *pWhere, /* Optional WHERE clause to be added */ |
| 106088 | + ExprList *pOrderBy, /* Optional ORDER BY clause */ |
| 106089 | + Expr *pLimit, /* Optional LIMIT clause */ |
| 106090 | + Expr *pOffset, /* Optional OFFSET clause */ |
| 105722 | 106091 | int iCur /* Cursor number for ephemeral table */ |
| 105723 | 106092 | ){ |
| 105724 | 106093 | SelectDest dest; |
| 105725 | 106094 | Select *pSel; |
| 105726 | 106095 | SrcList *pFrom; |
| | @@ -105733,12 +106102,12 @@ |
| 105733 | 106102 | pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); |
| 105734 | 106103 | pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); |
| 105735 | 106104 | assert( pFrom->a[0].pOn==0 ); |
| 105736 | 106105 | assert( pFrom->a[0].pUsing==0 ); |
| 105737 | 106106 | } |
| 105738 | | - pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, |
| 105739 | | - SF_IncludeHidden, 0, 0); |
| 106107 | + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, |
| 106108 | + SF_IncludeHidden, pLimit, pOffset); |
| 105740 | 106109 | sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); |
| 105741 | 106110 | sqlite3Select(pParse, pSel, &dest); |
| 105742 | 106111 | sqlite3SelectDelete(db, pSel); |
| 105743 | 106112 | } |
| 105744 | 106113 | #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ |
| | @@ -105759,22 +106128,27 @@ |
| 105759 | 106128 | ExprList *pOrderBy, /* The ORDER BY clause. May be null */ |
| 105760 | 106129 | Expr *pLimit, /* The LIMIT clause. May be null */ |
| 105761 | 106130 | Expr *pOffset, /* The OFFSET clause. May be null */ |
| 105762 | 106131 | char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ |
| 105763 | 106132 | ){ |
| 105764 | | - Expr *pWhereRowid = NULL; /* WHERE rowid .. */ |
| 106133 | + sqlite3 *db = pParse->db; |
| 106134 | + Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ |
| 105765 | 106135 | Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ |
| 105766 | | - Expr *pSelectRowid = NULL; /* SELECT rowid ... */ |
| 105767 | 106136 | ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ |
| 105768 | 106137 | SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ |
| 105769 | 106138 | Select *pSelect = NULL; /* Complete SELECT tree */ |
| 106139 | + Table *pTab; |
| 105770 | 106140 | |
| 105771 | 106141 | /* Check that there isn't an ORDER BY without a LIMIT clause. |
| 105772 | 106142 | */ |
| 105773 | | - if( pOrderBy && (pLimit == 0) ) { |
| 106143 | + if( pOrderBy && pLimit==0 ) { |
| 105774 | 106144 | sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); |
| 105775 | | - goto limit_where_cleanup; |
| 106145 | + sqlite3ExprDelete(pParse->db, pWhere); |
| 106146 | + sqlite3ExprListDelete(pParse->db, pOrderBy); |
| 106147 | + sqlite3ExprDelete(pParse->db, pLimit); |
| 106148 | + sqlite3ExprDelete(pParse->db, pOffset); |
| 106149 | + return 0; |
| 105776 | 106150 | } |
| 105777 | 106151 | |
| 105778 | 106152 | /* We only need to generate a select expression if there |
| 105779 | 106153 | ** is a limit/offset term to enforce. |
| 105780 | 106154 | */ |
| | @@ -105791,40 +106165,51 @@ |
| 105791 | 106165 | ** DELETE FROM table_a WHERE rowid IN ( |
| 105792 | 106166 | ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 |
| 105793 | 106167 | ** ); |
| 105794 | 106168 | */ |
| 105795 | 106169 | |
| 105796 | | - pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); |
| 105797 | | - if( pSelectRowid == 0 ) goto limit_where_cleanup; |
| 105798 | | - pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); |
| 105799 | | - if( pEList == 0 ) goto limit_where_cleanup; |
| 106170 | + pTab = pSrc->a[0].pTab; |
| 106171 | + if( HasRowid(pTab) ){ |
| 106172 | + pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); |
| 106173 | + pEList = sqlite3ExprListAppend( |
| 106174 | + pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) |
| 106175 | + ); |
| 106176 | + }else{ |
| 106177 | + Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 106178 | + if( pPk->nKeyCol==1 ){ |
| 106179 | + const char *zName = pTab->aCol[pPk->aiColumn[0]].zName; |
| 106180 | + pLhs = sqlite3Expr(db, TK_ID, zName); |
| 106181 | + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); |
| 106182 | + }else{ |
| 106183 | + int i; |
| 106184 | + for(i=0; i<pPk->nKeyCol; i++){ |
| 106185 | + Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName); |
| 106186 | + pEList = sqlite3ExprListAppend(pParse, pEList, p); |
| 106187 | + } |
| 106188 | + pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); |
| 106189 | + if( pLhs ){ |
| 106190 | + pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); |
| 106191 | + } |
| 106192 | + } |
| 106193 | + } |
| 105800 | 106194 | |
| 105801 | 106195 | /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree |
| 105802 | 106196 | ** and the SELECT subtree. */ |
| 106197 | + pSrc->a[0].pTab = 0; |
| 105803 | 106198 | pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); |
| 105804 | | - if( pSelectSrc == 0 ) { |
| 105805 | | - sqlite3ExprListDelete(pParse->db, pEList); |
| 105806 | | - goto limit_where_cleanup; |
| 105807 | | - } |
| 106199 | + pSrc->a[0].pTab = pTab; |
| 106200 | + pSrc->a[0].pIBIndex = 0; |
| 105808 | 106201 | |
| 105809 | 106202 | /* generate the SELECT expression tree. */ |
| 105810 | | - pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, |
| 105811 | | - pOrderBy,0,pLimit,pOffset); |
| 105812 | | - if( pSelect == 0 ) return 0; |
| 106203 | + pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, |
| 106204 | + pOrderBy,0,pLimit,pOffset |
| 106205 | + ); |
| 105813 | 106206 | |
| 105814 | 106207 | /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ |
| 105815 | | - pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); |
| 105816 | | - pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0; |
| 106208 | + pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); |
| 105817 | 106209 | sqlite3PExprAddSelect(pParse, pInClause, pSelect); |
| 105818 | 106210 | return pInClause; |
| 105819 | | - |
| 105820 | | -limit_where_cleanup: |
| 105821 | | - sqlite3ExprDelete(pParse->db, pWhere); |
| 105822 | | - sqlite3ExprListDelete(pParse->db, pOrderBy); |
| 105823 | | - sqlite3ExprDelete(pParse->db, pLimit); |
| 105824 | | - sqlite3ExprDelete(pParse->db, pOffset); |
| 105825 | | - return 0; |
| 105826 | 106211 | } |
| 105827 | 106212 | #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ |
| 105828 | 106213 | /* && !defined(SQLITE_OMIT_SUBQUERY) */ |
| 105829 | 106214 | |
| 105830 | 106215 | /* |
| | @@ -105835,11 +106220,14 @@ |
| 105835 | 106220 | ** pTabList pWhere |
| 105836 | 106221 | */ |
| 105837 | 106222 | SQLITE_PRIVATE void sqlite3DeleteFrom( |
| 105838 | 106223 | Parse *pParse, /* The parser context */ |
| 105839 | 106224 | SrcList *pTabList, /* The table from which we should delete things */ |
| 105840 | | - Expr *pWhere /* The WHERE clause. May be null */ |
| 106225 | + Expr *pWhere, /* The WHERE clause. May be null */ |
| 106226 | + ExprList *pOrderBy, /* ORDER BY clause. May be null */ |
| 106227 | + Expr *pLimit, /* LIMIT clause. May be null */ |
| 106228 | + Expr *pOffset /* OFFSET clause. May be null */ |
| 105841 | 106229 | ){ |
| 105842 | 106230 | Vdbe *v; /* The virtual database engine */ |
| 105843 | 106231 | Table *pTab; /* The table from which records will be deleted */ |
| 105844 | 106232 | int i; /* Loop counter */ |
| 105845 | 106233 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| | @@ -105879,10 +106267,11 @@ |
| 105879 | 106267 | db = pParse->db; |
| 105880 | 106268 | if( pParse->nErr || db->mallocFailed ){ |
| 105881 | 106269 | goto delete_from_cleanup; |
| 105882 | 106270 | } |
| 105883 | 106271 | assert( pTabList->nSrc==1 ); |
| 106272 | + |
| 105884 | 106273 | |
| 105885 | 106274 | /* Locate the table which we want to delete. This table has to be |
| 105886 | 106275 | ** put in an SrcList structure because some of the subroutines we |
| 105887 | 106276 | ** will be calling are designed to work with multiple tables and expect |
| 105888 | 106277 | ** an SrcList* parameter instead of just a Table* parameter. |
| | @@ -105903,10 +106292,20 @@ |
| 105903 | 106292 | #endif |
| 105904 | 106293 | #ifdef SQLITE_OMIT_VIEW |
| 105905 | 106294 | # undef isView |
| 105906 | 106295 | # define isView 0 |
| 105907 | 106296 | #endif |
| 106297 | + |
| 106298 | +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT |
| 106299 | + if( !isView ){ |
| 106300 | + pWhere = sqlite3LimitWhere( |
| 106301 | + pParse, pTabList, pWhere, pOrderBy, pLimit, pOffset, "DELETE" |
| 106302 | + ); |
| 106303 | + pOrderBy = 0; |
| 106304 | + pLimit = pOffset = 0; |
| 106305 | + } |
| 106306 | +#endif |
| 105908 | 106307 | |
| 105909 | 106308 | /* If pTab is really a view, make sure it has been initialized. |
| 105910 | 106309 | */ |
| 105911 | 106310 | if( sqlite3ViewGetColumnNames(pParse, pTab) ){ |
| 105912 | 106311 | goto delete_from_cleanup; |
| | @@ -105951,12 +106350,16 @@ |
| 105951 | 106350 | /* If we are trying to delete from a view, realize that view into |
| 105952 | 106351 | ** an ephemeral table. |
| 105953 | 106352 | */ |
| 105954 | 106353 | #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) |
| 105955 | 106354 | if( isView ){ |
| 105956 | | - sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur); |
| 106355 | + sqlite3MaterializeView(pParse, pTab, |
| 106356 | + pWhere, pOrderBy, pLimit, pOffset, iTabCur |
| 106357 | + ); |
| 105957 | 106358 | iDataCur = iIdxCur = iTabCur; |
| 106359 | + pOrderBy = 0; |
| 106360 | + pLimit = pOffset = 0; |
| 105958 | 106361 | } |
| 105959 | 106362 | #endif |
| 105960 | 106363 | |
| 105961 | 106364 | /* Resolve the column names in the WHERE clause. |
| 105962 | 106365 | */ |
| | @@ -106196,10 +106599,15 @@ |
| 106196 | 106599 | |
| 106197 | 106600 | delete_from_cleanup: |
| 106198 | 106601 | sqlite3AuthContextPop(&sContext); |
| 106199 | 106602 | sqlite3SrcListDelete(db, pTabList); |
| 106200 | 106603 | sqlite3ExprDelete(db, pWhere); |
| 106604 | +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) |
| 106605 | + sqlite3ExprListDelete(db, pOrderBy); |
| 106606 | + sqlite3ExprDelete(db, pLimit); |
| 106607 | + sqlite3ExprDelete(db, pOffset); |
| 106608 | +#endif |
| 106201 | 106609 | sqlite3DbFree(db, aToOpen); |
| 106202 | 106610 | return; |
| 106203 | 106611 | } |
| 106204 | 106612 | /* Make sure "isView" and other macros defined above are undefined. Otherwise |
| 106205 | 106613 | ** they may interfere with compilation of other functions in this file |
| | @@ -107237,20 +107645,24 @@ |
| 107237 | 107645 | ** For a case-insensitive search, set variable cx to be the same as |
| 107238 | 107646 | ** c but in the other case and search the input string for either |
| 107239 | 107647 | ** c or cx. |
| 107240 | 107648 | */ |
| 107241 | 107649 | if( c<=0x80 ){ |
| 107242 | | - u32 cx; |
| 107650 | + char zStop[3]; |
| 107243 | 107651 | int bMatch; |
| 107244 | 107652 | if( noCase ){ |
| 107245 | | - cx = sqlite3Toupper(c); |
| 107246 | | - c = sqlite3Tolower(c); |
| 107653 | + zStop[0] = sqlite3Toupper(c); |
| 107654 | + zStop[1] = sqlite3Tolower(c); |
| 107655 | + zStop[2] = 0; |
| 107247 | 107656 | }else{ |
| 107248 | | - cx = c; |
| 107657 | + zStop[0] = c; |
| 107658 | + zStop[1] = 0; |
| 107249 | 107659 | } |
| 107250 | | - while( (c2 = *(zString++))!=0 ){ |
| 107251 | | - if( c2!=c && c2!=cx ) continue; |
| 107660 | + while(1){ |
| 107661 | + zString += strcspn((const char*)zString, zStop); |
| 107662 | + if( zString[0]==0 ) break; |
| 107663 | + zString++; |
| 107252 | 107664 | bMatch = patternCompare(zPattern,zString,pInfo,matchOther); |
| 107253 | 107665 | if( bMatch!=SQLITE_NOMATCH ) return bMatch; |
| 107254 | 107666 | } |
| 107255 | 107667 | }else{ |
| 107256 | 107668 | int bMatch; |
| | @@ -109156,11 +109568,11 @@ |
| 109156 | 109568 | iSkip = sqlite3VdbeMakeLabel(v); |
| 109157 | 109569 | sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); |
| 109158 | 109570 | } |
| 109159 | 109571 | |
| 109160 | 109572 | pParse->disableTriggers = 1; |
| 109161 | | - sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); |
| 109573 | + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0, 0); |
| 109162 | 109574 | pParse->disableTriggers = 0; |
| 109163 | 109575 | |
| 109164 | 109576 | /* If the DELETE has generated immediate foreign key constraint |
| 109165 | 109577 | ** violations, halt the VDBE and return an error at this point, before |
| 109166 | 109578 | ** any modifications to the schema are made. This is because statement |
| | @@ -110764,11 +111176,12 @@ |
| 110764 | 111176 | sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); |
| 110765 | 111177 | }else{ |
| 110766 | 111178 | VdbeOp *pOp; |
| 110767 | 111179 | sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); |
| 110768 | 111180 | pOp = sqlite3VdbeGetOp(v, -1); |
| 110769 | | - if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ |
| 111181 | + assert( pOp!=0 ); |
| 111182 | + if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){ |
| 110770 | 111183 | appendFlag = 1; |
| 110771 | 111184 | pOp->opcode = OP_NewRowid; |
| 110772 | 111185 | pOp->p1 = iDataCur; |
| 110773 | 111186 | pOp->p2 = regRowid; |
| 110774 | 111187 | pOp->p3 = regAutoinc; |
| | @@ -117259,11 +117672,12 @@ |
| 117259 | 117672 | ** more likely to cause a segfault than -1 (of course there are assert() |
| 117260 | 117673 | ** statements too, but it never hurts to play the odds). |
| 117261 | 117674 | */ |
| 117262 | 117675 | assert( sqlite3_mutex_held(db->mutex) ); |
| 117263 | 117676 | if( pSchema ){ |
| 117264 | | - for(i=0; ALWAYS(i<db->nDb); i++){ |
| 117677 | + for(i=0; 1; i++){ |
| 117678 | + assert( i<db->nDb ); |
| 117265 | 117679 | if( db->aDb[i].pSchema==pSchema ){ |
| 117266 | 117680 | break; |
| 117267 | 117681 | } |
| 117268 | 117682 | } |
| 117269 | 117683 | assert( i>=0 && i<db->nDb ); |
| | @@ -121068,16 +121482,15 @@ |
| 121068 | 121482 | ** columns of the sub-query. |
| 121069 | 121483 | ** |
| 121070 | 121484 | ** (19) If the subquery uses LIMIT then the outer query may not |
| 121071 | 121485 | ** have a WHERE clause. |
| 121072 | 121486 | ** |
| 121073 | | -** (**) Subsumed into (17d3). Was: If the sub-query is a compound select, |
| 121074 | | -** then it must not use an ORDER BY clause - Ticket #3773. Because |
| 121075 | | -** of (17d3), then only way to have a compound subquery is if it is |
| 121076 | | -** the only term in the FROM clause of the outer query. But if the |
| 121077 | | -** only term in the FROM clause has an ORDER BY, then it will be |
| 121078 | | -** implemented as a co-routine and the flattener will never be called. |
| 121487 | +** (20) If the sub-query is a compound select, then it must not use |
| 121488 | +** an ORDER BY clause. Ticket #3773. We could relax this constraint |
| 121489 | +** somewhat by saying that the terms of the ORDER BY clause must |
| 121490 | +** appear as unmodified result columns in the outer query. But we |
| 121491 | +** have other optimizations in mind to deal with that case. |
| 121079 | 121492 | ** |
| 121080 | 121493 | ** (21) If the subquery uses LIMIT then the outer query may not be |
| 121081 | 121494 | ** DISTINCT. (See ticket [752e1646fc]). |
| 121082 | 121495 | ** |
| 121083 | 121496 | ** (22) The subquery may not be a recursive CTE. |
| | @@ -121207,10 +121620,13 @@ |
| 121207 | 121620 | ** use only the UNION ALL operator. And none of the simple select queries |
| 121208 | 121621 | ** that make up the compound SELECT are allowed to be aggregate or distinct |
| 121209 | 121622 | ** queries. |
| 121210 | 121623 | */ |
| 121211 | 121624 | if( pSub->pPrior ){ |
| 121625 | + if( pSub->pOrderBy ){ |
| 121626 | + return 0; /* Restriction (20) */ |
| 121627 | + } |
| 121212 | 121628 | if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ |
| 121213 | 121629 | return 0; /* (17d1), (17d2), or (17d3) */ |
| 121214 | 121630 | } |
| 121215 | 121631 | for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ |
| 121216 | 121632 | testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); |
| | @@ -121241,19 +121657,10 @@ |
| 121241 | 121657 | ** subquery is a join, then the flattening has already been stopped by |
| 121242 | 121658 | ** restriction (17d3) |
| 121243 | 121659 | */ |
| 121244 | 121660 | assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); |
| 121245 | 121661 | |
| 121246 | | - /* Ex-restriction (20): |
| 121247 | | - ** A compound subquery must be the only term in the FROM clause of the |
| 121248 | | - ** outer query by restriction (17d3). But if that term also has an |
| 121249 | | - ** ORDER BY clause, then the subquery will be implemented by co-routine |
| 121250 | | - ** and so the flattener will never be invoked. Hence, it is not possible |
| 121251 | | - ** for the subquery to be a compound and have an ORDER BY clause. |
| 121252 | | - */ |
| 121253 | | - assert( pSub->pPrior==0 || pSub->pOrderBy==0 ); |
| 121254 | | - |
| 121255 | 121662 | /***** If we reach this point, flattening is permitted. *****/ |
| 121256 | 121663 | SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", |
| 121257 | 121664 | pSub->zSelName, pSub, iFrom)); |
| 121258 | 121665 | |
| 121259 | 121666 | /* Authorize the subquery */ |
| | @@ -121604,46 +122011,48 @@ |
| 121604 | 122011 | return nChng; |
| 121605 | 122012 | } |
| 121606 | 122013 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ |
| 121607 | 122014 | |
| 121608 | 122015 | /* |
| 121609 | | -** Based on the contents of the AggInfo structure indicated by the first |
| 121610 | | -** argument, this function checks if the following are true: |
| 121611 | | -** |
| 121612 | | -** * the query contains just a single aggregate function, |
| 121613 | | -** * the aggregate function is either min() or max(), and |
| 121614 | | -** * the argument to the aggregate function is a column value. |
| 121615 | | -** |
| 121616 | | -** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX |
| 121617 | | -** is returned as appropriate. Also, *ppMinMax is set to point to the |
| 121618 | | -** list of arguments passed to the aggregate before returning. |
| 121619 | | -** |
| 121620 | | -** Or, if the conditions above are not met, *ppMinMax is set to 0 and |
| 121621 | | -** WHERE_ORDERBY_NORMAL is returned. |
| 121622 | | -*/ |
| 121623 | | -static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){ |
| 121624 | | - int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ |
| 121625 | | - |
| 121626 | | - *ppMinMax = 0; |
| 121627 | | - if( pAggInfo->nFunc==1 ){ |
| 121628 | | - Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */ |
| 121629 | | - ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */ |
| 121630 | | - |
| 121631 | | - assert( pExpr->op==TK_AGG_FUNCTION ); |
| 121632 | | - if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){ |
| 121633 | | - const char *zFunc = pExpr->u.zToken; |
| 121634 | | - if( sqlite3StrICmp(zFunc, "min")==0 ){ |
| 121635 | | - eRet = WHERE_ORDERBY_MIN; |
| 121636 | | - *ppMinMax = pEList; |
| 121637 | | - }else if( sqlite3StrICmp(zFunc, "max")==0 ){ |
| 121638 | | - eRet = WHERE_ORDERBY_MAX; |
| 121639 | | - *ppMinMax = pEList; |
| 121640 | | - } |
| 121641 | | - } |
| 121642 | | - } |
| 121643 | | - |
| 121644 | | - assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 ); |
| 122016 | +** The pFunc is the only aggregate function in the query. Check to see |
| 122017 | +** if the query is a candidate for the min/max optimization. |
| 122018 | +** |
| 122019 | +** If the query is a candidate for the min/max optimization, then set |
| 122020 | +** *ppMinMax to be an ORDER BY clause to be used for the optimization |
| 122021 | +** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on |
| 122022 | +** whether pFunc is a min() or max() function. |
| 122023 | +** |
| 122024 | +** If the query is not a candidate for the min/max optimization, return |
| 122025 | +** WHERE_ORDERBY_NORMAL (which must be zero). |
| 122026 | +** |
| 122027 | +** This routine must be called after aggregate functions have been |
| 122028 | +** located but before their arguments have been subjected to aggregate |
| 122029 | +** analysis. |
| 122030 | +*/ |
| 122031 | +static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ |
| 122032 | + int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ |
| 122033 | + ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ |
| 122034 | + const char *zFunc; /* Name of aggregate function pFunc */ |
| 122035 | + ExprList *pOrderBy; |
| 122036 | + u8 sortOrder; |
| 122037 | + |
| 122038 | + assert( *ppMinMax==0 ); |
| 122039 | + assert( pFunc->op==TK_AGG_FUNCTION ); |
| 122040 | + if( pEList==0 || pEList->nExpr!=1 ) return eRet; |
| 122041 | + zFunc = pFunc->u.zToken; |
| 122042 | + if( sqlite3StrICmp(zFunc, "min")==0 ){ |
| 122043 | + eRet = WHERE_ORDERBY_MIN; |
| 122044 | + sortOrder = SQLITE_SO_ASC; |
| 122045 | + }else if( sqlite3StrICmp(zFunc, "max")==0 ){ |
| 122046 | + eRet = WHERE_ORDERBY_MAX; |
| 122047 | + sortOrder = SQLITE_SO_DESC; |
| 122048 | + }else{ |
| 122049 | + return eRet; |
| 122050 | + } |
| 122051 | + *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); |
| 122052 | + assert( pOrderBy!=0 || db->mallocFailed ); |
| 122053 | + if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder; |
| 121645 | 122054 | return eRet; |
| 121646 | 122055 | } |
| 121647 | 122056 | |
| 121648 | 122057 | /* |
| 121649 | 122058 | ** The select statement passed as the first argument is an aggregate query. |
| | @@ -122026,16 +122435,18 @@ |
| 122026 | 122435 | ExprList *pEList; |
| 122027 | 122436 | struct SrcList_item *pFrom; |
| 122028 | 122437 | sqlite3 *db = pParse->db; |
| 122029 | 122438 | Expr *pE, *pRight, *pExpr; |
| 122030 | 122439 | u16 selFlags = p->selFlags; |
| 122440 | + u32 elistFlags = 0; |
| 122031 | 122441 | |
| 122032 | 122442 | p->selFlags |= SF_Expanded; |
| 122033 | 122443 | if( db->mallocFailed ){ |
| 122034 | 122444 | return WRC_Abort; |
| 122035 | 122445 | } |
| 122036 | | - if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ |
| 122446 | + assert( p->pSrc!=0 ); |
| 122447 | + if( (selFlags & SF_Expanded)!=0 ){ |
| 122037 | 122448 | return WRC_Prune; |
| 122038 | 122449 | } |
| 122039 | 122450 | pTabList = p->pSrc; |
| 122040 | 122451 | pEList = p->pEList; |
| 122041 | 122452 | if( OK_IF_ALWAYS_TRUE(p->pWith) ){ |
| | @@ -122138,10 +122549,11 @@ |
| 122138 | 122549 | pE = pEList->a[k].pExpr; |
| 122139 | 122550 | if( pE->op==TK_ASTERISK ) break; |
| 122140 | 122551 | assert( pE->op!=TK_DOT || pE->pRight!=0 ); |
| 122141 | 122552 | assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); |
| 122142 | 122553 | if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; |
| 122554 | + elistFlags |= pE->flags; |
| 122143 | 122555 | } |
| 122144 | 122556 | if( k<pEList->nExpr ){ |
| 122145 | 122557 | /* |
| 122146 | 122558 | ** If we get here it means the result set contains one or more "*" |
| 122147 | 122559 | ** operators that need to be expanded. Loop through each expression |
| | @@ -122153,10 +122565,11 @@ |
| 122153 | 122565 | int longNames = (flags & SQLITE_FullColNames)!=0 |
| 122154 | 122566 | && (flags & SQLITE_ShortColNames)==0; |
| 122155 | 122567 | |
| 122156 | 122568 | for(k=0; k<pEList->nExpr; k++){ |
| 122157 | 122569 | pE = a[k].pExpr; |
| 122570 | + elistFlags |= pE->flags; |
| 122158 | 122571 | pRight = pE->pRight; |
| 122159 | 122572 | assert( pE->op!=TK_DOT || pRight!=0 ); |
| 122160 | 122573 | if( pE->op!=TK_ASTERISK |
| 122161 | 122574 | && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK) |
| 122162 | 122575 | ){ |
| | @@ -122282,13 +122695,18 @@ |
| 122282 | 122695 | } |
| 122283 | 122696 | } |
| 122284 | 122697 | sqlite3ExprListDelete(db, pEList); |
| 122285 | 122698 | p->pEList = pNew; |
| 122286 | 122699 | } |
| 122287 | | - if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ |
| 122288 | | - sqlite3ErrorMsg(pParse, "too many columns in result set"); |
| 122289 | | - return WRC_Abort; |
| 122700 | + if( p->pEList ){ |
| 122701 | + if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ |
| 122702 | + sqlite3ErrorMsg(pParse, "too many columns in result set"); |
| 122703 | + return WRC_Abort; |
| 122704 | + } |
| 122705 | + if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ |
| 122706 | + p->selFlags |= SF_ComplexResult; |
| 122707 | + } |
| 122290 | 122708 | } |
| 122291 | 122709 | return WRC_Continue; |
| 122292 | 122710 | } |
| 122293 | 122711 | |
| 122294 | 122712 | /* |
| | @@ -122820,10 +123238,12 @@ |
| 122820 | 123238 | DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ |
| 122821 | 123239 | SortCtx sSort; /* Info on how to code the ORDER BY clause */ |
| 122822 | 123240 | AggInfo sAggInfo; /* Information used by aggregate queries */ |
| 122823 | 123241 | int iEnd; /* Address of the end of the query */ |
| 122824 | 123242 | sqlite3 *db; /* The database connection */ |
| 123243 | + ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ |
| 123244 | + u8 minMaxFlag; /* Flag for min/max queries */ |
| 122825 | 123245 | |
| 122826 | 123246 | #ifndef SQLITE_OMIT_EXPLAIN |
| 122827 | 123247 | int iRestoreSelectId = pParse->iSelectId; |
| 122828 | 123248 | pParse->iSelectId = pParse->iNextSelectId++; |
| 122829 | 123249 | #endif |
| | @@ -122906,22 +123326,31 @@ |
| 122906 | 123326 | ** flattening in that case. |
| 122907 | 123327 | */ |
| 122908 | 123328 | if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; |
| 122909 | 123329 | assert( pSub->pGroupBy==0 ); |
| 122910 | 123330 | |
| 122911 | | - /* If the subquery contains an ORDER BY clause and if |
| 123331 | + /* If the outer query contains a "complex" result set (that is, |
| 123332 | + ** if the result set of the outer query uses functions or subqueries) |
| 123333 | + ** and if the subquery contains an ORDER BY clause and if |
| 122912 | 123334 | ** it will be implemented as a co-routine, then do not flatten. This |
| 122913 | 123335 | ** restriction allows SQL constructs like this: |
| 122914 | 123336 | ** |
| 122915 | 123337 | ** SELECT expensive_function(x) |
| 122916 | 123338 | ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10); |
| 122917 | 123339 | ** |
| 122918 | 123340 | ** The expensive_function() is only computed on the 10 rows that |
| 122919 | 123341 | ** are output, rather than every row of the table. |
| 123342 | + ** |
| 123343 | + ** The requirement that the outer query have a complex result set |
| 123344 | + ** means that flattening does occur on simpler SQL constraints without |
| 123345 | + ** the expensive_function() like: |
| 123346 | + ** |
| 123347 | + ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10); |
| 122920 | 123348 | */ |
| 122921 | 123349 | if( pSub->pOrderBy!=0 |
| 122922 | 123350 | && i==0 |
| 123351 | + && (p->selFlags & SF_ComplexResult)!=0 |
| 122923 | 123352 | && (pTabList->nSrc==1 |
| 122924 | 123353 | || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) |
| 122925 | 123354 | ){ |
| 122926 | 123355 | continue; |
| 122927 | 123356 | } |
| | @@ -123336,18 +123765,41 @@ |
| 123336 | 123765 | pWhere = p->pWhere; |
| 123337 | 123766 | } |
| 123338 | 123767 | sqlite3ExprAnalyzeAggregates(&sNC, pHaving); |
| 123339 | 123768 | } |
| 123340 | 123769 | sAggInfo.nAccumulator = sAggInfo.nColumn; |
| 123770 | + if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ |
| 123771 | + minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy); |
| 123772 | + }else{ |
| 123773 | + minMaxFlag = WHERE_ORDERBY_NORMAL; |
| 123774 | + } |
| 123341 | 123775 | for(i=0; i<sAggInfo.nFunc; i++){ |
| 123342 | 123776 | assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) ); |
| 123343 | 123777 | sNC.ncFlags |= NC_InAggFunc; |
| 123344 | 123778 | sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList); |
| 123345 | 123779 | sNC.ncFlags &= ~NC_InAggFunc; |
| 123346 | 123780 | } |
| 123347 | 123781 | sAggInfo.mxReg = pParse->nMem; |
| 123348 | 123782 | if( db->mallocFailed ) goto select_end; |
| 123783 | +#if SELECTTRACE_ENABLED |
| 123784 | + if( sqlite3SelectTrace & 0x400 ){ |
| 123785 | + int ii; |
| 123786 | + SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n")); |
| 123787 | + sqlite3TreeViewSelect(0, p, 0); |
| 123788 | + for(ii=0; ii<sAggInfo.nColumn; ii++){ |
| 123789 | + sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", |
| 123790 | + ii, sAggInfo.aCol[ii].iMem); |
| 123791 | + sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0); |
| 123792 | + } |
| 123793 | + for(ii=0; ii<sAggInfo.nFunc; ii++){ |
| 123794 | + sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", |
| 123795 | + ii, sAggInfo.aFunc[ii].iMem); |
| 123796 | + sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0); |
| 123797 | + } |
| 123798 | + } |
| 123799 | +#endif |
| 123800 | + |
| 123349 | 123801 | |
| 123350 | 123802 | /* Processing for aggregates with GROUP BY is very different and |
| 123351 | 123803 | ** much more complex than aggregates without a GROUP BY. |
| 123352 | 123804 | */ |
| 123353 | 123805 | if( pGroupBy ){ |
| | @@ -123573,11 +124025,10 @@ |
| 123573 | 124025 | resetAccumulator(pParse, &sAggInfo); |
| 123574 | 124026 | sqlite3VdbeAddOp1(v, OP_Return, regReset); |
| 123575 | 124027 | |
| 123576 | 124028 | } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ |
| 123577 | 124029 | else { |
| 123578 | | - ExprList *pDel = 0; |
| 123579 | 124030 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 123580 | 124031 | Table *pTab; |
| 123581 | 124032 | if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){ |
| 123582 | 124033 | /* If isSimpleCount() returns a pointer to a Table structure, then |
| 123583 | 124034 | ** the SQL statement is of the form: |
| | @@ -123635,81 +124086,44 @@ |
| 123635 | 124086 | sqlite3VdbeAddOp1(v, OP_Close, iCsr); |
| 123636 | 124087 | explainSimpleCount(pParse, pTab, pBest); |
| 123637 | 124088 | }else |
| 123638 | 124089 | #endif /* SQLITE_OMIT_BTREECOUNT */ |
| 123639 | 124090 | { |
| 123640 | | - /* Check if the query is of one of the following forms: |
| 123641 | | - ** |
| 123642 | | - ** SELECT min(x) FROM ... |
| 123643 | | - ** SELECT max(x) FROM ... |
| 123644 | | - ** |
| 123645 | | - ** If it is, then ask the code in where.c to attempt to sort results |
| 123646 | | - ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. |
| 123647 | | - ** If where.c is able to produce results sorted in this order, then |
| 123648 | | - ** add vdbe code to break out of the processing loop after the |
| 123649 | | - ** first iteration (since the first iteration of the loop is |
| 123650 | | - ** guaranteed to operate on the row with the minimum or maximum |
| 123651 | | - ** value of x, the only row required). |
| 123652 | | - ** |
| 123653 | | - ** A special flag must be passed to sqlite3WhereBegin() to slightly |
| 123654 | | - ** modify behavior as follows: |
| 123655 | | - ** |
| 123656 | | - ** + If the query is a "SELECT min(x)", then the loop coded by |
| 123657 | | - ** where.c should not iterate over any values with a NULL value |
| 123658 | | - ** for x. |
| 123659 | | - ** |
| 123660 | | - ** + The optimizer code in where.c (the thing that decides which |
| 123661 | | - ** index or indices to use) should place a different priority on |
| 123662 | | - ** satisfying the 'ORDER BY' clause than it does in other cases. |
| 123663 | | - ** Refer to code and comments in where.c for details. |
| 123664 | | - */ |
| 123665 | | - ExprList *pMinMax = 0; |
| 123666 | | - u8 flag = WHERE_ORDERBY_NORMAL; |
| 123667 | | - |
| 123668 | | - assert( p->pGroupBy==0 ); |
| 123669 | | - assert( flag==0 ); |
| 123670 | | - if( p->pHaving==0 ){ |
| 123671 | | - flag = minMaxQuery(&sAggInfo, &pMinMax); |
| 123672 | | - } |
| 123673 | | - assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); |
| 123674 | | - |
| 123675 | | - if( flag ){ |
| 123676 | | - pMinMax = sqlite3ExprListDup(db, pMinMax, 0); |
| 123677 | | - pDel = pMinMax; |
| 123678 | | - assert( db->mallocFailed || pMinMax!=0 ); |
| 123679 | | - if( !db->mallocFailed ){ |
| 123680 | | - pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; |
| 123681 | | - pMinMax->a[0].pExpr->op = TK_COLUMN; |
| 123682 | | - } |
| 123683 | | - } |
| 123684 | | - |
| 123685 | 124091 | /* This case runs if the aggregate has no GROUP BY clause. The |
| 123686 | 124092 | ** processing is much simpler since there is only a single row |
| 123687 | 124093 | ** of output. |
| 123688 | 124094 | */ |
| 124095 | + assert( p->pGroupBy==0 ); |
| 123689 | 124096 | resetAccumulator(pParse, &sAggInfo); |
| 123690 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0); |
| 124097 | + |
| 124098 | + /* If this query is a candidate for the min/max optimization, then |
| 124099 | + ** minMaxFlag will have been previously set to either |
| 124100 | + ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will |
| 124101 | + ** be an appropriate ORDER BY expression for the optimization. |
| 124102 | + */ |
| 124103 | + assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); |
| 124104 | + assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); |
| 124105 | + |
| 124106 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, |
| 124107 | + 0, minMaxFlag, 0); |
| 123691 | 124108 | if( pWInfo==0 ){ |
| 123692 | | - sqlite3ExprListDelete(db, pDel); |
| 123693 | 124109 | goto select_end; |
| 123694 | 124110 | } |
| 123695 | 124111 | updateAccumulator(pParse, &sAggInfo); |
| 123696 | | - assert( pMinMax==0 || pMinMax->nExpr==1 ); |
| 123697 | 124112 | if( sqlite3WhereIsOrdered(pWInfo)>0 ){ |
| 123698 | 124113 | sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); |
| 123699 | 124114 | VdbeComment((v, "%s() by index", |
| 123700 | | - (flag==WHERE_ORDERBY_MIN?"min":"max"))); |
| 124115 | + (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max"))); |
| 123701 | 124116 | } |
| 123702 | 124117 | sqlite3WhereEnd(pWInfo); |
| 123703 | 124118 | finalizeAggFunctions(pParse, &sAggInfo); |
| 123704 | 124119 | } |
| 123705 | 124120 | |
| 123706 | 124121 | sSort.pOrderBy = 0; |
| 123707 | 124122 | sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); |
| 123708 | 124123 | selectInnerLoop(pParse, p, -1, 0, 0, |
| 123709 | 124124 | pDest, addrEnd, addrEnd); |
| 123710 | | - sqlite3ExprListDelete(db, pDel); |
| 123711 | 124125 | } |
| 123712 | 124126 | sqlite3VdbeResolveLabel(v, addrEnd); |
| 123713 | 124127 | |
| 123714 | 124128 | } /* endif aggregate query */ |
| 123715 | 124129 | |
| | @@ -123737,11 +124151,11 @@ |
| 123737 | 124151 | /* Control jumps to here if an error is encountered above, or upon |
| 123738 | 124152 | ** successful coding of the SELECT. |
| 123739 | 124153 | */ |
| 123740 | 124154 | select_end: |
| 123741 | 124155 | explainSetInteger(pParse->iSelectId, iRestoreSelectId); |
| 123742 | | - |
| 124156 | + sqlite3ExprListDelete(db, pMinMaxOrderBy); |
| 123743 | 124157 | sqlite3DbFree(db, sAggInfo.aCol); |
| 123744 | 124158 | sqlite3DbFree(db, sAggInfo.aFunc); |
| 123745 | 124159 | #if SELECTTRACE_ENABLED |
| 123746 | 124160 | SELECTTRACE(1,pParse,p,("end processing\n")); |
| 123747 | 124161 | pParse->nSelectIndent--; |
| | @@ -124663,11 +125077,11 @@ |
| 124663 | 125077 | case TK_UPDATE: { |
| 124664 | 125078 | sqlite3Update(pParse, |
| 124665 | 125079 | targetSrcList(pParse, pStep), |
| 124666 | 125080 | sqlite3ExprListDup(db, pStep->pExprList, 0), |
| 124667 | 125081 | sqlite3ExprDup(db, pStep->pWhere, 0), |
| 124668 | | - pParse->eOrconf |
| 125082 | + pParse->eOrconf, 0, 0, 0 |
| 124669 | 125083 | ); |
| 124670 | 125084 | break; |
| 124671 | 125085 | } |
| 124672 | 125086 | case TK_INSERT: { |
| 124673 | 125087 | sqlite3Insert(pParse, |
| | @@ -124679,11 +125093,11 @@ |
| 124679 | 125093 | break; |
| 124680 | 125094 | } |
| 124681 | 125095 | case TK_DELETE: { |
| 124682 | 125096 | sqlite3DeleteFrom(pParse, |
| 124683 | 125097 | targetSrcList(pParse, pStep), |
| 124684 | | - sqlite3ExprDup(db, pStep->pWhere, 0) |
| 125098 | + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0, 0 |
| 124685 | 125099 | ); |
| 124686 | 125100 | break; |
| 124687 | 125101 | } |
| 124688 | 125102 | default: assert( pStep->op==TK_SELECT ); { |
| 124689 | 125103 | SelectDest sDest; |
| | @@ -125146,11 +125560,14 @@ |
| 125146 | 125560 | SQLITE_PRIVATE void sqlite3Update( |
| 125147 | 125561 | Parse *pParse, /* The parser context */ |
| 125148 | 125562 | SrcList *pTabList, /* The table in which we should change things */ |
| 125149 | 125563 | ExprList *pChanges, /* Things to be changed */ |
| 125150 | 125564 | Expr *pWhere, /* The WHERE clause. May be null */ |
| 125151 | | - int onError /* How to handle constraint errors */ |
| 125565 | + int onError, /* How to handle constraint errors */ |
| 125566 | + ExprList *pOrderBy, /* ORDER BY clause. May be null */ |
| 125567 | + Expr *pLimit, /* LIMIT clause. May be null */ |
| 125568 | + Expr *pOffset /* OFFSET clause. May be null */ |
| 125152 | 125569 | ){ |
| 125153 | 125570 | int i, j; /* Loop counters */ |
| 125154 | 125571 | Table *pTab; /* The table to be updated */ |
| 125155 | 125572 | int addrTop = 0; /* VDBE instruction address of the start of the loop */ |
| 125156 | 125573 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| | @@ -125230,10 +125647,20 @@ |
| 125230 | 125647 | #endif |
| 125231 | 125648 | #ifdef SQLITE_OMIT_VIEW |
| 125232 | 125649 | # undef isView |
| 125233 | 125650 | # define isView 0 |
| 125234 | 125651 | #endif |
| 125652 | + |
| 125653 | +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT |
| 125654 | + if( !isView ){ |
| 125655 | + pWhere = sqlite3LimitWhere( |
| 125656 | + pParse, pTabList, pWhere, pOrderBy, pLimit, pOffset, "UPDATE" |
| 125657 | + ); |
| 125658 | + pOrderBy = 0; |
| 125659 | + pLimit = pOffset = 0; |
| 125660 | + } |
| 125661 | +#endif |
| 125235 | 125662 | |
| 125236 | 125663 | if( sqlite3ViewGetColumnNames(pParse, pTab) ){ |
| 125237 | 125664 | goto update_cleanup; |
| 125238 | 125665 | } |
| 125239 | 125666 | if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ |
| | @@ -125399,11 +125826,15 @@ |
| 125399 | 125826 | /* If we are trying to update a view, realize that view into |
| 125400 | 125827 | ** an ephemeral table. |
| 125401 | 125828 | */ |
| 125402 | 125829 | #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) |
| 125403 | 125830 | if( isView ){ |
| 125404 | | - sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur); |
| 125831 | + sqlite3MaterializeView(pParse, pTab, |
| 125832 | + pWhere, pOrderBy, pLimit, pOffset, iDataCur |
| 125833 | + ); |
| 125834 | + pOrderBy = 0; |
| 125835 | + pLimit = pOffset = 0; |
| 125405 | 125836 | } |
| 125406 | 125837 | #endif |
| 125407 | 125838 | |
| 125408 | 125839 | /* Resolve the column names in all the expressions in the |
| 125409 | 125840 | ** WHERE clause. |
| | @@ -125783,10 +126214,15 @@ |
| 125783 | 126214 | sqlite3AuthContextPop(&sContext); |
| 125784 | 126215 | sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ |
| 125785 | 126216 | sqlite3SrcListDelete(db, pTabList); |
| 125786 | 126217 | sqlite3ExprListDelete(db, pChanges); |
| 125787 | 126218 | sqlite3ExprDelete(db, pWhere); |
| 126219 | +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) |
| 126220 | + sqlite3ExprListDelete(db, pOrderBy); |
| 126221 | + sqlite3ExprDelete(db, pLimit); |
| 126222 | + sqlite3ExprDelete(db, pOffset); |
| 126223 | +#endif |
| 125788 | 126224 | return; |
| 125789 | 126225 | } |
| 125790 | 126226 | /* Make sure "isView" and other macros defined above are undefined. Otherwise |
| 125791 | 126227 | ** they may interfere with compilation of other functions in this file |
| 125792 | 126228 | ** (or in another file, if this file becomes part of the amalgamation). */ |
| | @@ -128413,12 +128849,12 @@ |
| 128413 | 128849 | ** a conditional such that is only evaluated on the second pass of a |
| 128414 | 128850 | ** LIKE-optimization loop, when scanning BLOBs instead of strings. |
| 128415 | 128851 | */ |
| 128416 | 128852 | static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ |
| 128417 | 128853 | int nLoop = 0; |
| 128418 | | - while( ALWAYS(pTerm!=0) |
| 128419 | | - && (pTerm->wtFlags & TERM_CODED)==0 |
| 128854 | + assert( pTerm!=0 ); |
| 128855 | + while( (pTerm->wtFlags & TERM_CODED)==0 |
| 128420 | 128856 | && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) |
| 128421 | 128857 | && (pLevel->notReady & pTerm->prereqAll)==0 |
| 128422 | 128858 | ){ |
| 128423 | 128859 | if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ |
| 128424 | 128860 | pTerm->wtFlags |= TERM_LIKECOND; |
| | @@ -128425,10 +128861,11 @@ |
| 128425 | 128861 | }else{ |
| 128426 | 128862 | pTerm->wtFlags |= TERM_CODED; |
| 128427 | 128863 | } |
| 128428 | 128864 | if( pTerm->iParent<0 ) break; |
| 128429 | 128865 | pTerm = &pTerm->pWC->a[pTerm->iParent]; |
| 128866 | + assert( pTerm!=0 ); |
| 128430 | 128867 | pTerm->nChild--; |
| 128431 | 128868 | if( pTerm->nChild!=0 ) break; |
| 128432 | 128869 | nLoop++; |
| 128433 | 128870 | } |
| 128434 | 128871 | } |
| | @@ -131257,11 +131694,11 @@ |
| 131257 | 131694 | int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ |
| 131258 | 131695 | int noCase = 0; /* uppercase equivalent to lowercase */ |
| 131259 | 131696 | int op; /* Top-level operator. pExpr->op */ |
| 131260 | 131697 | Parse *pParse = pWInfo->pParse; /* Parsing context */ |
| 131261 | 131698 | sqlite3 *db = pParse->db; /* Database connection */ |
| 131262 | | - unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */ |
| 131699 | + unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */ |
| 131263 | 131700 | int nLeft; /* Number of elements on left side vector */ |
| 131264 | 131701 | |
| 131265 | 131702 | if( db->mallocFailed ){ |
| 131266 | 131703 | return; |
| 131267 | 131704 | } |
| | @@ -131501,11 +131938,11 @@ |
| 131501 | 131938 | ** This information is used by the xBestIndex methods of |
| 131502 | 131939 | ** virtual tables. The native query optimizer does not attempt |
| 131503 | 131940 | ** to do anything with MATCH functions. |
| 131504 | 131941 | */ |
| 131505 | 131942 | if( pWC->op==TK_AND ){ |
| 131506 | | - Expr *pRight, *pLeft; |
| 131943 | + Expr *pRight = 0, *pLeft = 0; |
| 131507 | 131944 | int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight); |
| 131508 | 131945 | while( res-- > 0 ){ |
| 131509 | 131946 | int idxNew; |
| 131510 | 131947 | WhereTerm *pNewTerm; |
| 131511 | 131948 | Bitmask prereqColumn, prereqExpr; |
| | @@ -133669,26 +134106,25 @@ |
| 133669 | 134106 | |
| 133670 | 134107 | /* |
| 133671 | 134108 | ** Free a WhereInfo structure |
| 133672 | 134109 | */ |
| 133673 | 134110 | static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ |
| 133674 | | - if( ALWAYS(pWInfo) ){ |
| 133675 | | - int i; |
| 133676 | | - for(i=0; i<pWInfo->nLevel; i++){ |
| 133677 | | - WhereLevel *pLevel = &pWInfo->a[i]; |
| 133678 | | - if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ |
| 133679 | | - sqlite3DbFree(db, pLevel->u.in.aInLoop); |
| 133680 | | - } |
| 133681 | | - } |
| 133682 | | - sqlite3WhereClauseClear(&pWInfo->sWC); |
| 133683 | | - while( pWInfo->pLoops ){ |
| 133684 | | - WhereLoop *p = pWInfo->pLoops; |
| 133685 | | - pWInfo->pLoops = p->pNextLoop; |
| 133686 | | - whereLoopDelete(db, p); |
| 133687 | | - } |
| 133688 | | - sqlite3DbFreeNN(db, pWInfo); |
| 133689 | | - } |
| 134111 | + int i; |
| 134112 | + assert( pWInfo!=0 ); |
| 134113 | + for(i=0; i<pWInfo->nLevel; i++){ |
| 134114 | + WhereLevel *pLevel = &pWInfo->a[i]; |
| 134115 | + if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ |
| 134116 | + sqlite3DbFree(db, pLevel->u.in.aInLoop); |
| 134117 | + } |
| 134118 | + } |
| 134119 | + sqlite3WhereClauseClear(&pWInfo->sWC); |
| 134120 | + while( pWInfo->pLoops ){ |
| 134121 | + WhereLoop *p = pWInfo->pLoops; |
| 134122 | + pWInfo->pLoops = p->pNextLoop; |
| 134123 | + whereLoopDelete(db, p); |
| 134124 | + } |
| 134125 | + sqlite3DbFreeNN(db, pWInfo); |
| 133690 | 134126 | } |
| 133691 | 134127 | |
| 133692 | 134128 | /* |
| 133693 | 134129 | ** Return TRUE if all of the following are true: |
| 133694 | 134130 | ** |
| | @@ -134676,13 +135112,15 @@ |
| 134676 | 135112 | } |
| 134677 | 135113 | } |
| 134678 | 135114 | } |
| 134679 | 135115 | #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ |
| 134680 | 135116 | |
| 134681 | | - /* Loop over all indices |
| 134682 | | - */ |
| 134683 | | - for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ |
| 135117 | + /* Loop over all indices. If there was an INDEXED BY clause, then only |
| 135118 | + ** consider index pProbe. */ |
| 135119 | + for(; rc==SQLITE_OK && pProbe; |
| 135120 | + pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ |
| 135121 | + ){ |
| 134684 | 135122 | if( pProbe->pPartIdxWhere!=0 |
| 134685 | 135123 | && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ |
| 134686 | 135124 | testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ |
| 134687 | 135125 | continue; /* Partial index inappropriate for this query */ |
| 134688 | 135126 | } |
| | @@ -134788,14 +135226,10 @@ |
| 134788 | 135226 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 134789 | 135227 | sqlite3Stat4ProbeFree(pBuilder->pRec); |
| 134790 | 135228 | pBuilder->nRecValid = 0; |
| 134791 | 135229 | pBuilder->pRec = 0; |
| 134792 | 135230 | #endif |
| 134793 | | - |
| 134794 | | - /* If there was an INDEXED BY clause, then only that one index is |
| 134795 | | - ** considered. */ |
| 134796 | | - if( pSrc->pIBIndex ) break; |
| 134797 | 135231 | } |
| 134798 | 135232 | return rc; |
| 134799 | 135233 | } |
| 134800 | 135234 | |
| 134801 | 135235 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -139726,19 +140160,19 @@ |
| 139726 | 140160 | break; |
| 139727 | 140161 | case 133: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */ |
| 139728 | 140162 | { |
| 139729 | 140163 | sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1); |
| 139730 | 140164 | sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0); |
| 139731 | | - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72); |
| 140165 | + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72,0,0,0); |
| 139732 | 140166 | } |
| 139733 | 140167 | break; |
| 139734 | 140168 | case 136: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */ |
| 139735 | 140169 | { |
| 139736 | 140170 | sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1); |
| 139737 | 140171 | sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0); |
| 139738 | 140172 | sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list"); |
| 139739 | | - sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194); |
| 140173 | + sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194,0,0,0); |
| 139740 | 140174 | } |
| 139741 | 140175 | break; |
| 139742 | 140176 | case 137: /* setlist ::= setlist COMMA nm EQ expr */ |
| 139743 | 140177 | { |
| 139744 | 140178 | yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr); |
| | @@ -143290,11 +143724,11 @@ |
| 143290 | 143724 | case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; |
| 143291 | 143725 | case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; |
| 143292 | 143726 | case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; |
| 143293 | 143727 | case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; |
| 143294 | 143728 | case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; |
| 143295 | | - case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; |
| 143729 | + case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break; |
| 143296 | 143730 | case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; |
| 143297 | 143731 | case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; |
| 143298 | 143732 | case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; |
| 143299 | 143733 | case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; |
| 143300 | 143734 | case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; |
| | @@ -165839,11 +166273,11 @@ |
| 165839 | 166273 | |
| 165840 | 166274 | /* |
| 165841 | 166275 | ** The smallest possible node-size is (512-64)==448 bytes. And the largest |
| 165842 | 166276 | ** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). |
| 165843 | 166277 | ** Therefore all non-root nodes must contain at least 3 entries. Since |
| 165844 | | -** 2^40 is greater than 2^64, an r-tree structure always has a depth of |
| 166278 | +** 3^40 is greater than 2^64, an r-tree structure always has a depth of |
| 165845 | 166279 | ** 40 or less. |
| 165846 | 166280 | */ |
| 165847 | 166281 | #define RTREE_MAX_DEPTH 40 |
| 165848 | 166282 | |
| 165849 | 166283 | |
| | @@ -169237,10 +169671,467 @@ |
| 169237 | 169671 | }else{ |
| 169238 | 169672 | u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]); |
| 169239 | 169673 | sqlite3_result_int(ctx, readInt16(zBlob)); |
| 169240 | 169674 | } |
| 169241 | 169675 | } |
| 169676 | + |
| 169677 | +/* |
| 169678 | +** Context object passed between the various routines that make up the |
| 169679 | +** implementation of integrity-check function rtreecheck(). |
| 169680 | +*/ |
| 169681 | +typedef struct RtreeCheck RtreeCheck; |
| 169682 | +struct RtreeCheck { |
| 169683 | + sqlite3 *db; /* Database handle */ |
| 169684 | + const char *zDb; /* Database containing rtree table */ |
| 169685 | + const char *zTab; /* Name of rtree table */ |
| 169686 | + int bInt; /* True for rtree_i32 table */ |
| 169687 | + int nDim; /* Number of dimensions for this rtree tbl */ |
| 169688 | + sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */ |
| 169689 | + sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */ |
| 169690 | + int nLeaf; /* Number of leaf cells in table */ |
| 169691 | + int nNonLeaf; /* Number of non-leaf cells in table */ |
| 169692 | + int rc; /* Return code */ |
| 169693 | + char *zReport; /* Message to report */ |
| 169694 | + int nErr; /* Number of lines in zReport */ |
| 169695 | +}; |
| 169696 | + |
| 169697 | +#define RTREE_CHECK_MAX_ERROR 100 |
| 169698 | + |
| 169699 | +/* |
| 169700 | +** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error, |
| 169701 | +** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code. |
| 169702 | +*/ |
| 169703 | +static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){ |
| 169704 | + int rc = sqlite3_reset(pStmt); |
| 169705 | + if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc; |
| 169706 | +} |
| 169707 | + |
| 169708 | +/* |
| 169709 | +** The second and subsequent arguments to this function are a format string |
| 169710 | +** and printf style arguments. This function formats the string and attempts |
| 169711 | +** to compile it as an SQL statement. |
| 169712 | +** |
| 169713 | +** If successful, a pointer to the new SQL statement is returned. Otherwise, |
| 169714 | +** NULL is returned and an error code left in RtreeCheck.rc. |
| 169715 | +*/ |
| 169716 | +static sqlite3_stmt *rtreeCheckPrepare( |
| 169717 | + RtreeCheck *pCheck, /* RtreeCheck object */ |
| 169718 | + const char *zFmt, ... /* Format string and trailing args */ |
| 169719 | +){ |
| 169720 | + va_list ap; |
| 169721 | + char *z; |
| 169722 | + sqlite3_stmt *pRet = 0; |
| 169723 | + |
| 169724 | + va_start(ap, zFmt); |
| 169725 | + z = sqlite3_vmprintf(zFmt, ap); |
| 169726 | + |
| 169727 | + if( pCheck->rc==SQLITE_OK ){ |
| 169728 | + if( z==0 ){ |
| 169729 | + pCheck->rc = SQLITE_NOMEM; |
| 169730 | + }else{ |
| 169731 | + pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); |
| 169732 | + } |
| 169733 | + } |
| 169734 | + |
| 169735 | + sqlite3_free(z); |
| 169736 | + va_end(ap); |
| 169737 | + return pRet; |
| 169738 | +} |
| 169739 | + |
| 169740 | +/* |
| 169741 | +** The second and subsequent arguments to this function are a printf() |
| 169742 | +** style format string and arguments. This function formats the string and |
| 169743 | +** appends it to the report being accumuated in pCheck. |
| 169744 | +*/ |
| 169745 | +static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ |
| 169746 | + va_list ap; |
| 169747 | + va_start(ap, zFmt); |
| 169748 | + if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){ |
| 169749 | + char *z = sqlite3_vmprintf(zFmt, ap); |
| 169750 | + if( z==0 ){ |
| 169751 | + pCheck->rc = SQLITE_NOMEM; |
| 169752 | + }else{ |
| 169753 | + pCheck->zReport = sqlite3_mprintf("%z%s%z", |
| 169754 | + pCheck->zReport, (pCheck->zReport ? "\n" : ""), z |
| 169755 | + ); |
| 169756 | + if( pCheck->zReport==0 ){ |
| 169757 | + pCheck->rc = SQLITE_NOMEM; |
| 169758 | + } |
| 169759 | + } |
| 169760 | + pCheck->nErr++; |
| 169761 | + } |
| 169762 | + va_end(ap); |
| 169763 | +} |
| 169764 | + |
| 169765 | +/* |
| 169766 | +** This function is a no-op if there is already an error code stored |
| 169767 | +** in the RtreeCheck object indicated by the first argument. NULL is |
| 169768 | +** returned in this case. |
| 169769 | +** |
| 169770 | +** Otherwise, the contents of rtree table node iNode are loaded from |
| 169771 | +** the database and copied into a buffer obtained from sqlite3_malloc(). |
| 169772 | +** If no error occurs, a pointer to the buffer is returned and (*pnNode) |
| 169773 | +** is set to the size of the buffer in bytes. |
| 169774 | +** |
| 169775 | +** Or, if an error does occur, NULL is returned and an error code left |
| 169776 | +** in the RtreeCheck object. The final value of *pnNode is undefined in |
| 169777 | +** this case. |
| 169778 | +*/ |
| 169779 | +static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ |
| 169780 | + u8 *pRet = 0; /* Return value */ |
| 169781 | + |
| 169782 | + assert( pCheck->rc==SQLITE_OK ); |
| 169783 | + if( pCheck->pGetNode==0 ){ |
| 169784 | + pCheck->pGetNode = rtreeCheckPrepare(pCheck, |
| 169785 | + "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", |
| 169786 | + pCheck->zDb, pCheck->zTab |
| 169787 | + ); |
| 169788 | + } |
| 169789 | + |
| 169790 | + if( pCheck->rc==SQLITE_OK ){ |
| 169791 | + sqlite3_bind_int64(pCheck->pGetNode, 1, iNode); |
| 169792 | + if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ |
| 169793 | + int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); |
| 169794 | + const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); |
| 169795 | + pRet = sqlite3_malloc(nNode); |
| 169796 | + if( pRet==0 ){ |
| 169797 | + pCheck->rc = SQLITE_NOMEM; |
| 169798 | + }else{ |
| 169799 | + memcpy(pRet, pNode, nNode); |
| 169800 | + *pnNode = nNode; |
| 169801 | + } |
| 169802 | + } |
| 169803 | + rtreeCheckReset(pCheck, pCheck->pGetNode); |
| 169804 | + if( pCheck->rc==SQLITE_OK && pRet==0 ){ |
| 169805 | + rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode); |
| 169806 | + } |
| 169807 | + } |
| 169808 | + |
| 169809 | + return pRet; |
| 169810 | +} |
| 169811 | + |
| 169812 | +/* |
| 169813 | +** This function is used to check that the %_parent (if bLeaf==0) or %_rowid |
| 169814 | +** (if bLeaf==1) table contains a specified entry. The schemas of the |
| 169815 | +** two tables are: |
| 169816 | +** |
| 169817 | +** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) |
| 169818 | +** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER) |
| 169819 | +** |
| 169820 | +** In both cases, this function checks that there exists an entry with |
| 169821 | +** IPK value iKey and the second column set to iVal. |
| 169822 | +** |
| 169823 | +*/ |
| 169824 | +static void rtreeCheckMapping( |
| 169825 | + RtreeCheck *pCheck, /* RtreeCheck object */ |
| 169826 | + int bLeaf, /* True for a leaf cell, false for interior */ |
| 169827 | + i64 iKey, /* Key for mapping */ |
| 169828 | + i64 iVal /* Expected value for mapping */ |
| 169829 | +){ |
| 169830 | + int rc; |
| 169831 | + sqlite3_stmt *pStmt; |
| 169832 | + const char *azSql[2] = { |
| 169833 | + "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?", |
| 169834 | + "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?" |
| 169835 | + }; |
| 169836 | + |
| 169837 | + assert( bLeaf==0 || bLeaf==1 ); |
| 169838 | + if( pCheck->aCheckMapping[bLeaf]==0 ){ |
| 169839 | + pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck, |
| 169840 | + azSql[bLeaf], pCheck->zDb, pCheck->zTab |
| 169841 | + ); |
| 169842 | + } |
| 169843 | + if( pCheck->rc!=SQLITE_OK ) return; |
| 169844 | + |
| 169845 | + pStmt = pCheck->aCheckMapping[bLeaf]; |
| 169846 | + sqlite3_bind_int64(pStmt, 1, iKey); |
| 169847 | + rc = sqlite3_step(pStmt); |
| 169848 | + if( rc==SQLITE_DONE ){ |
| 169849 | + rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table", |
| 169850 | + iKey, iVal, (bLeaf ? "%_rowid" : "%_parent") |
| 169851 | + ); |
| 169852 | + }else if( rc==SQLITE_ROW ){ |
| 169853 | + i64 ii = sqlite3_column_int64(pStmt, 0); |
| 169854 | + if( ii!=iVal ){ |
| 169855 | + rtreeCheckAppendMsg(pCheck, |
| 169856 | + "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)", |
| 169857 | + iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal |
| 169858 | + ); |
| 169859 | + } |
| 169860 | + } |
| 169861 | + rtreeCheckReset(pCheck, pStmt); |
| 169862 | +} |
| 169863 | + |
| 169864 | +/* |
| 169865 | +** Argument pCell points to an array of coordinates stored on an rtree page. |
| 169866 | +** This function checks that the coordinates are internally consistent (no |
| 169867 | +** x1>x2 conditions) and adds an error message to the RtreeCheck object |
| 169868 | +** if they are not. |
| 169869 | +** |
| 169870 | +** Additionally, if pParent is not NULL, then it is assumed to point to |
| 169871 | +** the array of coordinates on the parent page that bound the page |
| 169872 | +** containing pCell. In this case it is also verified that the two |
| 169873 | +** sets of coordinates are mutually consistent and an error message added |
| 169874 | +** to the RtreeCheck object if they are not. |
| 169875 | +*/ |
| 169876 | +static void rtreeCheckCellCoord( |
| 169877 | + RtreeCheck *pCheck, |
| 169878 | + i64 iNode, /* Node id to use in error messages */ |
| 169879 | + int iCell, /* Cell number to use in error messages */ |
| 169880 | + u8 *pCell, /* Pointer to cell coordinates */ |
| 169881 | + u8 *pParent /* Pointer to parent coordinates */ |
| 169882 | +){ |
| 169883 | + RtreeCoord c1, c2; |
| 169884 | + RtreeCoord p1, p2; |
| 169885 | + int i; |
| 169886 | + |
| 169887 | + for(i=0; i<pCheck->nDim; i++){ |
| 169888 | + readCoord(&pCell[4*2*i], &c1); |
| 169889 | + readCoord(&pCell[4*(2*i + 1)], &c2); |
| 169890 | + |
| 169891 | + /* printf("%e, %e\n", c1.u.f, c2.u.f); */ |
| 169892 | + if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){ |
| 169893 | + rtreeCheckAppendMsg(pCheck, |
| 169894 | + "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode |
| 169895 | + ); |
| 169896 | + } |
| 169897 | + |
| 169898 | + if( pParent ){ |
| 169899 | + readCoord(&pParent[4*2*i], &p1); |
| 169900 | + readCoord(&pParent[4*(2*i + 1)], &p2); |
| 169901 | + |
| 169902 | + if( (pCheck->bInt ? c1.i<p1.i : c1.f<p1.f) |
| 169903 | + || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f) |
| 169904 | + ){ |
| 169905 | + rtreeCheckAppendMsg(pCheck, |
| 169906 | + "Dimension %d of cell %d on node %lld is corrupt relative to parent" |
| 169907 | + , i, iCell, iNode |
| 169908 | + ); |
| 169909 | + } |
| 169910 | + } |
| 169911 | + } |
| 169912 | +} |
| 169913 | + |
| 169914 | +/* |
| 169915 | +** Run rtreecheck() checks on node iNode, which is at depth iDepth within |
| 169916 | +** the r-tree structure. Argument aParent points to the array of coordinates |
| 169917 | +** that bound node iNode on the parent node. |
| 169918 | +** |
| 169919 | +** If any problems are discovered, an error message is appended to the |
| 169920 | +** report accumulated in the RtreeCheck object. |
| 169921 | +*/ |
| 169922 | +static void rtreeCheckNode( |
| 169923 | + RtreeCheck *pCheck, |
| 169924 | + int iDepth, /* Depth of iNode (0==leaf) */ |
| 169925 | + u8 *aParent, /* Buffer containing parent coords */ |
| 169926 | + i64 iNode /* Node to check */ |
| 169927 | +){ |
| 169928 | + u8 *aNode = 0; |
| 169929 | + int nNode = 0; |
| 169930 | + |
| 169931 | + assert( iNode==1 || aParent!=0 ); |
| 169932 | + assert( pCheck->nDim>0 ); |
| 169933 | + |
| 169934 | + aNode = rtreeCheckGetNode(pCheck, iNode, &nNode); |
| 169935 | + if( aNode ){ |
| 169936 | + if( nNode<4 ){ |
| 169937 | + rtreeCheckAppendMsg(pCheck, |
| 169938 | + "Node %lld is too small (%d bytes)", iNode, nNode |
| 169939 | + ); |
| 169940 | + }else{ |
| 169941 | + int nCell; /* Number of cells on page */ |
| 169942 | + int i; /* Used to iterate through cells */ |
| 169943 | + if( aParent==0 ){ |
| 169944 | + iDepth = readInt16(aNode); |
| 169945 | + if( iDepth>RTREE_MAX_DEPTH ){ |
| 169946 | + rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth); |
| 169947 | + sqlite3_free(aNode); |
| 169948 | + return; |
| 169949 | + } |
| 169950 | + } |
| 169951 | + nCell = readInt16(&aNode[2]); |
| 169952 | + if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){ |
| 169953 | + rtreeCheckAppendMsg(pCheck, |
| 169954 | + "Node %lld is too small for cell count of %d (%d bytes)", |
| 169955 | + iNode, nCell, nNode |
| 169956 | + ); |
| 169957 | + }else{ |
| 169958 | + for(i=0; i<nCell; i++){ |
| 169959 | + u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)]; |
| 169960 | + i64 iVal = readInt64(pCell); |
| 169961 | + rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent); |
| 169962 | + |
| 169963 | + if( iDepth>0 ){ |
| 169964 | + rtreeCheckMapping(pCheck, 0, iVal, iNode); |
| 169965 | + rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal); |
| 169966 | + pCheck->nNonLeaf++; |
| 169967 | + }else{ |
| 169968 | + rtreeCheckMapping(pCheck, 1, iVal, iNode); |
| 169969 | + pCheck->nLeaf++; |
| 169970 | + } |
| 169971 | + } |
| 169972 | + } |
| 169973 | + } |
| 169974 | + sqlite3_free(aNode); |
| 169975 | + } |
| 169976 | +} |
| 169977 | + |
| 169978 | +/* |
| 169979 | +** The second argument to this function must be either "_rowid" or |
| 169980 | +** "_parent". This function checks that the number of entries in the |
| 169981 | +** %_rowid or %_parent table is exactly nExpect. If not, it adds |
| 169982 | +** an error message to the report in the RtreeCheck object indicated |
| 169983 | +** by the first argument. |
| 169984 | +*/ |
| 169985 | +static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ |
| 169986 | + if( pCheck->rc==SQLITE_OK ){ |
| 169987 | + sqlite3_stmt *pCount; |
| 169988 | + pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'", |
| 169989 | + pCheck->zDb, pCheck->zTab, zTbl |
| 169990 | + ); |
| 169991 | + if( pCount ){ |
| 169992 | + if( sqlite3_step(pCount)==SQLITE_ROW ){ |
| 169993 | + i64 nActual = sqlite3_column_int64(pCount, 0); |
| 169994 | + if( nActual!=nExpect ){ |
| 169995 | + rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table" |
| 169996 | + " - expected %lld, actual %lld" , zTbl, nExpect, nActual |
| 169997 | + ); |
| 169998 | + } |
| 169999 | + } |
| 170000 | + pCheck->rc = sqlite3_finalize(pCount); |
| 170001 | + } |
| 170002 | + } |
| 170003 | +} |
| 170004 | + |
| 170005 | +/* |
| 170006 | +** This function does the bulk of the work for the rtree integrity-check. |
| 170007 | +** It is called by rtreecheck(), which is the SQL function implementation. |
| 170008 | +*/ |
| 170009 | +static int rtreeCheckTable( |
| 170010 | + sqlite3 *db, /* Database handle to access db through */ |
| 170011 | + const char *zDb, /* Name of db ("main", "temp" etc.) */ |
| 170012 | + const char *zTab, /* Name of rtree table to check */ |
| 170013 | + char **pzReport /* OUT: sqlite3_malloc'd report text */ |
| 170014 | +){ |
| 170015 | + RtreeCheck check; /* Common context for various routines */ |
| 170016 | + sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ |
| 170017 | + int bEnd = 0; /* True if transaction should be closed */ |
| 170018 | + |
| 170019 | + /* Initialize the context object */ |
| 170020 | + memset(&check, 0, sizeof(check)); |
| 170021 | + check.db = db; |
| 170022 | + check.zDb = zDb; |
| 170023 | + check.zTab = zTab; |
| 170024 | + |
| 170025 | + /* If there is not already an open transaction, open one now. This is |
| 170026 | + ** to ensure that the queries run as part of this integrity-check operate |
| 170027 | + ** on a consistent snapshot. */ |
| 170028 | + if( sqlite3_get_autocommit(db) ){ |
| 170029 | + check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); |
| 170030 | + bEnd = 1; |
| 170031 | + } |
| 170032 | + |
| 170033 | + /* Find number of dimensions in the rtree table. */ |
| 170034 | + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab); |
| 170035 | + if( pStmt ){ |
| 170036 | + int rc; |
| 170037 | + check.nDim = (sqlite3_column_count(pStmt) - 1) / 2; |
| 170038 | + if( check.nDim<1 ){ |
| 170039 | + rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree"); |
| 170040 | + }else if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 170041 | + check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); |
| 170042 | + } |
| 170043 | + rc = sqlite3_finalize(pStmt); |
| 170044 | + if( rc!=SQLITE_CORRUPT ) check.rc = rc; |
| 170045 | + } |
| 170046 | + |
| 170047 | + /* Do the actual integrity-check */ |
| 170048 | + if( check.nDim>=1 ){ |
| 170049 | + if( check.rc==SQLITE_OK ){ |
| 170050 | + rtreeCheckNode(&check, 0, 0, 1); |
| 170051 | + } |
| 170052 | + rtreeCheckCount(&check, "_rowid", check.nLeaf); |
| 170053 | + rtreeCheckCount(&check, "_parent", check.nNonLeaf); |
| 170054 | + } |
| 170055 | + |
| 170056 | + /* Finalize SQL statements used by the integrity-check */ |
| 170057 | + sqlite3_finalize(check.pGetNode); |
| 170058 | + sqlite3_finalize(check.aCheckMapping[0]); |
| 170059 | + sqlite3_finalize(check.aCheckMapping[1]); |
| 170060 | + |
| 170061 | + /* If one was opened, close the transaction */ |
| 170062 | + if( bEnd ){ |
| 170063 | + int rc = sqlite3_exec(db, "END", 0, 0, 0); |
| 170064 | + if( check.rc==SQLITE_OK ) check.rc = rc; |
| 170065 | + } |
| 170066 | + *pzReport = check.zReport; |
| 170067 | + return check.rc; |
| 170068 | +} |
| 170069 | + |
| 170070 | +/* |
| 170071 | +** Usage: |
| 170072 | +** |
| 170073 | +** rtreecheck(<rtree-table>); |
| 170074 | +** rtreecheck(<database>, <rtree-table>); |
| 170075 | +** |
| 170076 | +** Invoking this SQL function runs an integrity-check on the named rtree |
| 170077 | +** table. The integrity-check verifies the following: |
| 170078 | +** |
| 170079 | +** 1. For each cell in the r-tree structure (%_node table), that: |
| 170080 | +** |
| 170081 | +** a) for each dimension, (coord1 <= coord2). |
| 170082 | +** |
| 170083 | +** b) unless the cell is on the root node, that the cell is bounded |
| 170084 | +** by the parent cell on the parent node. |
| 170085 | +** |
| 170086 | +** c) for leaf nodes, that there is an entry in the %_rowid |
| 170087 | +** table corresponding to the cell's rowid value that |
| 170088 | +** points to the correct node. |
| 170089 | +** |
| 170090 | +** d) for cells on non-leaf nodes, that there is an entry in the |
| 170091 | +** %_parent table mapping from the cell's child node to the |
| 170092 | +** node that it resides on. |
| 170093 | +** |
| 170094 | +** 2. That there are the same number of entries in the %_rowid table |
| 170095 | +** as there are leaf cells in the r-tree structure, and that there |
| 170096 | +** is a leaf cell that corresponds to each entry in the %_rowid table. |
| 170097 | +** |
| 170098 | +** 3. That there are the same number of entries in the %_parent table |
| 170099 | +** as there are non-leaf cells in the r-tree structure, and that |
| 170100 | +** there is a non-leaf cell that corresponds to each entry in the |
| 170101 | +** %_parent table. |
| 170102 | +*/ |
| 170103 | +static void rtreecheck( |
| 170104 | + sqlite3_context *ctx, |
| 170105 | + int nArg, |
| 170106 | + sqlite3_value **apArg |
| 170107 | +){ |
| 170108 | + if( nArg!=1 && nArg!=2 ){ |
| 170109 | + sqlite3_result_error(ctx, |
| 170110 | + "wrong number of arguments to function rtreecheck()", -1 |
| 170111 | + ); |
| 170112 | + }else{ |
| 170113 | + int rc; |
| 170114 | + char *zReport = 0; |
| 170115 | + const char *zDb = (const char*)sqlite3_value_text(apArg[0]); |
| 170116 | + const char *zTab; |
| 170117 | + if( nArg==1 ){ |
| 170118 | + zTab = zDb; |
| 170119 | + zDb = "main"; |
| 170120 | + }else{ |
| 170121 | + zTab = (const char*)sqlite3_value_text(apArg[1]); |
| 170122 | + } |
| 170123 | + rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport); |
| 170124 | + if( rc==SQLITE_OK ){ |
| 170125 | + sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); |
| 170126 | + }else{ |
| 170127 | + sqlite3_result_error_code(ctx, rc); |
| 170128 | + } |
| 170129 | + sqlite3_free(zReport); |
| 170130 | + } |
| 170131 | +} |
| 170132 | + |
| 169242 | 170133 | |
| 169243 | 170134 | /* |
| 169244 | 170135 | ** Register the r-tree module with database handle db. This creates the |
| 169245 | 170136 | ** virtual table module "rtree" and the debugging/analysis scalar |
| 169246 | 170137 | ** function "rtreenode". |
| | @@ -169251,10 +170142,13 @@ |
| 169251 | 170142 | |
| 169252 | 170143 | rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); |
| 169253 | 170144 | if( rc==SQLITE_OK ){ |
| 169254 | 170145 | rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); |
| 169255 | 170146 | } |
| 170147 | + if( rc==SQLITE_OK ){ |
| 170148 | + rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0); |
| 170149 | + } |
| 169256 | 170150 | if( rc==SQLITE_OK ){ |
| 169257 | 170151 | #ifdef SQLITE_RTREE_INT_ONLY |
| 169258 | 170152 | void *c = (void *)RTREE_COORD_INT32; |
| 169259 | 170153 | #else |
| 169260 | 170154 | void *c = (void *)RTREE_COORD_REAL32; |
| | @@ -176455,20 +177349,27 @@ |
| 176455 | 177349 | |
| 176456 | 177350 | struct DbpageCursor { |
| 176457 | 177351 | sqlite3_vtab_cursor base; /* Base class. Must be first */ |
| 176458 | 177352 | int pgno; /* Current page number */ |
| 176459 | 177353 | int mxPgno; /* Last page to visit on this scan */ |
| 177354 | + Pager *pPager; /* Pager being read/written */ |
| 177355 | + DbPage *pPage1; /* Page 1 of the database */ |
| 177356 | + int iDb; /* Index of database to analyze */ |
| 177357 | + int szPage; /* Size of each page in bytes */ |
| 176460 | 177358 | }; |
| 176461 | 177359 | |
| 176462 | 177360 | struct DbpageTable { |
| 176463 | 177361 | sqlite3_vtab base; /* Base class. Must be first */ |
| 176464 | 177362 | sqlite3 *db; /* The database */ |
| 176465 | | - Pager *pPager; /* Pager being read/written */ |
| 176466 | | - int iDb; /* Index of database to analyze */ |
| 176467 | | - int szPage; /* Size of each page in bytes */ |
| 176468 | | - int nPage; /* Number of pages in the file */ |
| 176469 | 177363 | }; |
| 177364 | + |
| 177365 | +/* Columns */ |
| 177366 | +#define DBPAGE_COLUMN_PGNO 0 |
| 177367 | +#define DBPAGE_COLUMN_DATA 1 |
| 177368 | +#define DBPAGE_COLUMN_SCHEMA 2 |
| 177369 | + |
| 177370 | + |
| 176470 | 177371 | |
| 176471 | 177372 | /* |
| 176472 | 177373 | ** Connect to or create a dbpagevfs virtual table. |
| 176473 | 177374 | */ |
| 176474 | 177375 | static int dbpageConnect( |
| | @@ -176478,37 +177379,22 @@ |
| 176478 | 177379 | sqlite3_vtab **ppVtab, |
| 176479 | 177380 | char **pzErr |
| 176480 | 177381 | ){ |
| 176481 | 177382 | DbpageTable *pTab = 0; |
| 176482 | 177383 | int rc = SQLITE_OK; |
| 176483 | | - int iDb; |
| 176484 | | - |
| 176485 | | - if( argc>=4 ){ |
| 176486 | | - Token nm; |
| 176487 | | - sqlite3TokenInit(&nm, (char*)argv[3]); |
| 176488 | | - iDb = sqlite3FindDb(db, &nm); |
| 176489 | | - if( iDb<0 ){ |
| 176490 | | - *pzErr = sqlite3_mprintf("no such schema: %s", argv[3]); |
| 176491 | | - return SQLITE_ERROR; |
| 176492 | | - } |
| 176493 | | - }else{ |
| 176494 | | - iDb = 0; |
| 176495 | | - } |
| 177384 | + |
| 176496 | 177385 | rc = sqlite3_declare_vtab(db, |
| 176497 | 177386 | "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); |
| 176498 | 177387 | if( rc==SQLITE_OK ){ |
| 176499 | 177388 | pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable)); |
| 176500 | 177389 | if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; |
| 176501 | 177390 | } |
| 176502 | 177391 | |
| 176503 | 177392 | assert( rc==SQLITE_OK || pTab==0 ); |
| 176504 | 177393 | if( rc==SQLITE_OK ){ |
| 176505 | | - Btree *pBt = db->aDb[iDb].pBt; |
| 176506 | 177394 | memset(pTab, 0, sizeof(DbpageTable)); |
| 176507 | 177395 | pTab->db = db; |
| 176508 | | - pTab->iDb = iDb; |
| 176509 | | - pTab->pPager = pBt ? sqlite3BtreePager(pBt) : 0; |
| 176510 | 177396 | } |
| 176511 | 177397 | |
| 176512 | 177398 | *ppVtab = (sqlite3_vtab*)pTab; |
| 176513 | 177399 | return rc; |
| 176514 | 177400 | } |
| | @@ -176522,28 +177408,59 @@ |
| 176522 | 177408 | } |
| 176523 | 177409 | |
| 176524 | 177410 | /* |
| 176525 | 177411 | ** idxNum: |
| 176526 | 177412 | ** |
| 176527 | | -** 0 full table scan |
| 176528 | | -** 1 pgno=?1 |
| 177413 | +** 0 schema=main, full table scan |
| 177414 | +** 1 schema=main, pgno=?1 |
| 177415 | +** 2 schema=?1, full table scan |
| 177416 | +** 3 schema=?1, pgno=?2 |
| 176529 | 177417 | */ |
| 176530 | 177418 | static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
| 176531 | 177419 | int i; |
| 176532 | | - pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */ |
| 177420 | + int iPlan = 0; |
| 177421 | + |
| 177422 | + /* If there is a schema= constraint, it must be honored. Report a |
| 177423 | + ** ridiculously large estimated cost if the schema= constraint is |
| 177424 | + ** unavailable |
| 177425 | + */ |
| 177426 | + for(i=0; i<pIdxInfo->nConstraint; i++){ |
| 177427 | + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; |
| 177428 | + if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue; |
| 177429 | + if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
| 177430 | + if( !p->usable ){ |
| 177431 | + /* No solution. Use the default SQLITE_BIG_DBL cost */ |
| 177432 | + pIdxInfo->estimatedRows = 0x7fffffff; |
| 177433 | + return SQLITE_OK; |
| 177434 | + } |
| 177435 | + iPlan = 2; |
| 177436 | + pIdxInfo->aConstraintUsage[i].argvIndex = 1; |
| 177437 | + pIdxInfo->aConstraintUsage[i].omit = 1; |
| 177438 | + break; |
| 177439 | + } |
| 177440 | + |
| 177441 | + /* If we reach this point, it means that either there is no schema= |
| 177442 | + ** constraint (in which case we use the "main" schema) or else the |
| 177443 | + ** schema constraint was accepted. Lower the estimated cost accordingly |
| 177444 | + */ |
| 177445 | + pIdxInfo->estimatedCost = 1.0e6; |
| 177446 | + |
| 177447 | + /* Check for constraints against pgno */ |
| 176533 | 177448 | for(i=0; i<pIdxInfo->nConstraint; i++){ |
| 176534 | 177449 | struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; |
| 176535 | 177450 | if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
| 176536 | 177451 | pIdxInfo->estimatedRows = 1; |
| 176537 | 177452 | pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; |
| 176538 | 177453 | pIdxInfo->estimatedCost = 1.0; |
| 176539 | | - pIdxInfo->idxNum = 1; |
| 176540 | | - pIdxInfo->aConstraintUsage[i].argvIndex = 1; |
| 177454 | + pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1; |
| 176541 | 177455 | pIdxInfo->aConstraintUsage[i].omit = 1; |
| 177456 | + iPlan |= 1; |
| 176542 | 177457 | break; |
| 176543 | 177458 | } |
| 176544 | 177459 | } |
| 177460 | + pIdxInfo->idxNum = iPlan; |
| 177461 | + |
| 176545 | 177462 | if( pIdxInfo->nOrderBy>=1 |
| 176546 | 177463 | && pIdxInfo->aOrderBy[0].iColumn<=0 |
| 176547 | 177464 | && pIdxInfo->aOrderBy[0].desc==0 |
| 176548 | 177465 | ){ |
| 176549 | 177466 | pIdxInfo->orderByConsumed = 1; |
| | @@ -176573,10 +177490,11 @@ |
| 176573 | 177490 | /* |
| 176574 | 177491 | ** Close a dbpagevfs cursor. |
| 176575 | 177492 | */ |
| 176576 | 177493 | static int dbpageClose(sqlite3_vtab_cursor *pCursor){ |
| 176577 | 177494 | DbpageCursor *pCsr = (DbpageCursor *)pCursor; |
| 177495 | + if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); |
| 176578 | 177496 | sqlite3_free(pCsr); |
| 176579 | 177497 | return SQLITE_OK; |
| 176580 | 177498 | } |
| 176581 | 177499 | |
| 176582 | 177500 | /* |
| | @@ -176592,63 +177510,91 @@ |
| 176592 | 177510 | static int dbpageEof(sqlite3_vtab_cursor *pCursor){ |
| 176593 | 177511 | DbpageCursor *pCsr = (DbpageCursor *)pCursor; |
| 176594 | 177512 | return pCsr->pgno > pCsr->mxPgno; |
| 176595 | 177513 | } |
| 176596 | 177514 | |
| 177515 | +/* |
| 177516 | +** idxNum: |
| 177517 | +** |
| 177518 | +** 0 schema=main, full table scan |
| 177519 | +** 1 schema=main, pgno=?1 |
| 177520 | +** 2 schema=?1, full table scan |
| 177521 | +** 3 schema=?1, pgno=?2 |
| 177522 | +** |
| 177523 | +** idxStr is not used |
| 177524 | +*/ |
| 176597 | 177525 | static int dbpageFilter( |
| 176598 | 177526 | sqlite3_vtab_cursor *pCursor, |
| 176599 | 177527 | int idxNum, const char *idxStr, |
| 176600 | 177528 | int argc, sqlite3_value **argv |
| 176601 | 177529 | ){ |
| 176602 | 177530 | DbpageCursor *pCsr = (DbpageCursor *)pCursor; |
| 176603 | 177531 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 176604 | | - int rc = SQLITE_OK; |
| 176605 | | - Btree *pBt = pTab->db->aDb[pTab->iDb].pBt; |
| 176606 | | - |
| 176607 | | - pTab->szPage = sqlite3BtreeGetPageSize(pBt); |
| 176608 | | - pTab->nPage = sqlite3BtreeLastPage(pBt); |
| 176609 | | - if( idxNum==1 ){ |
| 176610 | | - pCsr->pgno = sqlite3_value_int(argv[0]); |
| 176611 | | - if( pCsr->pgno<1 || pCsr->pgno>pTab->nPage ){ |
| 177532 | + int rc; |
| 177533 | + sqlite3 *db = pTab->db; |
| 177534 | + Btree *pBt; |
| 177535 | + |
| 177536 | + /* Default setting is no rows of result */ |
| 177537 | + pCsr->pgno = 1; |
| 177538 | + pCsr->mxPgno = 0; |
| 177539 | + |
| 177540 | + if( idxNum & 2 ){ |
| 177541 | + const char *zSchema; |
| 177542 | + assert( argc>=1 ); |
| 177543 | + zSchema = (const char*)sqlite3_value_text(argv[0]); |
| 177544 | + pCsr->iDb = sqlite3FindDbName(db, zSchema); |
| 177545 | + if( pCsr->iDb<0 ) return SQLITE_OK; |
| 177546 | + }else{ |
| 177547 | + pCsr->iDb = 0; |
| 177548 | + } |
| 177549 | + pBt = db->aDb[pCsr->iDb].pBt; |
| 177550 | + if( pBt==0 ) return SQLITE_OK; |
| 177551 | + pCsr->pPager = sqlite3BtreePager(pBt); |
| 177552 | + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); |
| 177553 | + pCsr->mxPgno = sqlite3BtreeLastPage(pBt); |
| 177554 | + if( idxNum & 1 ){ |
| 177555 | + assert( argc>(idxNum>>1) ); |
| 177556 | + pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); |
| 177557 | + if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ |
| 176612 | 177558 | pCsr->pgno = 1; |
| 176613 | 177559 | pCsr->mxPgno = 0; |
| 176614 | 177560 | }else{ |
| 176615 | 177561 | pCsr->mxPgno = pCsr->pgno; |
| 176616 | 177562 | } |
| 176617 | 177563 | }else{ |
| 176618 | | - pCsr->pgno = 1; |
| 176619 | | - pCsr->mxPgno = pTab->nPage; |
| 177564 | + assert( pCsr->pgno==1 ); |
| 176620 | 177565 | } |
| 177566 | + if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); |
| 177567 | + rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0); |
| 176621 | 177568 | return rc; |
| 176622 | 177569 | } |
| 176623 | 177570 | |
| 176624 | 177571 | static int dbpageColumn( |
| 176625 | 177572 | sqlite3_vtab_cursor *pCursor, |
| 176626 | 177573 | sqlite3_context *ctx, |
| 176627 | 177574 | int i |
| 176628 | 177575 | ){ |
| 176629 | 177576 | DbpageCursor *pCsr = (DbpageCursor *)pCursor; |
| 176630 | | - DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 176631 | 177577 | int rc = SQLITE_OK; |
| 176632 | 177578 | switch( i ){ |
| 176633 | 177579 | case 0: { /* pgno */ |
| 176634 | 177580 | sqlite3_result_int(ctx, pCsr->pgno); |
| 176635 | 177581 | break; |
| 176636 | 177582 | } |
| 176637 | 177583 | case 1: { /* data */ |
| 176638 | 177584 | DbPage *pDbPage = 0; |
| 176639 | | - rc = sqlite3PagerGet(pTab->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); |
| 177585 | + rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); |
| 176640 | 177586 | if( rc==SQLITE_OK ){ |
| 176641 | | - sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pTab->szPage, |
| 177587 | + sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, |
| 176642 | 177588 | SQLITE_TRANSIENT); |
| 176643 | 177589 | } |
| 176644 | 177590 | sqlite3PagerUnref(pDbPage); |
| 176645 | 177591 | break; |
| 176646 | 177592 | } |
| 176647 | 177593 | default: { /* schema */ |
| 176648 | 177594 | sqlite3 *db = sqlite3_context_db_handle(ctx); |
| 176649 | | - sqlite3_result_text(ctx, db->aDb[pTab->iDb].zDbSName, -1, SQLITE_STATIC); |
| 177595 | + sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); |
| 176650 | 177596 | break; |
| 176651 | 177597 | } |
| 176652 | 177598 | } |
| 176653 | 177599 | return SQLITE_OK; |
| 176654 | 177600 | } |
| | @@ -176664,41 +177610,55 @@ |
| 176664 | 177610 | int argc, |
| 176665 | 177611 | sqlite3_value **argv, |
| 176666 | 177612 | sqlite_int64 *pRowid |
| 176667 | 177613 | ){ |
| 176668 | 177614 | DbpageTable *pTab = (DbpageTable *)pVtab; |
| 176669 | | - int pgno; |
| 177615 | + Pgno pgno; |
| 176670 | 177616 | DbPage *pDbPage = 0; |
| 176671 | 177617 | int rc = SQLITE_OK; |
| 176672 | 177618 | char *zErr = 0; |
| 177619 | + const char *zSchema; |
| 177620 | + int iDb; |
| 177621 | + Btree *pBt; |
| 177622 | + Pager *pPager; |
| 177623 | + int szPage; |
| 176673 | 177624 | |
| 176674 | 177625 | if( argc==1 ){ |
| 176675 | 177626 | zErr = "cannot delete"; |
| 176676 | 177627 | goto update_fail; |
| 176677 | 177628 | } |
| 176678 | 177629 | pgno = sqlite3_value_int(argv[0]); |
| 176679 | | - if( pgno<1 || pgno>pTab->nPage ){ |
| 176680 | | - zErr = "bad page number"; |
| 176681 | | - goto update_fail; |
| 176682 | | - } |
| 176683 | | - if( sqlite3_value_int(argv[1])!=pgno ){ |
| 177630 | + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ |
| 176684 | 177631 | zErr = "cannot insert"; |
| 176685 | 177632 | goto update_fail; |
| 176686 | 177633 | } |
| 177634 | + zSchema = (const char*)sqlite3_value_text(argv[4]); |
| 177635 | + iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; |
| 177636 | + if( iDb<0 ){ |
| 177637 | + zErr = "no such schema"; |
| 177638 | + goto update_fail; |
| 177639 | + } |
| 177640 | + pBt = pTab->db->aDb[iDb].pBt; |
| 177641 | + if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){ |
| 177642 | + zErr = "bad page number"; |
| 177643 | + goto update_fail; |
| 177644 | + } |
| 177645 | + szPage = sqlite3BtreeGetPageSize(pBt); |
| 176687 | 177646 | if( sqlite3_value_type(argv[3])!=SQLITE_BLOB |
| 176688 | | - || sqlite3_value_bytes(argv[3])!=pTab->szPage |
| 177647 | + || sqlite3_value_bytes(argv[3])!=szPage |
| 176689 | 177648 | ){ |
| 176690 | 177649 | zErr = "bad page value"; |
| 176691 | 177650 | goto update_fail; |
| 176692 | 177651 | } |
| 176693 | | - rc = sqlite3PagerGet(pTab->pPager, pgno, (DbPage**)&pDbPage, 0); |
| 177652 | + pPager = sqlite3BtreePager(pBt); |
| 177653 | + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); |
| 176694 | 177654 | if( rc==SQLITE_OK ){ |
| 176695 | 177655 | rc = sqlite3PagerWrite(pDbPage); |
| 176696 | 177656 | if( rc==SQLITE_OK ){ |
| 176697 | 177657 | memcpy(sqlite3PagerGetData(pDbPage), |
| 176698 | 177658 | sqlite3_value_blob(argv[3]), |
| 176699 | | - pTab->szPage); |
| 177659 | + szPage); |
| 176700 | 177660 | } |
| 176701 | 177661 | } |
| 176702 | 177662 | sqlite3PagerUnref(pDbPage); |
| 176703 | 177663 | return rc; |
| 176704 | 177664 | |
| | @@ -176705,10 +177665,26 @@ |
| 176705 | 177665 | update_fail: |
| 176706 | 177666 | sqlite3_free(pVtab->zErrMsg); |
| 176707 | 177667 | pVtab->zErrMsg = sqlite3_mprintf("%s", zErr); |
| 176708 | 177668 | return SQLITE_ERROR; |
| 176709 | 177669 | } |
| 177670 | + |
| 177671 | +/* Since we do not know in advance which database files will be |
| 177672 | +** written by the sqlite_dbpage virtual table, start a write transaction |
| 177673 | +** on them all. |
| 177674 | +*/ |
| 177675 | +static int dbpageBegin(sqlite3_vtab *pVtab){ |
| 177676 | + DbpageTable *pTab = (DbpageTable *)pVtab; |
| 177677 | + sqlite3 *db = pTab->db; |
| 177678 | + int i; |
| 177679 | + for(i=0; i<db->nDb; i++){ |
| 177680 | + Btree *pBt = db->aDb[i].pBt; |
| 177681 | + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1); |
| 177682 | + } |
| 177683 | + return SQLITE_OK; |
| 177684 | +} |
| 177685 | + |
| 176710 | 177686 | |
| 176711 | 177687 | /* |
| 176712 | 177688 | ** Invoke this routine to register the "dbpage" virtual table module |
| 176713 | 177689 | */ |
| 176714 | 177690 | SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ |
| | @@ -176725,11 +177701,11 @@ |
| 176725 | 177701 | dbpageNext, /* xNext - advance a cursor */ |
| 176726 | 177702 | dbpageEof, /* xEof - check for end of scan */ |
| 176727 | 177703 | dbpageColumn, /* xColumn - read data */ |
| 176728 | 177704 | dbpageRowid, /* xRowid - read data */ |
| 176729 | 177705 | dbpageUpdate, /* xUpdate */ |
| 176730 | | - 0, /* xBegin */ |
| 177706 | + dbpageBegin, /* xBegin */ |
| 176731 | 177707 | 0, /* xSync */ |
| 176732 | 177708 | 0, /* xCommit */ |
| 176733 | 177709 | 0, /* xRollback */ |
| 176734 | 177710 | 0, /* xFindMethod */ |
| 176735 | 177711 | 0, /* xRename */ |
| | @@ -201073,11 +202049,11 @@ |
| 201073 | 202049 | int nArg, /* Number of args */ |
| 201074 | 202050 | sqlite3_value **apUnused /* Function arguments */ |
| 201075 | 202051 | ){ |
| 201076 | 202052 | assert( nArg==0 ); |
| 201077 | 202053 | UNUSED_PARAM2(nArg, apUnused); |
| 201078 | | - sqlite3_result_text(pCtx, "fts5: 2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de48827", -1, SQLITE_TRANSIENT); |
| 202054 | + sqlite3_result_text(pCtx, "fts5: 2017-11-14 19:34:22 00ec95fcd02bb415dabd7f25fee24856d45d6916c18b2728e97e9bb9b8322ba3", -1, SQLITE_TRANSIENT); |
| 201079 | 202055 | } |
| 201080 | 202056 | |
| 201081 | 202057 | static int fts5Init(sqlite3 *db){ |
| 201082 | 202058 | static const sqlite3_module fts5Mod = { |
| 201083 | 202059 | /* iVersion */ 2, |
| | @@ -205341,12 +206317,12 @@ |
| 205341 | 206317 | } |
| 205342 | 206318 | #endif /* SQLITE_CORE */ |
| 205343 | 206319 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ |
| 205344 | 206320 | |
| 205345 | 206321 | /************** End of stmt.c ************************************************/ |
| 205346 | | -#if __LINE__!=205346 |
| 206322 | +#if __LINE__!=206322 |
| 205347 | 206323 | #undef SQLITE_SOURCE_ID |
| 205348 | | -#define SQLITE_SOURCE_ID "2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de4alt2" |
| 206324 | +#define SQLITE_SOURCE_ID "2017-11-14 19:34:22 00ec95fcd02bb415dabd7f25fee24856d45d6916c18b2728e97e9bb9b832alt2" |
| 205349 | 206325 | #endif |
| 205350 | 206326 | /* Return the source-id for this library */ |
| 205351 | 206327 | SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } |
| 205352 | 206328 | /************************** End of sqlite3.c ******************************/ |
| 205353 | 206329 | |