mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-10 01:02:56 +03:00
All mutexing and locking appears to be in place. Now we just have to
test it and make it all work. (CVS 4264) FossilOrigin-Name: 0f7941aef976aa4f3be3e0046edd1ae042e5d9a3
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C The\ssqlite3_value\sobject\snow\scarries\san\ssqlite3*\spointer\sto\suse\sfor\nrecording\smalloc\sfailures.\s\sThis\seliminates\sthe\sneed\sto\spass\ssqlite3*\npointers\sinto\smany\sinternal\sinterfaces.\s\sAlso\sadded\smore\smutexing.\s(CVS\s4263)
|
||||
D 2007-08-21T19:33:56
|
||||
C All\smutexing\sand\slocking\sappears\sto\sbe\sin\splace.\s\sNow\swe\sjust\shave\sto\ntest\sit\sand\smake\sit\sall\swork.\s(CVS\s4264)
|
||||
D 2007-08-21T20:25:40
|
||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@@ -124,7 +124,7 @@ F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
||||
F src/sqlite.h.in 95e159919060f9c6e060ff420ce17490f7b6a0f3
|
||||
F src/sqlite.h.in b2a7484c024c42f2e639f289beb7c8db36513a2c
|
||||
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
|
||||
F src/sqliteInt.h 23eb6a5b1f10d5d3d34c3c7846b7c3b93acf1276
|
||||
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
|
||||
@@ -159,7 +159,7 @@ F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373
|
||||
F src/vdbe.c 9d4d00589c174aad9a616f1615464ddddebba0ec
|
||||
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
|
||||
F src/vdbeInt.h 39fb069ce04137545ca0bc790f80ddc64a8c99d9
|
||||
F src/vdbeapi.c 09eb4fe5ce6e8e4558ca3fa1e22241f2d3895bf0
|
||||
F src/vdbeapi.c e12f99aa859118afbffff67eb32df36d564b5c80
|
||||
F src/vdbeaux.c b0aeed4ff33352904b392ee6c7408bae5b141b9b
|
||||
F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7
|
||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||
@@ -558,7 +558,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 7428732b1fa04b83eda0a3539834693ef351313e
|
||||
R 913d5d6bd631d176ac289a9e0cf82ff0
|
||||
P 9287276191a582c1cf7cf6b71d8399727d8e534d
|
||||
R c2481d632c284d895f66ae3d4866a0ab
|
||||
U drh
|
||||
Z c581f4a42a4b4dc59e9659821c9fdece
|
||||
Z aa5c15d669e0ef0f762ec1f2d438a5a0
|
||||
|
@@ -1 +1 @@
|
||||
9287276191a582c1cf7cf6b71d8399727d8e534d
|
||||
0f7941aef976aa4f3be3e0046edd1ae042e5d9a3
|
@@ -30,7 +30,7 @@
|
||||
** the version number) and changes its name to "sqlite3.h" as
|
||||
** part of the build process.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.234 2007/08/21 19:33:56 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.235 2007/08/21 20:25:40 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@@ -1745,6 +1745,10 @@ const void *sqlite3_column_name16(sqlite3_stmt*, int N);
|
||||
**
|
||||
** These APIs are only available if the library was compiled with the
|
||||
** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
|
||||
**
|
||||
** If two or more threads call one or more of these routines against the same
|
||||
** prepared statement and column at the same time then the results are
|
||||
** undefined.
|
||||
*/
|
||||
const char *sqlite3_column_database_name(sqlite3_stmt*,int);
|
||||
const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
|
||||
@@ -1905,17 +1909,27 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
/*
|
||||
** CAPI3REF: Results Values From A Query
|
||||
**
|
||||
** These routines return information about the information
|
||||
** in a single column of the current result row of a query. In every
|
||||
** These routines return information about
|
||||
** a single column of the current result row of a query. In every
|
||||
** case the first argument is a pointer to the
|
||||
** [sqlite3_stmt | SQL statement] that is being
|
||||
** evaluate (the [sqlite3_stmt*] that was returned from
|
||||
** evaluated (the [sqlite3_stmt*] that was returned from
|
||||
** [sqlite3_prepare_v2()] or one of its variants) and
|
||||
** the second argument is the index of the column for which information
|
||||
** should be returned. The left-most column has an index of 0.
|
||||
** should be returned. The left-most column of the result set
|
||||
** has an index of 0.
|
||||
**
|
||||
** If the SQL statement is not currently point to a valid row, or if the
|
||||
** the column index is out of range, the result is undefined.
|
||||
** These routines may only be called when the most recent call to
|
||||
** [sqlite3_step()] has returned [SQLITE_ROW] and neither
|
||||
** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently.
|
||||
** If any of these routines are called after [sqlite3_reset()] or
|
||||
** [sqlite3_finalize()] or after [sqlite3_step()] has returned
|
||||
** something other than [SQLITE_ROW], the results are undefined.
|
||||
** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
|
||||
** are called from a different thread while any of these routines
|
||||
** are pending, then the results are undefined.
|
||||
**
|
||||
** The sqlite3_column_type() routine returns
|
||||
** [SQLITE_INTEGER | datatype code] for the initial data type
|
||||
@@ -2019,6 +2033,13 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** find the size of the result. Do not mix call to sqlite3_column_text() or
|
||||
** sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not
|
||||
** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes().
|
||||
**
|
||||
** The pointers returned are valid until a type conversion occurs as
|
||||
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
|
||||
** [sqlite3_finalize()] is called. The memory space used to hold strings
|
||||
** and blobs is freed automatically. Do <b>not</b> pass the pointers returned
|
||||
** [sqlite3_column_blob()], [sqlite_column_text()], etc. into
|
||||
** [sqlite3_free()].
|
||||
*/
|
||||
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
|
||||
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
|
||||
@@ -2211,6 +2232,9 @@ void sqlite3_thread_cleanup(void);
|
||||
**
|
||||
** These routines must be called from the same thread as
|
||||
** the SQL function that supplied the sqlite3_value* parameters.
|
||||
** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()]
|
||||
** interface, then these routines should be called from the same thread
|
||||
** that ran [sqlite3_column_value()].
|
||||
*/
|
||||
const void *sqlite3_value_blob(sqlite3_value*);
|
||||
int sqlite3_value_bytes(sqlite3_value*);
|
||||
@@ -3311,6 +3335,13 @@ int sqlite3_mutex_try(sqlite3_mutex*);
|
||||
void sqlite3_mutex_leave(sqlite3_mutex*);
|
||||
int sqlite3_mutex_held(sqlite3_mutex*);
|
||||
int sqlite3_mutex_notheld(sqlite3_mutex*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Types
|
||||
**
|
||||
** The [sqlite3_mutex_alloc()] interface takes a single argument
|
||||
** which is one of these integer constants.
|
||||
*/
|
||||
#define SQLITE_MUTEX_FAST 0
|
||||
#define SQLITE_MUTEX_RECURSIVE 1
|
||||
#define SQLITE_MUTEX_STATIC_MASTER 2
|
||||
|
@@ -137,7 +137,6 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){
|
||||
int sqlite3_value_type(sqlite3_value* pVal){
|
||||
return pVal->type;
|
||||
}
|
||||
/* sqlite3_value_numeric_type() defined in vdbe.c */
|
||||
|
||||
/**************************** sqlite3_result_ *******************************
|
||||
** The following routines are used by user-defined functions to specify
|
||||
@@ -150,28 +149,35 @@ void sqlite3_result_blob(
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( n>=0 );
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
|
||||
}
|
||||
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
|
||||
}
|
||||
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
pCtx->isError = 1;
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
pCtx->isError = 1;
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
|
||||
}
|
||||
#endif
|
||||
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
|
||||
}
|
||||
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
|
||||
}
|
||||
void sqlite3_result_null(sqlite3_context *pCtx){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetNull(&pCtx->s);
|
||||
}
|
||||
void sqlite3_result_text(
|
||||
@@ -180,6 +186,7 @@ void sqlite3_result_text(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -189,6 +196,7 @@ void sqlite3_result_text16(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
|
||||
}
|
||||
void sqlite3_result_text16be(
|
||||
@@ -197,6 +205,7 @@ void sqlite3_result_text16be(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
|
||||
}
|
||||
void sqlite3_result_text16le(
|
||||
@@ -205,18 +214,22 @@ void sqlite3_result_text16le(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemCopy(&pCtx->s, pValue);
|
||||
}
|
||||
void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
|
||||
}
|
||||
|
||||
/* Force an SQLITE_TOOBIG error. */
|
||||
void sqlite3_result_error_toobig(sqlite3_context *pCtx){
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
sqlite3VdbeMemSetZeroBlob(&pCtx->s, SQLITE_MAX_LENGTH+1);
|
||||
}
|
||||
|
||||
@@ -535,14 +548,21 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){
|
||||
** of NULL.
|
||||
*/
|
||||
static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
||||
Vdbe *pVm = (Vdbe *)pStmt;
|
||||
int vals = sqlite3_data_count(pStmt);
|
||||
if( pVm==0 || pVm->resOnStack==0 || i>=pVm->nResColumn || i<0 ){
|
||||
Vdbe *pVm;
|
||||
int vals;
|
||||
Mem *pOut;
|
||||
|
||||
pVm = (Vdbe *)pStmt;
|
||||
if( pVm && pVm->resOnStack && i<pVm->nResColumn && i>=0 ){
|
||||
sqlite3_mutex_enter(pVm->db->mutex);
|
||||
vals = sqlite3_data_count(pStmt);
|
||||
pOut = &pVm->pTos[(1-vals)+i];
|
||||
}else{
|
||||
static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL };
|
||||
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
|
||||
return (Mem*)&nullMem;
|
||||
pOut = (Mem*)&nullMem;
|
||||
}
|
||||
return &pVm->pTos[(1-vals)+i];
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -552,7 +572,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
||||
** malloc() has failed, the threads mallocFailed flag is cleared and the result
|
||||
** code of statement pStmt set to SQLITE_NOMEM.
|
||||
**
|
||||
** Specificly, this is called from within:
|
||||
** Specifically, this is called from within:
|
||||
**
|
||||
** sqlite3_column_int()
|
||||
** sqlite3_column_int64()
|
||||
@@ -572,7 +592,10 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
|
||||
** and _finalize() will return NOMEM.
|
||||
*/
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
p->rc = sqlite3ApiExit(0, p->rc);
|
||||
if( p ){
|
||||
p->rc = sqlite3ApiExit(p->db, p->rc);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************** sqlite3_column_ *******************************
|
||||
@@ -620,7 +643,9 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
|
||||
return val;
|
||||
}
|
||||
sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
|
||||
return columnMem(pStmt, i);
|
||||
sqlite3_value *pOut = columnMem(pStmt, i);
|
||||
columnMallocFailure(pStmt);
|
||||
return pOut;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
|
||||
@@ -630,7 +655,9 @@ const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
|
||||
return sqlite3_value_type( columnMem(pStmt,i) );
|
||||
int iType = sqlite3_value_type( columnMem(pStmt,i) );
|
||||
columnMallocFailure(pStmt);
|
||||
return iType;
|
||||
}
|
||||
|
||||
/* The following function is experimental and subject to change or
|
||||
@@ -662,20 +689,28 @@ static const void *columnName(
|
||||
const void *(*xFunc)(Mem*),
|
||||
int useType
|
||||
){
|
||||
const void *ret;
|
||||
const void *ret = 0;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
int n = sqlite3_column_count(pStmt);
|
||||
int n;
|
||||
|
||||
if( p==0 || N>=n || N<0 ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( p!=0 ){
|
||||
n = sqlite3_column_count(pStmt);
|
||||
if( N<n && N>=0 ){
|
||||
N += useType*n;
|
||||
ret = xFunc(&p->aColName[N]);
|
||||
|
||||
/* A malloc may have failed inside of the xFunc() call. If this is the case,
|
||||
** clear the mallocFailed flag and return NULL.
|
||||
#if 0
|
||||
/* A malloc may have failed inside of the xFunc() call. If this
|
||||
** is the case, clear the mallocFailed flag and return NULL.
|
||||
*/
|
||||
sqlite3ApiExit(0, 0);
|
||||
if( p->db && p->db->mallocFailed ){
|
||||
p->db->mallocFailed = 0;
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user