mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Update an allocation routine in the sessions module to allow it to allocate the maximum size permitted by sqlite3_realloc64().
FossilOrigin-Name: 0b45e821911e4a852edd6d9e9cfe5f9de33337edf76fb12b79adaf11a4b83e8a
This commit is contained in:
98
ext/session/sessionbig.test
Normal file
98
ext/session/sessionbig.test
Normal file
@ -0,0 +1,98 @@
|
||||
# 2014 August 16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file implements regression tests for sessions SQLite extension.
|
||||
# Specifically, this file contains tests for "patchset" changes.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix sessionbig
|
||||
|
||||
forcedelete test.db2
|
||||
sqlite3 db2 test.db2
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
}
|
||||
do_execsql_test -db db2 1.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
}
|
||||
|
||||
do_test 1.2 {
|
||||
do_then_apply_sql {
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 1.3 {
|
||||
execsql { DELETE FROM t1 }
|
||||
execsql2 { DELETE FROM t1 }
|
||||
} {}
|
||||
|
||||
do_test 1.4 {
|
||||
set rc [catch {
|
||||
do_then_apply_sql {
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
}
|
||||
} msg]
|
||||
list $rc $msg
|
||||
} {1 SQLITE_NOMEM}
|
||||
|
||||
|
||||
finish_test
|
||||
|
@ -1974,13 +1974,29 @@ int sqlite3session_attach(
|
||||
** If successful, return zero. Otherwise, if an OOM condition is encountered,
|
||||
** set *pRc to SQLITE_NOMEM and return non-zero.
|
||||
*/
|
||||
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
|
||||
if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){
|
||||
static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
|
||||
#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1)
|
||||
i64 nReq = p->nBuf + nByte;
|
||||
if( *pRc==SQLITE_OK && nReq>p->nAlloc ){
|
||||
u8 *aNew;
|
||||
i64 nNew = p->nAlloc ? p->nAlloc : 128;
|
||||
|
||||
do {
|
||||
nNew = nNew*2;
|
||||
}while( (size_t)(nNew-p->nBuf)<nByte );
|
||||
}while( nNew<nReq );
|
||||
|
||||
/* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
|
||||
** of sqlite3_realloc64(). Allocations greater than this size in bytes
|
||||
** always fail. It is used here to ensure that this routine can always
|
||||
** allocate up to this limit - instead of up to the largest power of
|
||||
** two smaller than the limit. */
|
||||
if( nNew>SESSION_MAX_BUFFER_SZ ){
|
||||
nNew = SESSION_MAX_BUFFER_SZ;
|
||||
if( nNew<nReq ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
|
||||
if( 0==aNew ){
|
||||
|
Reference in New Issue
Block a user