Merge enhancements and fixes from trunk.
FossilOrigin-Name: e005f2d6dd9faf38cc8fdb9428b5aa6192a6adae
This commit is contained in:
commit
e6c7b09df6
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\sproblem\sin\sthe\scode\sadded\sby\s[707ea170b3]\scausing\svdbesort.c\sto\ssort\sunstably.
|
||||
D 2014-03-25T17:07:48.821
|
||||
C Merge\senhancements\sand\sfixes\sfrom\strunk.
|
||||
D 2014-03-25T18:29:12.015
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -164,7 +164,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 029cec7b98fe0a985922c03f101630391044c4ad
|
||||
F src/btree.c 8d7e432bdd27d63182865c708ea0e7606489b6d1
|
||||
F src/btree.h 232836cb51753f2e96aa8ce0f052c6df850f76ba
|
||||
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
|
||||
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
|
||||
@ -203,7 +203,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
|
||||
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5
|
||||
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
|
||||
F src/os_win.c e71678ac927d0a0fb11d993db20a9748eabf808e
|
||||
F src/pager.c 97a8908bf4e6e7c3adea09d3597cfa48ae33ab4e
|
||||
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
|
||||
@ -222,7 +222,7 @@ F src/shell.c cee9f46f2688a261601b1fd3d7f4b3cddf9b5cdf
|
||||
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
|
||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h 1e16bac177ce6396e59af867afb90c92949895de
|
||||
F src/sqliteInt.h afbf39e96736ceb85e1d896b281ba2406dd70aa0
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@ -266,7 +266,7 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
||||
F src/test_stat.c 9898687a6c2beca733b0dd6fe19163d987826d31
|
||||
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
|
||||
F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
|
||||
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
|
||||
F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
|
||||
@ -278,11 +278,11 @@ F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115
|
||||
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
|
||||
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
|
||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||
F src/vdbe.c 42177064bd02fc55984aabc3a241368fda01e8b4
|
||||
F src/vdbe.c 02f2de0b2f3b198438e3e64a2ceba9407bb8348b
|
||||
F src/vdbe.h fb2c48c198300a7c632f09fc940011d2ad2fc2ae
|
||||
F src/vdbeInt.h 2b9a6849166d0014c843ae3fd83a062be4efa325
|
||||
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
|
||||
F src/vdbeaux.c 5078ca7de4fd5ba4535bd17fe44d5b56c2d3294c
|
||||
F src/vdbeaux.c 68dbdc77cdc008eeabc088b8b8a60aa743ba8d2a
|
||||
F src/vdbeblob.c 15377abfb59251bccedd5a9c7d014a895f0c04aa
|
||||
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
|
||||
F src/vdbesort.c 691f2186ae0943cd746ea7f5498cc9abebb7a7cc
|
||||
@ -825,7 +825,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c 1603da7b4897716f9df15bd71b0310f56ec3181e
|
||||
F test/speedtest1.c 2bec93920c6d26adfa781b509b1c9ca0a4d8f39d
|
||||
F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe
|
||||
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
||||
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
|
||||
@ -836,7 +836,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test a653783d985108c4912cc64d341ffbbb55ad2806
|
||||
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
|
||||
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
|
||||
F test/table.test 580d23530187026d4502fae74a490f0408cf2cc7
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
@ -892,6 +892,7 @@ F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
|
||||
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
|
||||
F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395
|
||||
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
|
||||
F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
|
||||
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
|
||||
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
|
||||
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
|
||||
@ -1055,6 +1056,7 @@ F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
|
||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||
F test/wal64k.test 63828c2161ad76ddd4109dee0a096b6ef6895698
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
|
||||
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
||||
@ -1157,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||
P c3ae3697832a00d4d5758988a8766bdbb691e6b8
|
||||
R eb749164f2115a0b3ef6dbb32fd74b6a
|
||||
U dan
|
||||
Z ecf1eb93a5e3757595a49ddb23f9c671
|
||||
P d3e640afe611b6ae0b7f2cff5b00900d7e4d5ee3 9ab7ffd59209aef0ffbf384b3902a93fd3b86a6d
|
||||
R 335a8527f823954338585adf78102470
|
||||
U drh
|
||||
Z 4f8dfdcfe6d8ef52977c5b1537285eeb
|
||||
|
@ -1 +1 @@
|
||||
d3e640afe611b6ae0b7f2cff5b00900d7e4d5ee3
|
||||
e005f2d6dd9faf38cc8fdb9428b5aa6192a6adae
|
23
src/btree.c
23
src/btree.c
@ -746,20 +746,32 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
|
||||
** at is deleted out from under them.
|
||||
**
|
||||
** This routine returns an error code if something goes wrong. The
|
||||
** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
|
||||
** integer *pHasMoved is set as follows:
|
||||
**
|
||||
** 0: The cursor is unchanged
|
||||
** 1: The cursor is still pointing at the same row, but the pointers
|
||||
** returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch()
|
||||
** might now be invalid because of a balance() or other change to the
|
||||
** b-tree.
|
||||
** 2: The cursor is no longer pointing to the row. The row might have
|
||||
** been deleted out from under the cursor.
|
||||
*/
|
||||
int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
|
||||
int rc;
|
||||
|
||||
if( pCur->eState==CURSOR_VALID ){
|
||||
*pHasMoved = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
rc = restoreCursorPosition(pCur);
|
||||
if( rc ){
|
||||
*pHasMoved = 1;
|
||||
*pHasMoved = 2;
|
||||
return rc;
|
||||
}
|
||||
if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
|
||||
*pHasMoved = 1;
|
||||
*pHasMoved = 2;
|
||||
}else{
|
||||
*pHasMoved = 0;
|
||||
*pHasMoved = 1;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -4188,10 +4200,13 @@ static const void *fetchPayload(
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->info.nSize>0 );
|
||||
#if 0
|
||||
if( pCur->info.nSize==0 ){
|
||||
btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
|
||||
&pCur->info);
|
||||
}
|
||||
#endif
|
||||
*pAmt = pCur->info.nLocal;
|
||||
return (void*)(pCur->info.pCell + pCur->info.nHeader);
|
||||
}
|
||||
|
@ -323,6 +323,7 @@ static int posixFchown(int fd, uid_t uid, gid_t gid){
|
||||
|
||||
/* Forward reference */
|
||||
static int openDirectory(const char*, int*);
|
||||
static int unixGetpagesize(void);
|
||||
|
||||
/*
|
||||
** Many system calls are accessed through pointer-to-functions so that
|
||||
@ -446,6 +447,9 @@ static struct unix_syscall {
|
||||
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
|
||||
#endif
|
||||
|
||||
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
|
||||
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
/*
|
||||
@ -4105,6 +4109,36 @@ static int unixShmSystemLock(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the system page size.
|
||||
**
|
||||
** This function should not be called directly by other code in this file.
|
||||
** Instead, it should be called via macro osGetpagesize().
|
||||
*/
|
||||
static int unixGetpagesize(void){
|
||||
#if defined(_BSD_SOURCE)
|
||||
return getpagesize();
|
||||
#else
|
||||
return (int)sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the minimum number of 32KB shm regions that should be mapped at
|
||||
** a time, assuming that each mapping must be an integer multiple of the
|
||||
** current system page-size.
|
||||
**
|
||||
** Usually, this is 1. The exception seems to be systems that are configured
|
||||
** to use 64KB pages - in this case each mapping must cover at least two
|
||||
** shm regions.
|
||||
*/
|
||||
static int unixShmRegionPerMap(void){
|
||||
int shmsz = 32*1024; /* SHM region size */
|
||||
int pgsz = osGetpagesize(); /* System page size */
|
||||
assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */
|
||||
if( pgsz<shmsz ) return 1;
|
||||
return pgsz/shmsz;
|
||||
}
|
||||
|
||||
/*
|
||||
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
|
||||
@ -4116,10 +4150,11 @@ static void unixShmPurge(unixFile *pFd){
|
||||
unixShmNode *p = pFd->pInode->pShmNode;
|
||||
assert( unixMutexHeld() );
|
||||
if( p && p->nRef==0 ){
|
||||
int nShmPerMap = unixShmRegionPerMap();
|
||||
int i;
|
||||
assert( p->pInode==pFd->pInode );
|
||||
sqlite3_mutex_free(p->mutex);
|
||||
for(i=0; i<p->nRegion; i++){
|
||||
for(i=0; i<p->nRegion; i+=nShmPerMap){
|
||||
if( p->h>=0 ){
|
||||
osMunmap(p->apRegion[i], p->szRegion);
|
||||
}else{
|
||||
@ -4326,6 +4361,8 @@ static int unixShmMap(
|
||||
unixShm *p;
|
||||
unixShmNode *pShmNode;
|
||||
int rc = SQLITE_OK;
|
||||
int nShmPerMap = unixShmRegionPerMap();
|
||||
int nReqRegion;
|
||||
|
||||
/* If the shared-memory file has not yet been opened, open it now. */
|
||||
if( pDbFd->pShm==0 ){
|
||||
@ -4341,9 +4378,12 @@ static int unixShmMap(
|
||||
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
|
||||
|
||||
if( pShmNode->nRegion<=iRegion ){
|
||||
/* Minimum number of regions required to be mapped. */
|
||||
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
|
||||
|
||||
if( pShmNode->nRegion<nReqRegion ){
|
||||
char **apNew; /* New apRegion[] array */
|
||||
int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
|
||||
int nByte = nReqRegion*szRegion; /* Minimum required file size */
|
||||
struct stat sStat; /* Used by fstat() */
|
||||
|
||||
pShmNode->szRegion = szRegion;
|
||||
@ -4392,17 +4432,19 @@ static int unixShmMap(
|
||||
|
||||
/* Map the requested memory region into this processes address space. */
|
||||
apNew = (char **)sqlite3_realloc(
|
||||
pShmNode->apRegion, (iRegion+1)*sizeof(char *)
|
||||
pShmNode->apRegion, nReqRegion*sizeof(char *)
|
||||
);
|
||||
if( !apNew ){
|
||||
rc = SQLITE_IOERR_NOMEM;
|
||||
goto shmpage_out;
|
||||
}
|
||||
pShmNode->apRegion = apNew;
|
||||
while(pShmNode->nRegion<=iRegion){
|
||||
while( pShmNode->nRegion<nReqRegion ){
|
||||
int nMap = szRegion*nShmPerMap;
|
||||
int i;
|
||||
void *pMem;
|
||||
if( pShmNode->h>=0 ){
|
||||
pMem = osMmap(0, szRegion,
|
||||
pMem = osMmap(0, nMap,
|
||||
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
|
||||
);
|
||||
@ -4418,8 +4460,11 @@ static int unixShmMap(
|
||||
}
|
||||
memset(pMem, 0, szRegion);
|
||||
}
|
||||
pShmNode->apRegion[pShmNode->nRegion] = pMem;
|
||||
pShmNode->nRegion++;
|
||||
|
||||
for(i=0; i<nShmPerMap; i++){
|
||||
pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
|
||||
}
|
||||
pShmNode->nRegion += nShmPerMap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4633,19 +4678,6 @@ static void unixUnmapfile(unixFile *pFd){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the system page size.
|
||||
*/
|
||||
static int unixGetPagesize(void){
|
||||
#if HAVE_MREMAP
|
||||
return 512;
|
||||
#elif defined(_BSD_SOURCE)
|
||||
return getpagesize();
|
||||
#else
|
||||
return (int)sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to set the size of the memory mapping maintained by file
|
||||
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
||||
@ -4682,8 +4714,12 @@ static void unixRemapfile(
|
||||
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
||||
|
||||
if( pOrig ){
|
||||
const int szSyspage = unixGetPagesize();
|
||||
#if HAVE_MREMAP
|
||||
i64 nReuse = pFd->mmapSize;
|
||||
#else
|
||||
const int szSyspage = osGetpagesize();
|
||||
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
|
||||
#endif
|
||||
u8 *pReq = &pOrig[nReuse];
|
||||
|
||||
/* Unmap any pages of the existing mapping that cannot be reused. */
|
||||
@ -7429,7 +7465,7 @@ int sqlite3_os_init(void){
|
||||
|
||||
/* Double-check that the aSyscall[] array has been constructed
|
||||
** correctly. See ticket [bb3a86e890c8e96ab] */
|
||||
assert( ArraySize(aSyscall)==24 );
|
||||
assert( ArraySize(aSyscall)==25 );
|
||||
|
||||
/* Register all VFSes defined in the aVfs[] array */
|
||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||
|
@ -2393,8 +2393,6 @@ struct Parse {
|
||||
u8 checkSchema; /* Causes schema cookie check after an error */
|
||||
u8 nested; /* Number of nested calls to the parser/code generator */
|
||||
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
|
||||
u8 nColCache; /* Number of entries in aColCache[] */
|
||||
u8 iColCache; /* Next entry in aColCache[] to replace */
|
||||
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
|
||||
u8 mayAbort; /* True if statement may throw an ABORT exception */
|
||||
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
|
||||
|
@ -67,6 +67,11 @@
|
||||
** test_syscall list
|
||||
** Return a list of all system calls. The list is constructed using
|
||||
** the xNextSystemCall() VFS method.
|
||||
**
|
||||
** test_syscall pagesize PGSZ
|
||||
** If PGSZ is a power of two greater than 256, install a wrapper around
|
||||
** OS function getpagesize() that reports the system page size as PGSZ.
|
||||
** Or, if PGSZ is less than zero, remove any wrapper already installed.
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@ -89,7 +94,9 @@ static struct TestSyscallGlobal {
|
||||
int bPersist; /* 1 for persistent errors, 0 for transient */
|
||||
int nCount; /* Fail after this many more calls */
|
||||
int nFail; /* Number of failures that have occurred */
|
||||
} gSyscall = { 0, 0 };
|
||||
int pgsz;
|
||||
sqlite3_syscall_ptr orig_getpagesize;
|
||||
} gSyscall = { 0, 0, 0, 0, 0 };
|
||||
|
||||
static int ts_open(const char *, int, int);
|
||||
static int ts_close(int fd);
|
||||
@ -650,6 +657,45 @@ static int test_syscall_defaultvfs(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int ts_getpagesize(void){
|
||||
return gSyscall.pgsz;
|
||||
}
|
||||
|
||||
static int test_syscall_pagesize(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
|
||||
int pgsz;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "PGSZ");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &pgsz) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( pgsz<0 ){
|
||||
if( gSyscall.orig_getpagesize ){
|
||||
pVfs->xSetSystemCall(pVfs, "getpagesize", gSyscall.orig_getpagesize);
|
||||
}
|
||||
}else{
|
||||
if( pgsz<512 || (pgsz & (pgsz-1)) ){
|
||||
Tcl_AppendResult(interp, "pgsz out of range", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
gSyscall.orig_getpagesize = pVfs->xGetSystemCall(pVfs, "getpagesize");
|
||||
gSyscall.pgsz = pgsz;
|
||||
pVfs->xSetSystemCall(
|
||||
pVfs, "getpagesize", (sqlite3_syscall_ptr)ts_getpagesize
|
||||
);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int test_syscall(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
@ -668,6 +714,7 @@ static int test_syscall(
|
||||
{ "exists", test_syscall_exists },
|
||||
{ "list", test_syscall_list },
|
||||
{ "defaultvfs", test_syscall_defaultvfs },
|
||||
{ "pagesize", test_syscall_pagesize },
|
||||
{ 0, 0 }
|
||||
};
|
||||
int iCmd;
|
||||
|
35
src/vdbe.c
35
src/vdbe.c
@ -310,6 +310,29 @@ void sqlite3ValueApplyAffinity(
|
||||
applyAffinity((Mem *)pVal, affinity, enc);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
|
||||
** none.
|
||||
**
|
||||
** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
|
||||
** But it does set pMem->r and pMem->u.i appropriately.
|
||||
*/
|
||||
static u16 numericType(Mem *pMem){
|
||||
if( pMem->flags & (MEM_Int|MEM_Real) ){
|
||||
return pMem->flags & (MEM_Int|MEM_Real);
|
||||
}
|
||||
if( pMem->flags & (MEM_Str|MEM_Blob) ){
|
||||
if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){
|
||||
return 0;
|
||||
}
|
||||
if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
|
||||
return MEM_Int;
|
||||
}
|
||||
return MEM_Real;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Write a nice string representation of the contents of cell pMem
|
||||
@ -1351,20 +1374,22 @@ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
|
||||
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
|
||||
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
||||
char bIntint; /* Started out as two integer operands */
|
||||
int flags; /* Combined MEM_* flags from both inputs */
|
||||
u16 flags; /* Combined MEM_* flags from both inputs */
|
||||
u16 type1; /* Numeric type of left operand */
|
||||
u16 type2; /* Numeric type of right operand */
|
||||
i64 iA; /* Integer value of left operand */
|
||||
i64 iB; /* Integer value of right operand */
|
||||
double rA; /* Real value of left operand */
|
||||
double rB; /* Real value of right operand */
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
applyNumericAffinity(pIn1);
|
||||
type1 = numericType(pIn1);
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
applyNumericAffinity(pIn2);
|
||||
type2 = numericType(pIn2);
|
||||
pOut = &aMem[pOp->p3];
|
||||
flags = pIn1->flags | pIn2->flags;
|
||||
if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
|
||||
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
|
||||
if( (type1 & type2 & MEM_Int)!=0 ){
|
||||
iA = pIn1->u.i;
|
||||
iB = pIn2->u.i;
|
||||
bIntint = 1;
|
||||
@ -1420,7 +1445,7 @@ fp_math:
|
||||
}
|
||||
pOut->r = rB;
|
||||
MemSetTypeFlag(pOut, MEM_Real);
|
||||
if( (flags & MEM_Real)==0 && !bIntint ){
|
||||
if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
|
||||
sqlite3VdbeIntegerAffinity(pOut);
|
||||
}
|
||||
#endif
|
||||
|
@ -2735,7 +2735,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
|
||||
if( rc ) return rc;
|
||||
if( hasMoved ){
|
||||
p->cacheStatus = CACHE_STALE;
|
||||
p->nullRow = 1;
|
||||
if( hasMoved==2 ) p->nullRow = 1;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
|
@ -512,6 +512,45 @@ void testset_main(void){
|
||||
speedtest1_end_test();
|
||||
|
||||
|
||||
n = g.szTest/5;
|
||||
speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
|
||||
speedtest1_exec("BEGIN");
|
||||
speedtest1_prepare(
|
||||
"SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
|
||||
" ORDER BY a; -- %d times", n
|
||||
);
|
||||
for(i=1; i<=n; i++){
|
||||
x1 = speedtest1_random()%maxb;
|
||||
zNum[0] = '%';
|
||||
len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
|
||||
zNum[len] = '%';
|
||||
zNum[len+1] = 0;
|
||||
sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_exec("COMMIT");
|
||||
speedtest1_end_test();
|
||||
|
||||
n = g.szTest/5;
|
||||
speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
|
||||
speedtest1_exec("BEGIN");
|
||||
speedtest1_prepare(
|
||||
"SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
|
||||
" ORDER BY a LIMIT 10; -- %d times", n
|
||||
);
|
||||
for(i=1; i<=n; i++){
|
||||
x1 = speedtest1_random()%maxb;
|
||||
zNum[0] = '%';
|
||||
len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
|
||||
zNum[len] = '%';
|
||||
zNum[len+1] = 0;
|
||||
sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_exec("COMMIT");
|
||||
speedtest1_end_test();
|
||||
|
||||
|
||||
speedtest1_begin_test(150, "CREATE INDEX five times");
|
||||
speedtest1_exec("BEGIN;");
|
||||
speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
|
||||
|
@ -61,6 +61,7 @@ foreach s {
|
||||
fcntl read pread write pwrite fchmod fallocate
|
||||
pread64 pwrite64 unlink openDirectory mkdir rmdir
|
||||
statvfs fchown umask mmap munmap mremap
|
||||
getpagesize
|
||||
} {
|
||||
if {[test_syscall exists $s]} {lappend syscall_list $s}
|
||||
}
|
||||
|
93
test/tkt-a8a0d2996a.test
Normal file
93
test/tkt-a8a0d2996a.test
Normal file
@ -0,0 +1,93 @@
|
||||
# 2014-03-24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Tests to verify that arithmetic operators do not change the type of
|
||||
# input operands. Ticket [a8a0d2996a]
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix tkt-a8a0d2996a
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t(x,y);
|
||||
INSERT INTO t VALUES('1','1');
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x+0 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 1.1 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x-0 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 1.2 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x*1 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 1.3 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x/1 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 1.4 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x%4 AND y=='1';
|
||||
} {text text}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
UPDATE t SET x='1xyzzy';
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x+0 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 2.1 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x-0 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 2.2 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x*1 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 2.3 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x/1 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 2.4 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x%4 AND y=='1';
|
||||
} {text text}
|
||||
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
UPDATE t SET x='1.0';
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x+0 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 3.1 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x-0 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 3.2 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x*1 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 3.3 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x/1 AND y=='1';
|
||||
} {text text}
|
||||
do_execsql_test 3.4 {
|
||||
SELECT typeof(x), typeof(y) FROM t WHERE 1=x%4 AND y=='1';
|
||||
} {text text}
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
SELECT 1+1.;
|
||||
} {2.0}
|
||||
do_execsql_test 4.1 {
|
||||
SELECT '1.23e64'/'1.0000e+62';
|
||||
} {123.0}
|
||||
do_execsql_test 4.2 {
|
||||
SELECT '100x'+'-2y';
|
||||
} {98}
|
||||
do_execsql_test 4.3 {
|
||||
SELECT '100x'+'4.5y';
|
||||
} {104.5}
|
||||
do_execsql_test 4.4 {
|
||||
SELECT '-9223372036854775807x'-'1x';
|
||||
} {-9.22337203685478e+18}
|
||||
do_execsql_test 4.5 {
|
||||
SELECT '9223372036854775806x'+'1x';
|
||||
} {9.22337203685478e+18}
|
||||
do_execsql_test 4.6 {
|
||||
SELECT '1234x'/'10y';
|
||||
} {123.4}
|
47
test/wal64k.test
Normal file
47
test/wal64k.test
Normal file
@ -0,0 +1,47 @@
|
||||
# 2010 April 13
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the operation of the library in
|
||||
# "PRAGMA journal_mode=WAL" mode.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix wal64k
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
db close
|
||||
test_syscall pagesize 65536
|
||||
sqlite3 db test.db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA journal_mode = WAL;
|
||||
CREATE TABLE t1(x);
|
||||
CREATE INDEX i1 ON t1(x);
|
||||
} {wal}
|
||||
do_test 1.1 { file size test.db-shm } {65536}
|
||||
|
||||
do_test 1.2 {
|
||||
execsql BEGIN
|
||||
while {[file size test.db-shm]==65536} {
|
||||
execsql { INSERT INTO t1 VALUES( randstr(900,1100) ) }
|
||||
}
|
||||
execsql COMMIT
|
||||
file size test.db-shm
|
||||
} {131072}
|
||||
|
||||
integrity_check 1.3
|
||||
|
||||
db close
|
||||
test_syscall pagesize -1
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user