Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Incorporation the latest SQLite 3.8.7 alpha from upstream, for testing. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
fc8d8546ffabbdc5282b64fad3606d42 |
| User & Date: | drh 2014-09-01 18:42:30.122 |
Context
|
2014-09-01
| ||
| 18:51 | Add the --with-miniz configuration option (with the complete miniz source code.) Add the globalState TH1 command and fixes to the TH1 expr command. check-in: 66ae70a54b user: drh tags: trunk | |
| 18:42 | Incorporation the latest SQLite 3.8.7 alpha from upstream, for testing. check-in: fc8d8546ff user: drh tags: trunk | |
|
2014-08-31
| ||
| 08:42 | Cherry-pick [http://www.sqlite.org/src/info/f61db04be4d7fb21b7f721647c37c45e283ffbea|f61db04be4]: In the command-line shell, added options --lookaside, --pagecache, and --scratch used to configure auxiliary memories (except from the change from SQLITE_CONFIG_SINGLETHREAD -> SQLITE_CONFIG_MULTITHREAD, because fossil doesn't use multiple threads) check-in: 75dcdd0bdb user: jan.nijtmans tags: trunk | |
Changes
Changes to src/shell.c.
| ︙ | ︙ | |||
3825 3826 3827 3828 3829 3830 3831 3832 3833 | data->mode = MODE_List; memcpy(data->separator,"|", 2); memcpy(data->newline,"\r\n", 3); data->showHeader = 0; data->shellFlgs = SHFLG_Lookaside; sqlite3_config(SQLITE_CONFIG_URI, 1); sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); | > < | 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 |
data->mode = MODE_List;
memcpy(data->separator,"|", 2);
memcpy(data->newline,"\r\n", 3);
data->showHeader = 0;
data->shellFlgs = SHFLG_Lookaside;
sqlite3_config(SQLITE_CONFIG_URI, 1);
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
}
/*
** Output text to the console in a font that attracts extra attention.
*/
#ifdef _WIN32
static void printBold(const char *zText){
|
| ︙ | ︙ | |||
3938 3939 3940 3941 3942 3943 3944 |
zSize = cmdline_option_value(argc, argv, ++i);
szHeap = integerValue(zSize);
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#endif
}else if( strcmp(z,"-scratch")==0 ){
int n, sz;
| | | | | | | | 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 |
zSize = cmdline_option_value(argc, argv, ++i);
szHeap = integerValue(zSize);
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#endif
}else if( strcmp(z,"-scratch")==0 ){
int n, sz;
sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
if( sz>400000 ) sz = 400000;
if( sz<2500 ) sz = 2500;
n = (int)integerValue(cmdline_option_value(argc,argv,++i));
if( n>10 ) n = 10;
if( n<1 ) n = 1;
sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
data.shellFlgs |= SHFLG_Scratch;
}else if( strcmp(z,"-pagecache")==0 ){
int n, sz;
sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
if( sz>70000 ) sz = 70000;
if( sz<800 ) sz = 800;
n = (int)integerValue(cmdline_option_value(argc,argv,++i));
if( n<10 ) n = 10;
sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
data.shellFlgs |= SHFLG_Pagecache;
}else if( strcmp(z,"-lookaside")==0 ){
int n, sz;
sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
if( sz<0 ) sz = 0;
n = (int)integerValue(cmdline_option_value(argc,argv,++i));
if( n<0 ) n = 0;
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
#ifdef SQLITE_ENABLE_VFSTRACE
}else if( strcmp(z,"-vfstrace")==0 ){
extern int vfstrace_register(
const char *zTraceName,
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | 1 2 3 4 5 6 7 8 9 10 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.8.7. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other |
| ︙ | ︙ | |||
218 219 220 221 222 223 224 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.7" #define SQLITE_VERSION_NUMBER 3008007 #define SQLITE_SOURCE_ID "2014-09-01 18:21:27 672e7387b1bda8d007da7de4244226577d7ab2dc" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 |
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
#define SQLITE_LIMIT_SQL_LENGTH 1
#define SQLITE_LIMIT_COLUMN 2
#define SQLITE_LIMIT_EXPR_DEPTH 3
#define SQLITE_LIMIT_COMPOUND_SELECT 4
#define SQLITE_LIMIT_VDBE_OP 5
#define SQLITE_LIMIT_FUNCTION_ARG 6
#define SQLITE_LIMIT_ATTACHED 7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
| > > > > > | 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 |
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
**
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
** <dd>The maximum number of auxiliary worker threads that a single
** [prepared statement] may start.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
#define SQLITE_LIMIT_SQL_LENGTH 1
#define SQLITE_LIMIT_COLUMN 2
#define SQLITE_LIMIT_EXPR_DEPTH 3
#define SQLITE_LIMIT_COMPOUND_SELECT 4
#define SQLITE_LIMIT_VDBE_OP 5
#define SQLITE_LIMIT_FUNCTION_ARG 6
#define SQLITE_LIMIT_ATTACHED 7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
|
| ︙ | ︙ | |||
6276 6277 6278 6279 6280 6281 6282 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 | > | | 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_LAST 24 /* ** CAPI3REF: SQLite Runtime Status ** ** ^This interface is used to retrieve runtime status information ** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for |
| ︙ | ︙ | |||
7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 | # define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) #else /* Generates a warning - but it always works */ # define SQLITE_INT_TO_PTR(X) ((void*)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never ** threadsafe. 1 means the library is serialized which is the highest ** level of threadsafety. 2 means the library is multithreaded - multiple ** threads can use SQLite as long as no two threads try to use the same ** database connection at the same time. | > > > > > > > > > > > > | 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 | # define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) #else /* Generates a warning - but it always works */ # define SQLITE_INT_TO_PTR(X) ((void*)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif /* ** A macro to hint to the compiler that a function should not be ** inlined. */ #if defined(__GNUC__) # define SQLITE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) # define SQLITE_NOINLINE __declspec(noinline) #else # define SQLITE_NOINLINE #endif /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never ** threadsafe. 1 means the library is serialized which is the highest ** level of threadsafety. 2 means the library is multithreaded - multiple ** threads can use SQLite as long as no two threads try to use the same ** database connection at the same time. |
| ︙ | ︙ | |||
8152 8153 8154 8155 8156 8157 8158 |
**
** Again, this structure is intended to be opaque, but it can't really
** be opaque because it is used by macros.
*/
struct HashElem {
HashElem *next, *prev; /* Next and previous elements in the table */
void *data; /* Data associated with this element */
| | | | | 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 |
**
** Again, this structure is intended to be opaque, but it can't really
** be opaque because it is used by macros.
*/
struct HashElem {
HashElem *next, *prev; /* Next and previous elements in the table */
void *data; /* Data associated with this element */
const char *pKey; /* Key associated with this element */
};
/*
** Access routines. To delete, insert a NULL pointer.
*/
SQLITE_PRIVATE void sqlite3HashInit(Hash*);
SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey);
SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/*
** Macros for looping over all elements of a hash table. The idiom is
** like this:
**
** Hash h;
|
| ︙ | ︙ | |||
8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 | ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified ** on the command-line */ #ifndef SQLITE_TEMP_STORE # define SQLITE_TEMP_STORE 1 # define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */ #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) | > > > > > > > > > > > > > > > > > > > > > | 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 | ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified ** on the command-line */ #ifndef SQLITE_TEMP_STORE # define SQLITE_TEMP_STORE 1 # define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */ #endif /* ** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if ** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it ** to zero. */ #if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0 # undef SQLITE_MAX_WORKER_THREADS # define SQLITE_MAX_WORKER_THREADS 0 #endif #ifndef SQLITE_MAX_WORKER_THREADS # define SQLITE_MAX_WORKER_THREADS 8 #endif #ifndef SQLITE_DEFAULT_WORKER_THREADS # define SQLITE_DEFAULT_WORKER_THREADS 0 #endif #if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS # undef SQLITE_MAX_WORKER_THREADS # define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) |
| ︙ | ︙ | |||
8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 | typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; typedef struct PrintfArguments PrintfArguments; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SelectDest SelectDest; typedef struct SrcList SrcList; typedef struct StrAccum StrAccum; typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; typedef struct Trigger Trigger; | > | 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 | typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; typedef struct PrintfArguments PrintfArguments; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; typedef struct SrcList SrcList; typedef struct StrAccum StrAccum; typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; typedef struct Trigger Trigger; |
| ︙ | ︙ | |||
8996 8997 8998 8999 9000 9001 9002 | SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( BtCursor*, UnpackedRecord *pUnKey, i64 intKey, int bias, int *pRes ); | | > | 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 |
SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
BtCursor*,
UnpackedRecord *pUnKey,
i64 intKey,
int bias,
int *pRes
);
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*);
SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
const void *pData, int nData,
int nZero, int bias, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes);
|
| ︙ | ︙ | |||
9287 9288 9289 9290 9291 9292 9293 | #define OP_Copy 33 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_SCopy 34 /* synopsis: r[P2]=r[P1] */ #define OP_ResultRow 35 /* synopsis: output=r[P1@P2] */ #define OP_CollSeq 36 #define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */ #define OP_MustBeInt 38 #define OP_RealAffinity 39 | > | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | < < | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < > > | | | | | | | | | < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 |
#define OP_Copy 33 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
#define OP_SCopy 34 /* synopsis: r[P2]=r[P1] */
#define OP_ResultRow 35 /* synopsis: output=r[P1@P2] */
#define OP_CollSeq 36
#define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */
#define OP_MustBeInt 38
#define OP_RealAffinity 39
#define OP_Cast 40 /* synopsis: affinity(r[P1]) */
#define OP_Permutation 41
#define OP_Compare 42 /* synopsis: r[P1@P3] <-> r[P2@P3] */
#define OP_Jump 43
#define OP_Once 44
#define OP_If 45
#define OP_IfNot 46
#define OP_Column 47 /* synopsis: r[P3]=PX */
#define OP_Affinity 48 /* synopsis: affinity(r[P1@P2]) */
#define OP_MakeRecord 49 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
#define OP_Count 50 /* synopsis: r[P2]=count() */
#define OP_ReadCookie 51
#define OP_SetCookie 52
#define OP_ReopenIdx 53 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenRead 54 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenWrite 55 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenAutoindex 56 /* synopsis: nColumn=P2 */
#define OP_OpenEphemeral 57 /* synopsis: nColumn=P2 */
#define OP_SorterOpen 58
#define OP_SequenceTest 59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
#define OP_OpenPseudo 60 /* synopsis: P3 columns in r[P2] */
#define OP_Close 61
#define OP_SeekLT 62 /* synopsis: key=r[P3@P4] */
#define OP_SeekLE 63 /* synopsis: key=r[P3@P4] */
#define OP_SeekGE 64 /* synopsis: key=r[P3@P4] */
#define OP_SeekGT 65 /* synopsis: key=r[P3@P4] */
#define OP_Seek 66 /* synopsis: intkey=r[P2] */
#define OP_NoConflict 67 /* synopsis: key=r[P3@P4] */
#define OP_NotFound 68 /* synopsis: key=r[P3@P4] */
#define OP_Found 69 /* synopsis: key=r[P3@P4] */
#define OP_NotExists 70 /* synopsis: intkey=r[P3] */
#define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
#define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
#define OP_Sequence 73 /* synopsis: r[P2]=cursor[P1].ctr++ */
#define OP_NewRowid 74 /* synopsis: r[P2]=rowid */
#define OP_Insert 75 /* synopsis: intkey=r[P3] data=r[P2] */
#define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
#define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
#define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
#define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
#define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
#define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
#define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
#define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
#define OP_InsertInt 84 /* synopsis: intkey=P3 data=r[P2] */
#define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
#define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
#define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
#define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
#define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
#define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
#define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
#define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
#define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
#define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
#define OP_Delete 95
#define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
#define OP_ResetCount 98
#define OP_SorterCompare 99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
#define OP_SorterData 100 /* synopsis: r[P2]=data */
#define OP_RowKey 101 /* synopsis: r[P2]=key */
#define OP_RowData 102 /* synopsis: r[P2]=data */
#define OP_Rowid 103 /* synopsis: r[P2]=rowid */
#define OP_NullRow 104
#define OP_Last 105
#define OP_SorterSort 106
#define OP_Sort 107
#define OP_Rewind 108
#define OP_SorterInsert 109
#define OP_IdxInsert 110 /* synopsis: key=r[P2] */
#define OP_IdxDelete 111 /* synopsis: key=r[P2@P3] */
#define OP_IdxRowid 112 /* synopsis: r[P2]=rowid */
#define OP_IdxLE 113 /* synopsis: key=r[P3@P4] */
#define OP_IdxGT 114 /* synopsis: key=r[P3@P4] */
#define OP_IdxLT 115 /* synopsis: key=r[P3@P4] */
#define OP_IdxGE 116 /* synopsis: key=r[P3@P4] */
#define OP_Destroy 117
#define OP_Clear 118
#define OP_ResetSorter 119
#define OP_CreateIndex 120 /* synopsis: r[P2]=root iDb=P1 */
#define OP_CreateTable 121 /* synopsis: r[P2]=root iDb=P1 */
#define OP_ParseSchema 122
#define OP_LoadAnalysis 123
#define OP_DropTable 124
#define OP_DropIndex 125
#define OP_DropTrigger 126
#define OP_IntegrityCk 127
#define OP_RowSetAdd 128 /* synopsis: rowset(P1)=r[P2] */
#define OP_RowSetRead 129 /* synopsis: r[P3]=rowset(P1) */
#define OP_RowSetTest 130 /* synopsis: if r[P3] in rowset(P1) goto P2 */
#define OP_Program 131
#define OP_Param 132
#define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
#define OP_FkCounter 134 /* synopsis: fkctr[P1]+=P2 */
#define OP_FkIfZero 135 /* synopsis: if fkctr[P1]==0 goto P2 */
#define OP_MemMax 136 /* synopsis: r[P1]=max(r[P1],r[P2]) */
#define OP_IfPos 137 /* synopsis: if r[P1]>0 goto P2 */
#define OP_IfNeg 138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */
#define OP_IfZero 139 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */
#define OP_AggFinal 140 /* synopsis: accum=r[P1] N=P2 */
#define OP_IncrVacuum 141
#define OP_Expire 142
#define OP_TableLock 143 /* synopsis: iDb=P1 root=P2 write=P3 */
#define OP_VBegin 144
#define OP_VCreate 145
#define OP_VDestroy 146
#define OP_VOpen 147
#define OP_VColumn 148 /* synopsis: r[P3]=vcolumn(P2) */
#define OP_VNext 149
#define OP_VRename 150
#define OP_Pagecount 151
#define OP_MaxPgcnt 152
#define OP_Init 153 /* synopsis: Start at P2 */
#define OP_Noop 154
#define OP_Explain 155
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */
#define OPFLG_IN1 0x0004 /* in1: P1 is an input */
#define OPFLG_IN2 0x0008 /* in2: P2 is an input */
#define OPFLG_IN3 0x0010 /* in3: P3 is an input */
#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\
/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\
/* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\
/* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\
/* 40 */ 0x04, 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00,\
/* 48 */ 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00,\
/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
/* 64 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x4c,\
/* 72 */ 0x4c, 0x02, 0x02, 0x00, 0x05, 0x05, 0x15, 0x15,\
/* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\
/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\
/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\
/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x00,\
/* 112 */ 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00,\
/* 120 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 128 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x02, 0x00, 0x01,\
/* 136 */ 0x08, 0x05, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00,\
/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,\
/* 152 */ 0x02, 0x01, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
|
| ︙ | ︙ | |||
9858 9859 9860 9861 9862 9863 9864 | */ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); /* Create a new pager cache. ** Under memory stress, invoke xStress to try to make pages clean. ** Only clean and unpinned pages can be reclaimed. */ | | | > | > | 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 | */ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); /* Create a new pager cache. ** Under memory stress, invoke xStress to try to make pages clean. ** Only clean and unpinned pages can be reclaimed. */ SQLITE_PRIVATE int sqlite3PcacheOpen( int szPage, /* Size of every page */ int szExtra, /* Extra space associated with each page */ int bPurgeable, /* True if pages are on backing store */ int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ void *pStress, /* Argument to xStress */ PCache *pToInit /* Preallocated space for the PCache */ ); /* Modify the page-size after the cache has been created. */ SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int); /* Return the size in bytes of a PCache object. Used to preallocate ** storage space. */ SQLITE_PRIVATE int sqlite3PcacheSize(void); /* One release per successful fetch. Page is pinned until released. ** Reference counted. */ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ |
| ︙ | ︙ | |||
10377 10378 10379 10380 10381 10382 10383 | #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ /* ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ | | | 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 | #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ /* ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ #define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) /* ** Lookaside malloc is a set of fixed-size buffers that can be used ** to satisfy small transient memory allocation requests for objects ** associated with a particular database connection. The use of ** lookaside malloc provides a significant performance enhancement ** (approx 10%) by avoiding numerous malloc/free requests while parsing |
| ︙ | ︙ | |||
10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 |
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */
int nTotalChange; /* Value returned by sqlite3_total_changes() */
int aLimit[SQLITE_N_LIMIT]; /* Limits */
struct sqlite3InitInfo { /* Information used during initialization */
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
| > | 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 |
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */
int nTotalChange; /* Value returned by sqlite3_total_changes() */
int aLimit[SQLITE_N_LIMIT]; /* Limits */
int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */
struct sqlite3InitInfo { /* Information used during initialization */
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
|
| ︙ | ︙ | |||
11117 11118 11119 11120 11121 11122 11123 |
** The r1 and r2 member variables are only used by the optimized comparison
** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
| | | 11158 11159 11160 11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 |
** The r1 and r2 member variables are only used by the optimized comparison
** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
Mem *aMem; /* Values */
int r1; /* Value to return if (lhs > rhs) */
int r2; /* Value to return if (rhs < lhs) */
};
/*
|
| ︙ | ︙ | |||
12765 12766 12767 12768 12769 12770 12771 | SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); #endif SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); /* ** Routines to read and write variable-length integers. These used to ** be defined locally, but now we use the varint routines in the util.c | | < < < < | < | < < | < < < < < < < < | > | | 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 | SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); #endif SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); /* ** Routines to read and write variable-length integers. These used to ** be defined locally, but now we use the varint routines in the util.c ** file. */ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); SQLITE_PRIVATE int sqlite3VarintLen(u64 v); /* ** The common case is for a varint to be a single byte. They following ** macros handle the common case without a procedure call, but then call ** the procedure for larger varints. */ #define getVarint32(A,B) \ (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B))) #define putVarint32(A,B) \ (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ sqlite3PutVarint((A),(B))) #define getVarint sqlite3GetVarint #define putVarint sqlite3PutVarint SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *); SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); SQLITE_PRIVATE u8 sqlite3HexToInt(int h); SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); #if defined(SQLITE_TEST) SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif |
| ︙ | ︙ | |||
13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 | #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ #define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */ #endif /* _SQLITEINT_H_ */ /************** End of sqliteInt.h *******************************************/ /************** Begin file global.c ******************************************/ /* ** 2008 June 13 ** | > > > > > > > > | 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 | #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ #define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */ /* ** Threading interface */ #if SQLITE_MAX_WORKER_THREADS>0 SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); #endif #endif /* _SQLITEINT_H_ */ /************** End of sqliteInt.h *******************************************/ /************** Begin file global.c ******************************************/ /* ** 2008 June 13 ** |
| ︙ | ︙ | |||
14120 14121 14122 14123 14124 14125 14126 14127 |
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
| > < | 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 |
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
Mem *pOut; /* The return value is stored here */
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
Mem *pMem; /* Memory cell used to store aggregate context */
CollSeq *pColl; /* Collating sequence */
Vdbe *pVdbe; /* The VM that owns this context */
int iOp; /* Instruction number of OP_Function */
int isError; /* Error code returned by the function. */
u8 skipFlag; /* Skip skip accumulator loading if true */
u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
|
| ︙ | ︙ | |||
14272 14273 14274 14275 14276 14277 14278 | #else SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); #endif SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); | | > | | | | | 14307 14308 14309 14310 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 14345 14346 14347 14348 14349 14350 | #else SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); #endif SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p); #define VdbeMemDynamic(X) \ (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) #define VdbeMemReleaseExtern(X) \ if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); SQLITE_PRIVATE const char *sqlite3OpcodeName(int); SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); #else # define sqlite3VdbeEnter(X) |
| ︙ | ︙ | |||
19385 19386 19387 19388 19389 19390 19391 19392 19393 19394 19395 19396 19397 19398 | ** Determine if we are dealing with WinRT, which provides only a subset of ** the full Win32 API. */ #if !defined(SQLITE_OS_WINRT) # define SQLITE_OS_WINRT 0 #endif #endif /* _OS_WIN_H_ */ /************** End of os_win.h **********************************************/ /************** Continuing where we left off in mutex_w32.c ******************/ #endif /* | > > > > > > > > > > | 19421 19422 19423 19424 19425 19426 19427 19428 19429 19430 19431 19432 19433 19434 19435 19436 19437 19438 19439 19440 19441 19442 19443 19444 | ** Determine if we are dealing with WinRT, which provides only a subset of ** the full Win32 API. */ #if !defined(SQLITE_OS_WINRT) # define SQLITE_OS_WINRT 0 #endif /* ** For WinCE, some API function parameters do not appear to be declared as ** volatile. */ #if SQLITE_OS_WINCE # define SQLITE_WIN32_VOLATILE #else # define SQLITE_WIN32_VOLATILE volatile #endif #endif /* _OS_WIN_H_ */ /************** End of os_win.h **********************************************/ /************** Continuing where we left off in mutex_w32.c ******************/ #endif /* |
| ︙ | ︙ | |||
19465 19466 19467 19468 19469 19470 19471 | static int winMutex_isInit = 0; static int winMutex_isNt = -1; /* <0 means "need to query" */ /* As the winMutexInit() and winMutexEnd() functions are called as part ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the ** "interlocked" magic used here is probably not strictly necessary. */ | | | 19511 19512 19513 19514 19515 19516 19517 19518 19519 19520 19521 19522 19523 19524 19525 |
static int winMutex_isInit = 0;
static int winMutex_isNt = -1; /* <0 means "need to query" */
/* As the winMutexInit() and winMutexEnd() functions are called as part
** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
** "interlocked" magic used here is probably not strictly necessary.
*/
static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
|
| ︙ | ︙ | |||
20091 20092 20093 20094 20095 20096 20097 20098 20099 20100 20101 20102 |
** embedded processor.
*/
SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
void *p;
assert( n>0 );
sqlite3_mutex_enter(mem0.mutex);
if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
p = mem0.pScratchFree;
mem0.pScratchFree = mem0.pScratchFree->pNext;
mem0.nScratchFree--;
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
| > < > > | | < | < < < | 20137 20138 20139 20140 20141 20142 20143 20144 20145 20146 20147 20148 20149 20150 20151 20152 20153 20154 20155 20156 20157 20158 20159 20160 20161 20162 20163 20164 |
** embedded processor.
*/
SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
void *p;
assert( n>0 );
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
p = mem0.pScratchFree;
mem0.pScratchFree = mem0.pScratchFree->pNext;
mem0.nScratchFree--;
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
sqlite3_mutex_leave(mem0.mutex);
}else{
sqlite3_mutex_leave(mem0.mutex);
p = sqlite3Malloc(n);
if( sqlite3GlobalConfig.bMemstat && p ){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
sqlite3_mutex_leave(mem0.mutex);
}
sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
}
assert( sqlite3_mutex_notheld(mem0.mutex) );
#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
|
| ︙ | ︙ | |||
20217 20218 20219 20220 20221 20222 20223 20224 20225 20226 20227 20228 20229 20230 20231 20232 20233 |
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
sqlite3GlobalConfig.m.xFree(p);
sqlite3_mutex_leave(mem0.mutex);
}else{
sqlite3GlobalConfig.m.xFree(p);
}
}
/*
** Free memory that might be associated with a particular database
** connection.
*/
SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
assert( db==0 || sqlite3_mutex_held(db->mutex) );
if( p==0 ) return;
if( db ){
if( db->pnBytesFreed ){
| > > > > > > > > | | 20261 20262 20263 20264 20265 20266 20267 20268 20269 20270 20271 20272 20273 20274 20275 20276 20277 20278 20279 20280 20281 20282 20283 20284 20285 20286 20287 20288 20289 20290 20291 20292 20293 |
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
sqlite3GlobalConfig.m.xFree(p);
sqlite3_mutex_leave(mem0.mutex);
}else{
sqlite3GlobalConfig.m.xFree(p);
}
}
/*
** Add the size of memory allocation "p" to the count in
** *db->pnBytesFreed.
*/
static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
*db->pnBytesFreed += sqlite3DbMallocSize(db,p);
}
/*
** Free memory that might be associated with a particular database
** connection.
*/
SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
assert( db==0 || sqlite3_mutex_held(db->mutex) );
if( p==0 ) return;
if( db ){
if( db->pnBytesFreed ){
measureAllocationSize(db, p);
return;
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
#if SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
|
| ︙ | ︙ | |||
20494 20495 20496 20497 20498 20499 20500 20501 20502 20503 20504 20505 20506 20507 20508 20509 20510 20511 20512 20513 20514 20515 20516 20517 20518 20519 20520 |
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite3DbFree(db, *pz);
*pz = z;
}
/*
** This function must be called before exiting any API function (i.e.
** returning control to the user) that has called sqlite3_malloc or
** sqlite3_realloc.
**
** The returned value is normally a copy of the second argument to this
** function. However, if a malloc() failure has occurred since the previous
** invocation SQLITE_NOMEM is returned instead.
**
** If the first argument, db, is not NULL and a malloc() error has occurred,
** then the connection error-code (the value returned by sqlite3_errcode())
** is set to SQLITE_NOMEM.
*/
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
/* If the db handle is not NULL, then we must hold the connection handle
** mutex here. Otherwise the read (and possible write) of db->mallocFailed
** is unsafe, as is the call to sqlite3Error().
*/
assert( !db || sqlite3_mutex_held(db->mutex) );
| > > > > > > > > > | | < < | | 20546 20547 20548 20549 20550 20551 20552 20553 20554 20555 20556 20557 20558 20559 20560 20561 20562 20563 20564 20565 20566 20567 20568 20569 20570 20571 20572 20573 20574 20575 20576 20577 20578 20579 20580 20581 20582 20583 20584 20585 20586 20587 20588 20589 20590 20591 20592 |
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite3DbFree(db, *pz);
*pz = z;
}
/*
** Take actions at the end of an API call to indicate an OOM error
*/
static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
db->mallocFailed = 0;
sqlite3Error(db, SQLITE_NOMEM);
return SQLITE_NOMEM;
}
/*
** This function must be called before exiting any API function (i.e.
** returning control to the user) that has called sqlite3_malloc or
** sqlite3_realloc.
**
** The returned value is normally a copy of the second argument to this
** function. However, if a malloc() failure has occurred since the previous
** invocation SQLITE_NOMEM is returned instead.
**
** If the first argument, db, is not NULL and a malloc() error has occurred,
** then the connection error-code (the value returned by sqlite3_errcode())
** is set to SQLITE_NOMEM.
*/
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
/* If the db handle is not NULL, then we must hold the connection handle
** mutex here. Otherwise the read (and possible write) of db->mallocFailed
** is unsafe, as is the call to sqlite3Error().
*/
assert( !db || sqlite3_mutex_held(db->mutex) );
if( db==0 ) return rc & 0xff;
if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){
return apiOomError(db);
}
return rc & db->errMask;
}
/************** End of malloc.c **********************************************/
/************** Begin file printf.c ******************************************/
/*
** The "printf" code that follows dates from the 1980's. It is in
** the public domain. The original comments are included here for
|
| ︙ | ︙ | |||
21309 21310 21311 21312 21313 21314 21315 | ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** ** This is a helper routine to sqlite3StrAccumAppend() that does special-case ** work (enlarging the buffer) using tail recursion, so that the ** sqlite3StrAccumAppend() routine can use fast calling semantics. */ | | < | | < | > > | 21368 21369 21370 21371 21372 21373 21374 21375 21376 21377 21378 21379 21380 21381 21382 21383 21384 21385 21386 21387 21388 21389 21390 21391 21392 21393 21394 21395 21396 21397 21398 21399 21400 21401 21402 21403 21404 21405 |
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
** This is a helper routine to sqlite3StrAccumAppend() that does special-case
** work (enlarging the buffer) using tail recursion, so that the
** sqlite3StrAccumAppend() routine can use fast calling semantics.
*/
static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
N = sqlite3StrAccumEnlarge(p, N);
if( N>0 ){
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
}
/*
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 );
assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
}else{
assert( p->zText );
p->nChar += N;
memcpy(&p->zText[p->nChar-N], z, N);
}
}
/*
** Append the complete text of zero-terminated string z[] to the p string.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
|
| ︙ | ︙ | |||
21701 21702 21703 21704 21705 21706 21707 21708 21709 21710 21711 21712 21713 21714 |
&GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
sizeof(sqlite3Prng)
);
}
#endif /* SQLITE_OMIT_BUILTIN_TEST */
/************** End of random.c **********************************************/
/************** Begin file utf.c *********************************************/
/*
** 2004 April 13
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 21760 21761 21762 21763 21764 21765 21766 21767 21768 21769 21770 21771 21772 21773 21774 21775 21776 21777 21778 21779 21780 21781 21782 21783 21784 21785 21786 21787 21788 21789 21790 21791 21792 21793 21794 21795 21796 21797 21798 21799 21800 21801 21802 21803 21804 21805 21806 21807 21808 21809 21810 21811 21812 21813 21814 21815 21816 21817 21818 21819 21820 21821 21822 21823 21824 21825 21826 21827 21828 21829 21830 21831 21832 21833 21834 21835 21836 21837 21838 21839 21840 21841 21842 21843 21844 21845 21846 21847 21848 21849 21850 21851 21852 21853 21854 21855 21856 21857 21858 21859 21860 21861 21862 21863 21864 21865 21866 21867 21868 21869 21870 21871 21872 21873 21874 21875 21876 21877 21878 21879 21880 21881 21882 21883 21884 21885 21886 21887 21888 21889 21890 21891 21892 21893 21894 21895 21896 21897 21898 21899 21900 21901 21902 21903 21904 21905 21906 21907 21908 21909 21910 21911 21912 21913 21914 21915 21916 21917 21918 21919 21920 21921 21922 21923 21924 21925 21926 21927 21928 21929 21930 21931 21932 21933 21934 21935 21936 21937 21938 21939 21940 21941 21942 21943 21944 21945 21946 21947 21948 21949 21950 21951 21952 21953 21954 21955 21956 21957 21958 21959 21960 21961 21962 21963 21964 21965 21966 21967 21968 21969 21970 21971 21972 21973 21974 21975 21976 21977 21978 21979 21980 21981 21982 21983 21984 21985 21986 21987 21988 21989 21990 21991 21992 21993 21994 21995 21996 21997 21998 21999 22000 22001 22002 22003 22004 22005 22006 22007 22008 22009 22010 22011 22012 22013 22014 22015 22016 22017 22018 22019 22020 22021 22022 22023 22024 22025 22026 22027 22028 22029 22030 22031 22032 22033 22034 22035 22036 22037 |
&GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
sizeof(sqlite3Prng)
);
}
#endif /* SQLITE_OMIT_BUILTIN_TEST */
/************** End of random.c **********************************************/
/************** Begin file threads.c *****************************************/
/*
** 2012 July 21
**
** 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 presents a simple cross-platform threading interface for
** use internally by SQLite.
**
** A "thread" can be created using sqlite3ThreadCreate(). This thread
** runs independently of its creator until it is joined using
** sqlite3ThreadJoin(), at which point it terminates.
**
** Threads do not have to be real. It could be that the work of the
** "thread" is done by the main thread at either the sqlite3ThreadCreate()
** or sqlite3ThreadJoin() call. This is, in fact, what happens in
** single threaded systems. Nothing in SQLite requires multiple threads.
** This interface exists so that applications that want to take advantage
** of multiple cores can do so, while also allowing applications to stay
** single-threaded if desired.
*/
#if SQLITE_MAX_WORKER_THREADS>0
/********************************* Unix Pthreads ****************************/
#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
/* #include <pthread.h> */
/* A running thread */
struct SQLiteThread {
pthread_t tid; /* Thread ID */
int done; /* Set to true when thread finishes */
void *pOut; /* Result returned by the thread */
void *(*xTask)(void*); /* The thread routine */
void *pIn; /* Argument to the thread */
};
/* Create a new thread */
SQLITE_PRIVATE int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
int rc;
assert( ppThread!=0 );
assert( xTask!=0 );
/* This routine is never used in single-threaded mode */
assert( sqlite3GlobalConfig.bCoreMutex!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
memset(p, 0, sizeof(*p));
p->xTask = xTask;
p->pIn = pIn;
if( sqlite3FaultSim(200) ){
rc = 1;
}else{
rc = pthread_create(&p->tid, 0, xTask, pIn);
}
if( rc ){
p->done = 1;
p->pOut = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
int rc;
assert( ppOut!=0 );
if( NEVER(p==0) ) return SQLITE_NOMEM;
if( p->done ){
*ppOut = p->pOut;
rc = SQLITE_OK;
}else{
rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK;
}
sqlite3_free(p);
return rc;
}
#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
/******************************** End Unix Pthreads *************************/
/********************************* Win32 Threads ****************************/
#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <process.h>
/* A running thread */
struct SQLiteThread {
uintptr_t tid; /* The thread handle */
unsigned id; /* The thread identifier */
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
void *pResult; /* Result of xTask */
};
/* Thread procedure Win32 compatibility shim */
static unsigned __stdcall sqlite3ThreadProc(
void *pArg /* IN: Pointer to the SQLiteThread structure */
){
SQLiteThread *p = (SQLiteThread *)pArg;
assert( p!=0 );
#if 0
/*
** This assert appears to trigger spuriously on certain
** versions of Windows, possibly due to _beginthreadex()
** and/or CreateThread() not fully setting their thread
** ID parameter before starting the thread.
*/
assert( p->id==GetCurrentThreadId() );
#endif
assert( p->xTask!=0 );
p->pResult = p->xTask(p->pIn);
_endthreadex(0);
return 0; /* NOT REACHED */
}
/* Create a new thread */
SQLITE_PRIVATE int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( sqlite3GlobalConfig.bCoreMutex==0 ){
memset(p, 0, sizeof(*p));
}else{
p->xTask = xTask;
p->pIn = pIn;
p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
if( p->tid==0 ){
memset(p, 0, sizeof(*p));
}
}
if( p->xTask==0 ){
p->id = GetCurrentThreadId();
p->pResult = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */
/* Get the results of the thread */
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
DWORD rc;
BOOL bRc;
assert( ppOut!=0 );
if( NEVER(p==0) ) return SQLITE_NOMEM;
if( p->xTask==0 ){
assert( p->id==GetCurrentThreadId() );
rc = WAIT_OBJECT_0;
assert( p->tid==0 );
}else{
assert( p->id!=0 && p->id!=GetCurrentThreadId() );
rc = sqlite3Win32Wait((HANDLE)p->tid);
assert( rc!=WAIT_IO_COMPLETION );
bRc = CloseHandle((HANDLE)p->tid);
assert( bRc );
}
if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
sqlite3_free(p);
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}
#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
/******************************** End Win32 Threads *************************/
/********************************* Single-Threaded **************************/
#ifndef SQLITE_THREADS_IMPLEMENTED
/*
** This implementation does not actually create a new thread. It does the
** work of the thread in the main thread, when either the thread is created
** or when it is joined
*/
/* A running thread */
struct SQLiteThread {
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
void *pResult; /* Result of xTask */
};
/* Create a new thread */
SQLITE_PRIVATE int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
p->xTask = xTask;
p->pIn = pIn;
}else{
p->xTask = 0;
p->pResult = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
if( NEVER(p==0) ) return SQLITE_NOMEM;
if( p->xTask ){
*ppOut = p->xTask(p->pIn);
}else{
*ppOut = p->pResult;
}
sqlite3_free(p);
#if defined(SQLITE_TEST)
{
void *pTstAlloc = sqlite3Malloc(10);
if (!pTstAlloc) return SQLITE_NOMEM;
sqlite3_free(pTstAlloc);
}
#endif
return SQLITE_OK;
}
#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */
/****************************** End Single-Threaded *************************/
#endif /* SQLITE_MAX_WORKER_THREADS>0 */
/************** End of threads.c *********************************************/
/************** Begin file utf.c *********************************************/
/*
** 2004 April 13
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
21901 21902 21903 21904 21905 21906 21907 | #ifndef SQLITE_OMIT_UTF16 /* ** This routine transforms the internal text encoding used by pMem to ** desiredEnc. It is an error if the string is already of the desired ** encoding, or if *pMem does not contain a string value. */ | | | 22224 22225 22226 22227 22228 22229 22230 22231 22232 22233 22234 22235 22236 22237 22238 |
#ifndef SQLITE_OMIT_UTF16
/*
** This routine transforms the internal text encoding used by pMem to
** desiredEnc. It is an error if the string is already of the desired
** encoding, or if *pMem does not contain a string value.
*/
SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
int len; /* Maximum length of output string in bytes */
unsigned char *zOut; /* Output buffer */
unsigned char *zIn; /* Input iterator */
unsigned char *zTerm; /* End of input */
unsigned char *z; /* Output iterator */
unsigned int c;
|
| ︙ | ︙ | |||
22343 22344 22345 22346 22347 22348 22349 22350 22351 22352 22353 22354 22355 22356 |
*/
SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
const char *z2 = z;
if( z==0 ) return 0;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
| > > > > > > > > > | 22666 22667 22668 22669 22670 22671 22672 22673 22674 22675 22676 22677 22678 22679 22680 22681 22682 22683 22684 22685 22686 22687 22688 |
*/
SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
const char *z2 = z;
if( z==0 ) return 0;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Set the current error code to err_code and clear any prior error message.
*/
SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
assert( db!=0 );
db->errCode = err_code;
if( db->pErr ) sqlite3ValueSetNull(db->pErr);
}
/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
|
| ︙ | ︙ | |||
22365 22366 22367 22368 22369 22370 22371 | ** zFormat and any string tokens that follow it are assumed to be ** encoded in UTF-8. ** ** To clear the most recent error for sqlite handle "db", sqlite3Error ** should be called with err_code set to SQLITE_OK and zFormat set ** to NULL. */ | | > > | < < | | | | 22697 22698 22699 22700 22701 22702 22703 22704 22705 22706 22707 22708 22709 22710 22711 22712 22713 22714 22715 22716 22717 22718 22719 22720 22721 22722 22723 22724 22725 22726 22727 22728 22729 22730 22731 22732 22733 22734 22735 22736 22737 22738 22739 22740 22741 |
** zFormat and any string tokens that follow it are assumed to be
** encoded in UTF-8.
**
** To clear the most recent error for sqlite handle "db", sqlite3Error
** should be called with err_code set to SQLITE_OK and zFormat set
** to NULL.
*/
SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
assert( db!=0 );
db->errCode = err_code;
if( zFormat==0 ){
sqlite3Error(db, err_code);
}else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
char *z;
va_list ap;
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
}
}
/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
** The following formatting characters are allowed:
**
** %s Insert a string
** %z A string that should be freed after use
** %d Insert an integer
** %T Insert a token
** %S Insert the first element of a SrcList
**
** This function should be used to report any error that occurs while
** compiling an SQL statement (i.e. within sqlite3_prepare()). The
** last thing the sqlite3_prepare() function does is copy the error
** stored by this function into the database handle using sqlite3Error().
** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used
** during statement execution (sqlite3_step() etc.).
*/
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
char *zMsg;
va_list ap;
sqlite3 *db = pParse->db;
va_start(ap, zFormat);
zMsg = sqlite3VMPrintf(db, zFormat, ap);
|
| ︙ | ︙ | |||
22932 22933 22934 22935 22936 22937 22938 | ** of bytes written is returned. ** ** A variable-length integer consists of the lower 7 bits of each byte ** for all bytes that have the 8th bit set and one byte with the 8th ** bit clear. Except, if we get to the 9th byte, it stores the full ** 8 bits and is the last byte. */ | | | 23264 23265 23266 23267 23268 23269 23270 23271 23272 23273 23274 23275 23276 23277 23278 |
** of bytes written is returned.
**
** A variable-length integer consists of the lower 7 bits of each byte
** for all bytes that have the 8th bit set and one byte with the 8th
** bit clear. Except, if we get to the 9th byte, it stores the full
** 8 bits and is the last byte.
*/
static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){
int i, j, n;
u8 buf[10];
if( v & (((u64)0xff000000)<<32) ){
p[8] = (u8)v;
v >>= 8;
for(i=7; i>=0; i--){
p[i] = (u8)((v & 0x7f) | 0x80);
|
| ︙ | ︙ | |||
22956 22957 22958 22959 22960 22961 22962 |
buf[0] &= 0x7f;
assert( n<=9 );
for(i=0, j=n-1; j>=0; j--, i++){
p[i] = buf[j];
}
return n;
}
| < < < < < < < < < | < | | < | | | | | 23288 23289 23290 23291 23292 23293 23294 23295 23296 23297 23298 23299 23300 23301 23302 23303 23304 23305 23306 23307 23308 23309 23310 23311 23312 |
buf[0] &= 0x7f;
assert( n<=9 );
for(i=0, j=n-1; j>=0; j--, i++){
p[i] = buf[j];
}
return n;
}
SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
if( v<=0x7f ){
p[0] = v&0x7f;
return 1;
}
if( v<=0x3fff ){
p[0] = ((v>>7)&0x7f)|0x80;
p[1] = v&0x7f;
return 2;
}
return putVarint64(p,v);
}
/*
** Bitmasks used by sqlite3GetVarint(). These precomputed constants
** are defined here rather than simply putting the constant expressions
** inline in order to work around bugs in the RVT compiler.
**
|
| ︙ | ︙ | |||
23653 23654 23655 23656 23657 23658 23659 | } pH->count = 0; } /* ** The hashing function. */ | | | | | < | 23974 23975 23976 23977 23978 23979 23980 23981 23982 23983 23984 23985 23986 23987 23988 23989 23990 23991 23992 |
}
pH->count = 0;
}
/*
** The hashing function.
*/
static unsigned int strHash(const char *z){
unsigned int h = 0;
unsigned char c;
while( (c = (unsigned char)*z++)!=0 ){
h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
}
return h;
}
/* Link pNew element into the hash table pH. If pEntry!=0 then also
** insert pNew into the pEntry hash bucket.
|
| ︙ | ︙ | |||
23730 23731 23732 23733 23734 23735 23736 |
if( new_ht==0 ) return 0;
sqlite3_free(pH->ht);
pH->ht = new_ht;
pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
memset(new_ht, 0, new_size*sizeof(struct _ht));
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
| | | | | < | > | > > > > | > | | 24050 24051 24052 24053 24054 24055 24056 24057 24058 24059 24060 24061 24062 24063 24064 24065 24066 24067 24068 24069 24070 24071 24072 24073 24074 24075 24076 24077 24078 24079 24080 24081 24082 24083 24084 24085 24086 24087 24088 24089 24090 24091 24092 24093 24094 24095 24096 24097 24098 |
if( new_ht==0 ) return 0;
sqlite3_free(pH->ht);
pH->ht = new_ht;
pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
memset(new_ht, 0, new_size*sizeof(struct _ht));
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
unsigned int h = strHash(elem->pKey) % new_size;
next_elem = elem->next;
insertElement(pH, &new_ht[h], elem);
}
return 1;
}
/* This function (for internal use only) locates an element in an
** hash table that matches the given key. The hash for this key is
** also computed and returned in the *pH parameter.
*/
static HashElem *findElementWithHash(
const Hash *pH, /* The pH to be searched */
const char *pKey, /* The key we are searching for */
unsigned int *pHash /* Write the hash value here */
){
HashElem *elem; /* Used to loop thru the element list */
int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
if( pH->ht ){
struct _ht *pEntry;
h = strHash(pKey) % pH->htsize;
pEntry = &pH->ht[h];
elem = pEntry->chain;
count = pEntry->count;
}else{
h = 0;
elem = pH->first;
count = pH->count;
}
*pHash = h;
while( count-- ){
assert( elem!=0 );
if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
return elem;
}
elem = elem->next;
}
return 0;
}
|
| ︙ | ︙ | |||
23802 23803 23804 23805 23806 23807 23808 |
assert( pH->first==0 );
assert( pH->count==0 );
sqlite3HashClear(pH);
}
}
/* Attempt to locate an element of the hash table pH with a key
| | | < < < < < < | | | < < < < < < | < < | < < < | < | 24127 24128 24129 24130 24131 24132 24133 24134 24135 24136 24137 24138 24139 24140 24141 24142 24143 24144 24145 24146 24147 24148 24149 24150 24151 24152 24153 24154 24155 24156 24157 24158 24159 24160 24161 24162 24163 24164 24165 24166 24167 24168 24169 24170 24171 24172 24173 24174 24175 24176 24177 24178 24179 24180 24181 24182 24183 24184 24185 24186 24187 24188 24189 24190 24191 24192 24193 24194 24195 24196 24197 24198 |
assert( pH->first==0 );
assert( pH->count==0 );
sqlite3HashClear(pH);
}
}
/* Attempt to locate an element of the hash table pH with a key
** that matches pKey. Return the data for this element if it is
** found, or NULL if there is no match.
*/
SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
HashElem *elem; /* The element that matches key */
unsigned int h; /* A hash on key */
assert( pH!=0 );
assert( pKey!=0 );
elem = findElementWithHash(pH, pKey, &h);
return elem ? elem->data : 0;
}
/* Insert an element into the hash table pH. The key is pKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
** element is created and NULL is returned.
**
** If another element already exists with the same key, then the
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance. If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
unsigned int h; /* the hash of the key modulo hash table size */
HashElem *elem; /* Used to loop thru the element list */
HashElem *new_elem; /* New element added to the pH */
assert( pH!=0 );
assert( pKey!=0 );
elem = findElementWithHash(pH,pKey,&h);
if( elem ){
void *old_data = elem->data;
if( data==0 ){
removeElementGivenHash(pH,elem,h);
}else{
elem->data = data;
elem->pKey = pKey;
}
return old_data;
}
if( data==0 ) return 0;
new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
if( new_elem==0 ) return data;
new_elem->pKey = pKey;
new_elem->data = data;
pH->count++;
if( pH->count>=10 && pH->count > 2*pH->htsize ){
if( rehash(pH, pH->count*2) ){
assert( pH->htsize>0 );
h = strHash(pKey) % pH->htsize;
}
}
insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem);
return 0;
}
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodec.awk script for details. */
|
| ︙ | ︙ | |||
23932 23933 23934 23935 23936 23937 23938 |
/* 33 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
/* 34 */ "SCopy" OpHelp("r[P2]=r[P1]"),
/* 35 */ "ResultRow" OpHelp("output=r[P1@P2]"),
/* 36 */ "CollSeq" OpHelp(""),
/* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
/* 38 */ "MustBeInt" OpHelp(""),
/* 39 */ "RealAffinity" OpHelp(""),
| > | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | < < > > | < < | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < > > | | | | | | | | | < < < < < | | | | | | | | | | | | 24239 24240 24241 24242 24243 24244 24245 24246 24247 24248 24249 24250 24251 24252 24253 24254 24255 24256 24257 24258 24259 24260 24261 24262 24263 24264 24265 24266 24267 24268 24269 24270 24271 24272 24273 24274 24275 24276 24277 24278 24279 24280 24281 24282 24283 24284 24285 24286 24287 24288 24289 24290 24291 24292 24293 24294 24295 24296 24297 24298 24299 24300 24301 24302 24303 24304 24305 24306 24307 24308 24309 24310 24311 24312 24313 24314 24315 24316 24317 24318 24319 24320 24321 24322 24323 24324 24325 24326 24327 24328 24329 24330 24331 24332 24333 24334 24335 24336 24337 24338 24339 24340 24341 24342 24343 24344 24345 24346 24347 24348 24349 24350 24351 24352 24353 24354 24355 24356 24357 24358 24359 24360 24361 24362 24363 24364 24365 24366 24367 24368 |
/* 33 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
/* 34 */ "SCopy" OpHelp("r[P2]=r[P1]"),
/* 35 */ "ResultRow" OpHelp("output=r[P1@P2]"),
/* 36 */ "CollSeq" OpHelp(""),
/* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
/* 38 */ "MustBeInt" OpHelp(""),
/* 39 */ "RealAffinity" OpHelp(""),
/* 40 */ "Cast" OpHelp("affinity(r[P1])"),
/* 41 */ "Permutation" OpHelp(""),
/* 42 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
/* 43 */ "Jump" OpHelp(""),
/* 44 */ "Once" OpHelp(""),
/* 45 */ "If" OpHelp(""),
/* 46 */ "IfNot" OpHelp(""),
/* 47 */ "Column" OpHelp("r[P3]=PX"),
/* 48 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
/* 49 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
/* 50 */ "Count" OpHelp("r[P2]=count()"),
/* 51 */ "ReadCookie" OpHelp(""),
/* 52 */ "SetCookie" OpHelp(""),
/* 53 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
/* 54 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
/* 55 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
/* 56 */ "OpenAutoindex" OpHelp("nColumn=P2"),
/* 57 */ "OpenEphemeral" OpHelp("nColumn=P2"),
/* 58 */ "SorterOpen" OpHelp(""),
/* 59 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
/* 60 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
/* 61 */ "Close" OpHelp(""),
/* 62 */ "SeekLT" OpHelp("key=r[P3@P4]"),
/* 63 */ "SeekLE" OpHelp("key=r[P3@P4]"),
/* 64 */ "SeekGE" OpHelp("key=r[P3@P4]"),
/* 65 */ "SeekGT" OpHelp("key=r[P3@P4]"),
/* 66 */ "Seek" OpHelp("intkey=r[P2]"),
/* 67 */ "NoConflict" OpHelp("key=r[P3@P4]"),
/* 68 */ "NotFound" OpHelp("key=r[P3@P4]"),
/* 69 */ "Found" OpHelp("key=r[P3@P4]"),
/* 70 */ "NotExists" OpHelp("intkey=r[P3]"),
/* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
/* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
/* 73 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
/* 74 */ "NewRowid" OpHelp("r[P2]=rowid"),
/* 75 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
/* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
/* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
/* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
/* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
/* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
/* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
/* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"),
/* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"),
/* 84 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
/* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
/* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
/* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
/* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
/* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
/* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
/* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
/* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
/* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
/* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
/* 95 */ "Delete" OpHelp(""),
/* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
/* 97 */ "String8" OpHelp("r[P2]='P4'"),
/* 98 */ "ResetCount" OpHelp(""),
/* 99 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
/* 100 */ "SorterData" OpHelp("r[P2]=data"),
/* 101 */ "RowKey" OpHelp("r[P2]=key"),
/* 102 */ "RowData" OpHelp("r[P2]=data"),
/* 103 */ "Rowid" OpHelp("r[P2]=rowid"),
/* 104 */ "NullRow" OpHelp(""),
/* 105 */ "Last" OpHelp(""),
/* 106 */ "SorterSort" OpHelp(""),
/* 107 */ "Sort" OpHelp(""),
/* 108 */ "Rewind" OpHelp(""),
/* 109 */ "SorterInsert" OpHelp(""),
/* 110 */ "IdxInsert" OpHelp("key=r[P2]"),
/* 111 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
/* 112 */ "IdxRowid" OpHelp("r[P2]=rowid"),
/* 113 */ "IdxLE" OpHelp("key=r[P3@P4]"),
/* 114 */ "IdxGT" OpHelp("key=r[P3@P4]"),
/* 115 */ "IdxLT" OpHelp("key=r[P3@P4]"),
/* 116 */ "IdxGE" OpHelp("key=r[P3@P4]"),
/* 117 */ "Destroy" OpHelp(""),
/* 118 */ "Clear" OpHelp(""),
/* 119 */ "ResetSorter" OpHelp(""),
/* 120 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
/* 121 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
/* 122 */ "ParseSchema" OpHelp(""),
/* 123 */ "LoadAnalysis" OpHelp(""),
/* 124 */ "DropTable" OpHelp(""),
/* 125 */ "DropIndex" OpHelp(""),
/* 126 */ "DropTrigger" OpHelp(""),
/* 127 */ "IntegrityCk" OpHelp(""),
/* 128 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
/* 129 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
/* 130 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
/* 131 */ "Program" OpHelp(""),
/* 132 */ "Param" OpHelp(""),
/* 133 */ "Real" OpHelp("r[P2]=P4"),
/* 134 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
/* 135 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
/* 136 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
/* 137 */ "IfPos" OpHelp("if r[P1]>0 goto P2"),
/* 138 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"),
/* 139 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
/* 140 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
/* 141 */ "IncrVacuum" OpHelp(""),
/* 142 */ "Expire" OpHelp(""),
/* 143 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
/* 144 */ "VBegin" OpHelp(""),
/* 145 */ "VCreate" OpHelp(""),
/* 146 */ "VDestroy" OpHelp(""),
/* 147 */ "VOpen" OpHelp(""),
/* 148 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
/* 149 */ "VNext" OpHelp(""),
/* 150 */ "VRename" OpHelp(""),
/* 151 */ "Pagecount" OpHelp(""),
/* 152 */ "MaxPgcnt" OpHelp(""),
/* 153 */ "Init" OpHelp("Start at P2"),
/* 154 */ "Noop" OpHelp(""),
/* 155 */ "Explain" OpHelp(""),
};
return azName[i];
}
#endif
/************** End of opcodes.c *********************************************/
/************** Begin file os_unix.c *****************************************/
|
| ︙ | ︙ | |||
30152 30153 30154 30155 30156 30157 30158 |
){
int rc = SQLITE_OK;
UNUSED_PARAMETER(NotUsed);
SimulateIOError(return SQLITE_IOERR_DELETE);
if( osUnlink(zPath)==(-1) ){
if( errno==ENOENT
#if OS_VXWORKS
| | | 30456 30457 30458 30459 30460 30461 30462 30463 30464 30465 30466 30467 30468 30469 30470 |
){
int rc = SQLITE_OK;
UNUSED_PARAMETER(NotUsed);
SimulateIOError(return SQLITE_IOERR_DELETE);
if( osUnlink(zPath)==(-1) ){
if( errno==ENOENT
#if OS_VXWORKS
|| osAccess(zPath,0)!=0
#endif
){
rc = SQLITE_IOERR_DELETE_NOENT;
}else{
rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
}
return rc;
|
| ︙ | ︙ | |||
32389 32390 32391 32392 32393 32394 32395 | ** 1: Operating system is Win9x. ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST | | | | 32693 32694 32695 32696 32697 32698 32699 32700 32701 32702 32703 32704 32705 32706 32707 32708 32709 | ** 1: Operating system is Win9x. ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; #else static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; #endif #ifndef SYSCALL # define SYSCALL sqlite3_syscall_ptr #endif /* |
| ︙ | ︙ | |||
32922 32923 32924 32925 32926 32927 32928 |
#else
{ "WaitForSingleObject", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[63].pCurrent)
| < < < < | 33226 33227 33228 33229 33230 33231 33232 33233 33234 33235 33236 33237 33238 33239 33240 |
#else
{ "WaitForSingleObject", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[63].pCurrent)
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
#else
|
| ︙ | ︙ | |||
33034 33035 33036 33037 33038 33039 33040 |
#if defined(InterlockedCompareExchange)
{ "InterlockedCompareExchange", (SYSCALL)0, 0 },
#define osInterlockedCompareExchange InterlockedCompareExchange
#else
{ "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
| | | | 33334 33335 33336 33337 33338 33339 33340 33341 33342 33343 33344 33345 33346 33347 33348 33349 |
#if defined(InterlockedCompareExchange)
{ "InterlockedCompareExchange", (SYSCALL)0, 0 },
#define osInterlockedCompareExchange InterlockedCompareExchange
#else
{ "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
#endif /* defined(InterlockedCompareExchange) */
}; /* End of the overrideable system calls */
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes. Return SQLITE_OK opon successfully updating the
|
| ︙ | ︙ | |||
33268 33269 33270 33271 33272 33273 33274 33275 33276 33277 33278 33279 33280 33281 | } assert( sleepObj!=NULL ); osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); #else osSleep(milliseconds); #endif } /* ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, ** or WinCE. Return false (zero) for Win95, Win98, or WinME. ** ** Here is an interesting observation: Win95, Win98, and WinME lack ** the LockFileEx() API. But we can still statically link against that | > > > > > > > | 33568 33569 33570 33571 33572 33573 33574 33575 33576 33577 33578 33579 33580 33581 33582 33583 33584 33585 33586 33587 33588 |
}
assert( sleepObj!=NULL );
osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
#else
osSleep(milliseconds);
#endif
}
SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
DWORD rc;
while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
TRUE))==WAIT_IO_COMPLETION ){}
return rc;
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
|
| ︙ | ︙ | |||
37982 37983 37984 37985 37986 37987 37988 37989 |
for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){
assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) );
}
return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0);
}
#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */
/*
| > > > > > > > | > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | < < < < < < < | | | | | | | | | | | | | | | | | | > < | | | > > > > > > > > > > > | 38289 38290 38291 38292 38293 38294 38295 38296 38297 38298 38299 38300 38301 38302 38303 38304 38305 38306 38307 38308 38309 38310 38311 38312 38313 38314 38315 38316 38317 38318 38319 38320 38321 38322 38323 38324 38325 38326 38327 38328 38329 38330 38331 38332 38333 38334 38335 38336 38337 38338 38339 38340 38341 38342 38343 38344 38345 38346 38347 38348 38349 38350 38351 38352 38353 38354 38355 38356 38357 38358 38359 38360 38361 38362 38363 38364 38365 38366 38367 38368 38369 38370 38371 38372 38373 38374 38375 38376 38377 38378 38379 38380 38381 38382 38383 38384 38385 38386 38387 38388 38389 38390 38391 38392 |
for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){
assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) );
}
return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0);
}
#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */
/* Allowed values for second argument to pcacheManageDirtyList() */
#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */
#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */
#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */
/*
** Manage pPage's participation on the dirty list. Bits of the addRemove
** argument determines what operation to do. The 0x01 bit means first
** remove pPage from the dirty list. The 0x02 means add pPage back to
** the dirty list. Doing both moves pPage to the front of the dirty list.
*/
static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
PCache *p = pPage->pCache;
if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
assert( pPage->pDirtyPrev || pPage==p->pDirty );
/* Update the PCache1.pSynced variable if necessary. */
if( p->pSynced==pPage ){
PgHdr *pSynced = pPage->pDirtyPrev;
while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
pSynced = pSynced->pDirtyPrev;
}
p->pSynced = pSynced;
}
if( pPage->pDirtyNext ){
pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
}else{
assert( pPage==p->pDirtyTail );
p->pDirtyTail = pPage->pDirtyPrev;
}
if( pPage->pDirtyPrev ){
pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
}else{
assert( pPage==p->pDirty );
p->pDirty = pPage->pDirtyNext;
if( p->pDirty==0 && p->bPurgeable ){
assert( p->eCreate==1 );
p->eCreate = 2;
}
}
pPage->pDirtyNext = 0;
pPage->pDirtyPrev = 0;
expensive_assert( pcacheCheckSynced(p) );
}
if( addRemove & PCACHE_DIRTYLIST_ADD ){
assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
pPage->pDirtyNext = p->pDirty;
if( pPage->pDirtyNext ){
assert( pPage->pDirtyNext->pDirtyPrev==0 );
pPage->pDirtyNext->pDirtyPrev = pPage;
}else if( p->bPurgeable ){
assert( p->eCreate==2 );
p->eCreate = 1;
}
p->pDirty = pPage;
if( !p->pDirtyTail ){
p->pDirtyTail = pPage;
}
if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
p->pSynced = pPage;
}
expensive_assert( pcacheCheckSynced(p) );
}
}
/*
** Wrapper around the pluggable caches xUnpin method. If the cache is
** being used for an in-memory database, this function is a no-op.
*/
static void pcacheUnpin(PgHdr *p){
if( p->pCache->bPurgeable ){
if( p->pgno==1 ){
p->pCache->pPage1 = 0;
}
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
}
}
/*
** Compute the number of pages of cache requested.
*/
static int numberOfCachePages(PCache *p){
if( p->szCache>=0 ){
return p->szCache;
}else{
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
/*************************************************** General Interfaces ******
**
** Initialize and shutdown the page cache subsystem. Neither of these
** functions are threadsafe.
|
| ︙ | ︙ | |||
38095 38096 38097 38098 38099 38100 38101 | /* ** Create a new PCache object. Storage space to hold the object ** has already been allocated and is passed in as the p pointer. ** The caller discovers how much space needs to be allocated by ** calling sqlite3PcacheSize(). */ | | | > | > > > > > > > | | > | < | | < < < < < < | < < | | < > > > > > > > > > > > > > > > > > > > > > | | < < < > | < < < < < < < < < < < < < < < < < < < | > > | | > | > > > > > > > > > > > > > > > > | > > | | | | | | | | | | | | | | | | | | | | | | | | | | < | > | > > > > > > > > > > > > > > > | | < | | | | | | | | > | | > > > > > > > > > > > | | > > | > > | | | | | | | | < | < | < | < | < | < | | | | | | 38414 38415 38416 38417 38418 38419 38420 38421 38422 38423 38424 38425 38426 38427 38428 38429 38430 38431 38432 38433 38434 38435 38436 38437 38438 38439 38440 38441 38442 38443 38444 38445 38446 38447 38448 38449 38450 38451 38452 38453 38454 38455 38456 38457 38458 38459 38460 38461 38462 38463 38464 38465 38466 38467 38468 38469 38470 38471 38472 38473 38474 38475 38476 38477 38478 38479 38480 38481 38482 38483 38484 38485 38486 38487 38488 38489 38490 38491 38492 38493 38494 38495 38496 38497 38498 38499 38500 38501 38502 38503 38504 38505 38506 38507 38508 38509 38510 38511 38512 38513 38514 38515 38516 38517 38518 38519 38520 38521 38522 38523 38524 38525 38526 38527 38528 38529 38530 38531 38532 38533 38534 38535 38536 38537 38538 38539 38540 38541 38542 38543 38544 38545 38546 38547 38548 38549 38550 38551 38552 38553 38554 38555 38556 38557 38558 38559 38560 38561 38562 38563 38564 38565 38566 38567 38568 38569 38570 38571 38572 38573 38574 38575 38576 38577 38578 38579 38580 38581 38582 38583 38584 38585 38586 38587 38588 38589 38590 38591 38592 38593 38594 38595 38596 38597 38598 38599 38600 38601 38602 38603 38604 38605 38606 38607 38608 38609 38610 38611 38612 38613 38614 38615 38616 38617 38618 38619 38620 38621 38622 38623 38624 38625 38626 38627 38628 38629 38630 38631 38632 38633 38634 38635 38636 38637 38638 38639 38640 38641 38642 38643 38644 38645 38646 38647 38648 38649 38650 38651 38652 38653 38654 38655 38656 38657 38658 38659 38660 38661 38662 38663 38664 38665 38666 38667 38668 38669 38670 38671 38672 38673 38674 38675 38676 38677 38678 38679 38680 38681 38682 38683 38684 38685 38686 38687 38688 38689 38690 38691 |
/*
** Create a new PCache object. Storage space to hold the object
** has already been allocated and is passed in as the p pointer.
** The caller discovers how much space needs to be allocated by
** calling sqlite3PcacheSize().
*/
SQLITE_PRIVATE int sqlite3PcacheOpen(
int szPage, /* Size of every page */
int szExtra, /* Extra space associated with each page */
int bPurgeable, /* True if pages are on backing store */
int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
void *pStress, /* Argument to xStress */
PCache *p /* Preallocated space for the PCache */
){
memset(p, 0, sizeof(PCache));
p->szPage = 1;
p->szExtra = szExtra;
p->bPurgeable = bPurgeable;
p->eCreate = 2;
p->xStress = xStress;
p->pStress = pStress;
p->szCache = 100;
return sqlite3PcacheSetPageSize(p, szPage);
}
/*
** Change the page size for PCache object. The caller must ensure that there
** are no outstanding page references when this function is called.
*/
SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
assert( pCache->nRef==0 && pCache->pDirty==0 );
if( pCache->szPage ){
sqlite3_pcache *pNew;
pNew = sqlite3GlobalConfig.pcache2.xCreate(
szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
);
if( pNew==0 ) return SQLITE_NOMEM;
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
if( pCache->pCache ){
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
pCache->pCache = pNew;
pCache->pPage1 = 0;
pCache->szPage = szPage;
}
return SQLITE_OK;
}
/*
** Try to obtain a page from the cache.
**
** This routine returns a pointer to an sqlite3_pcache_page object if
** such an object is already in cache, or if a new one is created.
** This routine returns a NULL pointer if the object was not in cache
** and could not be created.
**
** The createFlags should be 0 to check for existing pages and should
** be 3 (not 1, but 3) to try to create a new page.
**
** If the createFlag is 0, then NULL is always returned if the page
** is not already in the cache. If createFlag is 1, then a new page
** is created only if that can be done without spilling dirty pages
** and without exceeding the cache size limit.
**
** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
** initialize the sqlite3_pcache_page object and convert it into a
** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
** routines are split this way for performance reasons. When separated
** they can both (usually) operate without having to push values to
** the stack on entry and pop them back off on exit, which saves a
** lot of pushing and popping.
*/
SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
PCache *pCache, /* Obtain the page from this cache */
Pgno pgno, /* Page number to obtain */
int createFlag /* If true, create page if it does not exist already */
){
int eCreate;
assert( pCache!=0 );
assert( pCache->pCache!=0 );
assert( createFlag==3 || createFlag==0 );
assert( pgno>0 );
/* eCreate defines what to do if the page does not exist.
** 0 Do not allocate a new page. (createFlag==0)
** 1 Allocate a new page if doing so is inexpensive.
** (createFlag==1 AND bPurgeable AND pDirty)
** 2 Allocate a new page even it doing so is difficult.
** (createFlag==1 AND !(bPurgeable AND pDirty)
*/
eCreate = createFlag & pCache->eCreate;
assert( eCreate==0 || eCreate==1 || eCreate==2 );
assert( createFlag==0 || pCache->eCreate==eCreate );
assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
}
/*
** If the sqlite3PcacheFetch() routine is unable to allocate a new
** page because new clean pages are available for reuse and the cache
** size limit has been reached, then this routine can be invoked to
** try harder to allocate a page. This routine might invoke the stress
** callback to spill dirty pages to the journal. It will then try to
** allocate the new page and will only fail to allocate a new page on
** an OOM error.
**
** This routine should be invoked only after sqlite3PcacheFetch() fails.
*/
SQLITE_PRIVATE int sqlite3PcacheFetchStress(
PCache *pCache, /* Obtain the page from this cache */
Pgno pgno, /* Page number to obtain */
sqlite3_pcache_page **ppPage /* Write result here */
){
PgHdr *pPg;
if( pCache->eCreate==2 ) return 0;
/* Find a dirty page to write-out and recycle. First try to find a
** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
** cleared), but if that is not possible settle for any other
** unreferenced dirty page.
*/
expensive_assert( pcacheCheckSynced(pCache) );
for(pPg=pCache->pSynced;
pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC));
pPg=pPg->pDirtyPrev
);
pCache->pSynced = pPg;
if( !pPg ){
for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
}
if( pPg ){
int rc;
#ifdef SQLITE_LOG_CACHE_SPILL
sqlite3_log(SQLITE_FULL,
"spill page %d making room for %d - cache used: %d/%d",
pPg->pgno, pgno,
sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
numberOfCachePages(pCache));
#endif
rc = pCache->xStress(pCache->pStress, pPg);
if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
return rc;
}
}
*ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
}
/*
** This is a helper routine for sqlite3PcacheFetchFinish()
**
** In the uncommon case where the page being fetched has not been
** initialized, this routine is invoked to do the initialization.
** This routine is broken out into a separate function since it
** requires extra stack manipulation that can be avoided in the common
** case.
*/
static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
PCache *pCache, /* Obtain the page from this cache */
Pgno pgno, /* Page number obtained */
sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */
){
PgHdr *pPgHdr;
assert( pPage!=0 );
pPgHdr = (PgHdr*)pPage->pExtra;
assert( pPgHdr->pPage==0 );
memset(pPgHdr, 0, sizeof(PgHdr));
pPgHdr->pPage = pPage;
pPgHdr->pData = pPage->pBuf;
pPgHdr->pExtra = (void *)&pPgHdr[1];
memset(pPgHdr->pExtra, 0, pCache->szExtra);
pPgHdr->pCache = pCache;
pPgHdr->pgno = pgno;
return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
}
/*
** This routine converts the sqlite3_pcache_page object returned by
** sqlite3PcacheFetch() into an initialized PgHdr object. This routine
** must be called after sqlite3PcacheFetch() in order to get a usable
** result.
*/
SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
PCache *pCache, /* Obtain the page from this cache */
Pgno pgno, /* Page number obtained */
sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */
){
PgHdr *pPgHdr;
if( pPage==0 ) return 0;
pPgHdr = (PgHdr *)pPage->pExtra;
if( !pPgHdr->pPage ){
return pcacheFetchFinishWithInit(pCache, pgno, pPage);
}
if( 0==pPgHdr->nRef ){
pCache->nRef++;
}
pPgHdr->nRef++;
if( pgno==1 ){
pCache->pPage1 = pPgHdr;
}
return pPgHdr;
}
/*
** Decrement the reference count on a page. If the page is clean and the
** reference count drops to 0, then it is made elible for recycling.
*/
SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
assert( p->nRef>0 );
p->nRef--;
if( p->nRef==0 ){
p->pCache->nRef--;
if( (p->flags&PGHDR_DIRTY)==0 ){
pcacheUnpin(p);
}else{
/* Move the page to the head of the dirty list. */
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
}
}
}
/*
** Increase the reference count of a supplied page by 1.
*/
SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
assert(p->nRef>0);
p->nRef++;
}
/*
** Drop a page from the cache. There must be exactly one reference to the
** page. This function deletes that reference, so after it returns the
** page pointed to by p is invalid.
*/
SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
assert( p->nRef==1 );
if( p->flags&PGHDR_DIRTY ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
}
p->pCache->nRef--;
if( p->pgno==1 ){
p->pCache->pPage1 = 0;
}
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
}
/*
** Make sure the page is marked as dirty. If it isn't dirty already,
** make it so.
*/
SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
p->flags &= ~PGHDR_DONT_WRITE;
assert( p->nRef>0 );
if( 0==(p->flags & PGHDR_DIRTY) ){
p->flags |= PGHDR_DIRTY;
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
}
}
/*
** Make sure the page is marked as clean. If it isn't clean already,
** make it so.
*/
SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
if( (p->flags & PGHDR_DIRTY) ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
if( p->nRef==0 ){
pcacheUnpin(p);
}
}
}
|
| ︙ | ︙ | |||
38353 38354 38355 38356 38357 38358 38359 |
SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
PCache *pCache = p->pCache;
assert( p->nRef>0 );
assert( newPgno>0 );
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
p->pgno = newPgno;
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
| < | | 38716 38717 38718 38719 38720 38721 38722 38723 38724 38725 38726 38727 38728 38729 38730 |
SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
PCache *pCache = p->pCache;
assert( p->nRef>0 );
assert( newPgno>0 );
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
p->pgno = newPgno;
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
}
}
/*
** Drop every cache entry whose page number is greater than "pgno". The
** caller must ensure that there are no outstanding references to any pages
** other than page 1 with a page number greater than pgno.
|
| ︙ | ︙ | |||
38395 38396 38397 38398 38399 38400 38401 |
}
}
/*
** Close a cache.
*/
SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
| | | < | 38757 38758 38759 38760 38761 38762 38763 38764 38765 38766 38767 38768 38769 38770 38771 38772 |
}
}
/*
** Close a cache.
*/
SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
assert( pCache->pCache!=0 );
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
/*
** Discard the contents of the cache.
*/
SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
sqlite3PcacheTruncate(pCache, 0);
|
| ︙ | ︙ | |||
38506 38507 38508 38509 38510 38511 38512 |
return p->nRef;
}
/*
** Return the total number of pages in the cache.
*/
SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
| < | | < < > < | | < | | < | 38867 38868 38869 38870 38871 38872 38873 38874 38875 38876 38877 38878 38879 38880 38881 38882 38883 38884 38885 38886 38887 38888 38889 38890 38891 38892 38893 38894 38895 38896 38897 38898 38899 38900 38901 38902 38903 38904 38905 38906 38907 38908 38909 |
return p->nRef;
}
/*
** Return the total number of pages in the cache.
*/
SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
assert( pCache->pCache!=0 );
return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
}
#ifdef SQLITE_TEST
/*
** Get the suggested cache-size value.
*/
SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
return numberOfCachePages(pCache);
}
#endif
/*
** Set the suggested cache-size value.
*/
SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
assert( pCache->pCache!=0 );
pCache->szCache = mxPage;
sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
numberOfCachePages(pCache));
}
/*
** Free up as much memory as possible from the page cache.
*/
SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
assert( pCache->pCache!=0 );
sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
}
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
** defined.
|
| ︙ | ︙ | |||
38942 38943 38944 38945 38946 38947 38948 | /* ** This function is used to resize the hash table used by the cache passed ** as the first argument. ** ** The PCache mutex must be held when this function is called. */ | | | 39298 39299 39300 39301 39302 39303 39304 39305 39306 39307 39308 39309 39310 39311 39312 |
/*
** This function is used to resize the hash table used by the cache passed
** as the first argument.
**
** The PCache mutex must be held when this function is called.
*/
static void pcache1ResizeHash(PCache1 *p){
PgHdr1 **apNew;
unsigned int nNew;
unsigned int i;
assert( sqlite3_mutex_held(p->pGroup->mutex) );
nNew = p->nHash*2;
|
| ︙ | ︙ | |||
38974 38975 38976 38977 38978 38979 38980 |
apNew[h] = pPage;
}
}
sqlite3_free(p->apHash);
p->apHash = apNew;
p->nHash = nNew;
}
| < < | 39330 39331 39332 39333 39334 39335 39336 39337 39338 39339 39340 39341 39342 39343 |
apNew[h] = pPage;
}
}
sqlite3_free(p->apHash);
p->apHash = apNew;
p->nHash = nNew;
}
}
/*
** This function is used internally to remove the page pPage from the
** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
** LRU list, then this function is a no-op.
**
|
| ︙ | ︙ | |||
39110 39111 39112 39113 39114 39115 39116 39117 39118 39119 39120 39121 39122 39123 |
*/
static void pcache1Shutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
assert( pcache1.isInit!=0 );
memset(&pcache1, 0, sizeof(pcache1));
}
/*
** Implementation of the sqlite3_pcache.xCreate method.
**
** Allocate a new cache.
*/
static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
PCache1 *pCache; /* The newly created page cache */
| > > > | 39464 39465 39466 39467 39468 39469 39470 39471 39472 39473 39474 39475 39476 39477 39478 39479 39480 |
*/
static void pcache1Shutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
assert( pcache1.isInit!=0 );
memset(&pcache1, 0, sizeof(pcache1));
}
/* forward declaration */
static void pcache1Destroy(sqlite3_pcache *p);
/*
** Implementation of the sqlite3_pcache.xCreate method.
**
** Allocate a new cache.
*/
static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
PCache1 *pCache; /* The newly created page cache */
|
| ︙ | ︙ | |||
39154 39155 39156 39157 39158 39159 39160 39161 39162 |
}else{
pGroup = &pcache1.grp;
}
pCache->pGroup = pGroup;
pCache->szPage = szPage;
pCache->szExtra = szExtra;
pCache->bPurgeable = (bPurgeable ? 1 : 0);
if( bPurgeable ){
pCache->nMin = 10;
| > > < > | > > > | 39511 39512 39513 39514 39515 39516 39517 39518 39519 39520 39521 39522 39523 39524 39525 39526 39527 39528 39529 39530 39531 39532 39533 39534 39535 |
}else{
pGroup = &pcache1.grp;
}
pCache->pGroup = pGroup;
pCache->szPage = szPage;
pCache->szExtra = szExtra;
pCache->bPurgeable = (bPurgeable ? 1 : 0);
pcache1EnterMutex(pGroup);
pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
pGroup->nMinPage += pCache->nMin;
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
}
pcache1LeaveMutex(pGroup);
if( pCache->nHash==0 ){
pcache1Destroy((sqlite3_pcache*)pCache);
pCache = 0;
}
}
return (sqlite3_pcache *)pCache;
}
/*
** Implementation of the sqlite3_pcache.xCachesize method.
|
| ︙ | ︙ | |||
39215 39216 39217 39218 39219 39220 39221 39222 39223 39224 39225 39226 39227 39228 | PCache1 *pCache = (PCache1*)p; pcache1EnterMutex(pCache->pGroup); n = pCache->nPage; pcache1LeaveMutex(pCache->pGroup); return n; } /* ** Implementation of the sqlite3_pcache.xFetch method. ** ** Fetch a page by key value. ** ** Whether or not a new page may be allocated by this function depends on ** the value of the createFlag argument. 0 means do not allocate a new | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 39577 39578 39579 39580 39581 39582 39583 39584 39585 39586 39587 39588 39589 39590 39591 39592 39593 39594 39595 39596 39597 39598 39599 39600 39601 39602 39603 39604 39605 39606 39607 39608 39609 39610 39611 39612 39613 39614 39615 39616 39617 39618 39619 39620 39621 39622 39623 39624 39625 39626 39627 39628 39629 39630 39631 39632 39633 39634 39635 39636 39637 39638 39639 39640 39641 39642 39643 39644 39645 39646 39647 39648 39649 39650 39651 39652 39653 39654 39655 39656 39657 39658 39659 39660 39661 39662 39663 39664 39665 39666 39667 39668 39669 39670 39671 39672 39673 39674 39675 39676 39677 39678 39679 |
PCache1 *pCache = (PCache1*)p;
pcache1EnterMutex(pCache->pGroup);
n = pCache->nPage;
pcache1LeaveMutex(pCache->pGroup);
return n;
}
/*
** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
** in the header of the pcache1Fetch() procedure.
**
** This steps are broken out into a separate procedure because they are
** usually not needed, and by avoiding the stack initialization required
** for these steps, the main pcache1Fetch() procedure can run faster.
*/
static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
PCache1 *pCache,
unsigned int iKey,
int createFlag
){
unsigned int nPinned;
PGroup *pGroup = pCache->pGroup;
PgHdr1 *pPage = 0;
/* Step 3: Abort if createFlag is 1 but the cache is nearly full */
assert( pCache->nPage >= pCache->nRecyclable );
nPinned = pCache->nPage - pCache->nRecyclable;
assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
assert( pCache->n90pct == pCache->nMax*9/10 );
if( createFlag==1 && (
nPinned>=pGroup->mxPinned
|| nPinned>=pCache->n90pct
|| pcache1UnderMemoryPressure(pCache)
)){
return 0;
}
if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
assert( pCache->nHash>0 && pCache->apHash );
/* Step 4. Try to recycle a page. */
if( pCache->bPurgeable && pGroup->pLruTail && (
(pCache->nPage+1>=pCache->nMax)
|| pGroup->nCurrentPage>=pGroup->nMaxPage
|| pcache1UnderMemoryPressure(pCache)
)){
PCache1 *pOther;
pPage = pGroup->pLruTail;
assert( pPage->isPinned==0 );
pcache1RemoveFromHash(pPage);
pcache1PinPage(pPage);
pOther = pPage->pCache;
/* We want to verify that szPage and szExtra are the same for pOther
** and pCache. Assert that we can verify this by comparing sums. */
assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
assert( pCache->szExtra<512 );
assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
assert( pOther->szExtra<512 );
if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
pcache1FreePage(pPage);
pPage = 0;
}else{
pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
}
}
/* Step 5. If a usable page buffer has still not been found,
** attempt to allocate a new one.
*/
if( !pPage ){
if( createFlag==1 ) sqlite3BeginBenignMalloc();
pPage = pcache1AllocPage(pCache);
if( createFlag==1 ) sqlite3EndBenignMalloc();
}
if( pPage ){
unsigned int h = iKey % pCache->nHash;
pCache->nPage++;
pPage->iKey = iKey;
pPage->pNext = pCache->apHash[h];
pPage->pCache = pCache;
pPage->pLruPrev = 0;
pPage->pLruNext = 0;
pPage->isPinned = 1;
*(void **)pPage->page.pExtra = 0;
pCache->apHash[h] = pPage;
if( iKey>pCache->iMaxKey ){
pCache->iMaxKey = iKey;
}
}
return pPage;
}
/*
** Implementation of the sqlite3_pcache.xFetch method.
**
** Fetch a page by key value.
**
** Whether or not a new page may be allocated by this function depends on
** the value of the createFlag argument. 0 means do not allocate a new
|
| ︙ | ︙ | |||
39274 39275 39276 39277 39278 39279 39280 |
** 5. Otherwise, allocate and return a new page buffer.
*/
static sqlite3_pcache_page *pcache1Fetch(
sqlite3_pcache *p,
unsigned int iKey,
int createFlag
){
| < < > | < | | < < < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | 39725 39726 39727 39728 39729 39730 39731 39732 39733 39734 39735 39736 39737 39738 39739 39740 39741 39742 39743 39744 39745 39746 39747 39748 39749 39750 39751 39752 39753 39754 39755 39756 39757 39758 39759 39760 39761 39762 |
** 5. Otherwise, allocate and return a new page buffer.
*/
static sqlite3_pcache_page *pcache1Fetch(
sqlite3_pcache *p,
unsigned int iKey,
int createFlag
){
PCache1 *pCache = (PCache1 *)p;
PgHdr1 *pPage = 0;
assert( offsetof(PgHdr1,page)==0 );
assert( pCache->bPurgeable || createFlag!=1 );
assert( pCache->bPurgeable || pCache->nMin==0 );
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
assert( pCache->nMin==0 || pCache->bPurgeable );
assert( pCache->nHash>0 );
pcache1EnterMutex(pCache->pGroup);
/* Step 1: Search the hash table for an existing entry. */
pPage = pCache->apHash[iKey % pCache->nHash];
while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
/* Step 2: Abort if no existing page is found and createFlag is 0 */
if( pPage ){
if( !pPage->isPinned ) pcache1PinPage(pPage);
}else if( createFlag ){
/* Steps 3, 4, and 5 implemented by this subroutine */
pPage = pcache1FetchStage2(pCache, iKey, createFlag);
}
assert( pPage==0 || pCache->iMaxKey>=iKey );
pcache1LeaveMutex(pCache->pGroup);
return (sqlite3_pcache_page*)pPage;
}
/*
** Implementation of the sqlite3_pcache.xUnpin method.
**
|
| ︙ | ︙ | |||
41919 41920 41921 41922 41923 41924 41925 |
&& jrnlSize>pPager->journalOff
){
rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
}
return rc;
}
| < < < < < < < < < < < < < < < | 42283 42284 42285 42286 42287 42288 42289 42290 42291 42292 42293 42294 42295 42296 |
&& jrnlSize>pPager->journalOff
){
rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
}
return rc;
}
/*
** Discard the entire contents of the in-memory page-cache.
*/
static void pager_reset(Pager *pPager){
sqlite3BackupRestart(pPager->pBackup);
sqlite3PcacheClear(pPager->pPCache);
}
|
| ︙ | ︙ | |||
42226 42227 42228 42229 42230 42231 42232 |
}
}
}
#ifdef SQLITE_CHECK_PAGES
sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
| | | 42575 42576 42577 42578 42579 42580 42581 42582 42583 42584 42585 42586 42587 42588 42589 |
}
}
}
#ifdef SQLITE_CHECK_PAGES
sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
PgHdr *p = sqlite3PagerLookup(pPager, 1);
if( p ){
p->pageHash = 0;
sqlite3PagerUnrefNotNull(p);
}
}
#endif
|
| ︙ | ︙ | |||
42505 42506 42507 42508 42509 42510 42511 |
** 2008-04-14: When attempting to vacuum a corrupt database file, it
** is possible to fail a statement on a database that does not yet exist.
** Do not attempt to write if database file has never been opened.
*/
if( pagerUseWal(pPager) ){
pPg = 0;
}else{
| | | 42854 42855 42856 42857 42858 42859 42860 42861 42862 42863 42864 42865 42866 42867 42868 |
** 2008-04-14: When attempting to vacuum a corrupt database file, it
** is possible to fail a statement on a database that does not yet exist.
** Do not attempt to write if database file has never been opened.
*/
if( pagerUseWal(pPager) ){
pPg = 0;
}else{
pPg = sqlite3PagerLookup(pPager, pgno);
}
assert( pPg || !MEMDB );
assert( pPager->eState!=PAGER_OPEN || pPg==0 );
PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
(isMainJrnl?"main-journal":"sub-journal")
));
|
| ︙ | ︙ | |||
43879 43880 43881 43882 43883 43884 43885 |
if( rc==SQLITE_OK ){
pager_reset(pPager);
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
pPager->pageSize = pageSize;
sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew;
| | | 44228 44229 44230 44231 44232 44233 44234 44235 44236 44237 44238 44239 44240 44241 44242 |
if( rc==SQLITE_OK ){
pager_reset(pPager);
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
pPager->pageSize = pageSize;
sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew;
rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
}
}
*pPageSize = pPager->pageSize;
if( rc==SQLITE_OK ){
if( nReserve<0 ) nReserve = pPager->nReserve;
assert( nReserve>=0 && nReserve<1000 );
|
| ︙ | ︙ | |||
44642 44643 44644 44645 44646 44647 44648 | ** ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling ** regardless of whether or not a sync is required. This is set during ** a rollback or by user request, respectively. ** ** Spilling is also prohibited when in an error state since that could ** lead to database corruption. In the current implementaton it | | | 44991 44992 44993 44994 44995 44996 44997 44998 44999 45000 45001 45002 45003 45004 45005 | ** ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling ** regardless of whether or not a sync is required. This is set during ** a rollback or by user request, respectively. ** ** Spilling is also prohibited when in an error state since that could ** lead to database corruption. In the current implementaton it ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 ** while in the error state, hence it is impossible for this routine to ** be called in the error state. Nevertheless, we include a NEVER() ** test for the error state as a safeguard against future changes. */ if( NEVER(pPager->errCode) ) return SQLITE_OK; testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); testcase( pPager->doNotSpill & SPILLFLAG_OFF ); |
| ︙ | ︙ | |||
44978 44979 44980 44981 44982 44983 44984 |
*/
if( rc==SQLITE_OK ){
assert( pPager->memDb==0 );
rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
testcase( rc!=SQLITE_OK );
}
| > > > > > > > | | < > < < < < < < | 45327 45328 45329 45330 45331 45332 45333 45334 45335 45336 45337 45338 45339 45340 45341 45342 45343 45344 45345 45346 45347 45348 45349 45350 45351 45352 45353 45354 45355 45356 45357 |
*/
if( rc==SQLITE_OK ){
assert( pPager->memDb==0 );
rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
testcase( rc!=SQLITE_OK );
}
/* Initialize the PCache object. */
if( rc==SQLITE_OK ){
assert( nExtra<1000 );
nExtra = ROUND8(nExtra);
rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
!memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
}
/* If an error occurred above, free the Pager structure and close the file.
*/
if( rc!=SQLITE_OK ){
sqlite3OsClose(pPager->fd);
sqlite3PageFree(pPager->pTmpSpace);
sqlite3_free(pPager);
return rc;
}
PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
pPager->useJournal = (u8)useJournal;
/* pPager->stmtOpen = 0; */
/* pPager->stmtInUse = 0; */
/* pPager->nRef = 0; */
|
| ︙ | ︙ | |||
45542 45543 45544 45545 45546 45547 45548 |
}
/* If the pager is in the error state, return an error immediately.
** Otherwise, request the page from the PCache layer. */
if( pPager->errCode!=SQLITE_OK ){
rc = pPager->errCode;
}else{
| < | > > | > > > > > > > | 45892 45893 45894 45895 45896 45897 45898 45899 45900 45901 45902 45903 45904 45905 45906 45907 45908 45909 45910 45911 45912 45913 45914 45915 45916 45917 45918 45919 45920 45921 45922 45923 45924 45925 45926 45927 45928 45929 45930 45931 45932 45933 45934 45935 45936 45937 45938 45939 45940 45941 45942 45943 45944 45945 45946 45947 |
}
/* If the pager is in the error state, return an error immediately.
** Otherwise, request the page from the PCache layer. */
if( pPager->errCode!=SQLITE_OK ){
rc = pPager->errCode;
}else{
if( bMmapOk && pagerUseWal(pPager) ){
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
if( rc!=SQLITE_OK ) goto pager_acquire_err;
}
if( bMmapOk && iFrame==0 ){
void *pData = 0;
rc = sqlite3OsFetch(pPager->fd,
(i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
);
if( rc==SQLITE_OK && pData ){
if( pPager->eState>PAGER_READER ){
pPg = sqlite3PagerLookup(pPager, pgno);
}
if( pPg==0 ){
rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
}else{
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
}
if( pPg ){
assert( rc==SQLITE_OK );
*ppPage = pPg;
return SQLITE_OK;
}
}
if( rc!=SQLITE_OK ){
goto pager_acquire_err;
}
}
{
sqlite3_pcache_page *pBase;
pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
if( pBase==0 ){
rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
if( rc!=SQLITE_OK ) goto pager_acquire_err;
}
pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
if( pPg==0 ) rc = SQLITE_NOMEM;
}
}
if( rc!=SQLITE_OK ){
/* Either the call to sqlite3PcacheFetch() returned an error or the
** pager was already in the error-state when this function was called.
** Set pPg to 0 and jump to the exception handler. */
pPg = 0;
|
| ︙ | ︙ | |||
45672 45673 45674 45675 45676 45677 45678 |
** See also sqlite3PagerGet(). The difference between this routine
** and sqlite3PagerGet() is that _get() will go to the disk and read
** in the page if the page is not already in cache. This routine
** returns NULL if the page is not in cache or if a disk I/O error
** has ever happened.
*/
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
| | < | | | 46030 46031 46032 46033 46034 46035 46036 46037 46038 46039 46040 46041 46042 46043 46044 46045 46046 46047 46048 46049 |
** See also sqlite3PagerGet(). The difference between this routine
** and sqlite3PagerGet() is that _get() will go to the disk and read
** in the page if the page is not already in cache. This routine
** returns NULL if the page is not in cache or if a disk I/O error
** has ever happened.
*/
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
sqlite3_pcache_page *pPage;
assert( pPager!=0 );
assert( pgno!=0 );
assert( pPager->pPCache!=0 );
pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
}
/*
** Release a page reference.
**
** If the number of references to the page drop to zero, then the
** page is added to the LRU list. When all references to all pages
|
| ︙ | ︙ | |||
46013 46014 46015 46016 46017 46018 46019 46020 46021 46022 46023 46024 46025 46026 46027 46028 46029 46030 46031 46032 46033 46034 |
/* Update the database size and return.
*/
if( pPager->dbSize<pPg->pgno ){
pPager->dbSize = pPg->pgno;
}
return rc;
}
/*
** Mark a data page as writeable. This routine must be called before
** making changes to a page. The caller must check the return value
** of this function and be careful not to change any page data unless
** this routine returns SQLITE_OK.
**
** The difference between this function and pager_write() is that this
** function also deals with the special case where 2 or more pages
** fit on a single disk sector. In this case all co-resident pages
** must have been written to the journal file before returning.
**
** If an error occurs, SQLITE_NOMEM or an IO error code is returned
** as appropriate. Otherwise, SQLITE_OK.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < | | | < | < < < < < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 46370 46371 46372 46373 46374 46375 46376 46377 46378 46379 46380 46381 46382 46383 46384 46385 46386 46387 46388 46389 46390 46391 46392 46393 46394 46395 46396 46397 46398 46399 46400 46401 46402 46403 46404 46405 46406 46407 46408 46409 46410 46411 46412 46413 46414 46415 46416 46417 46418 46419 46420 46421 46422 46423 46424 46425 46426 46427 46428 46429 46430 46431 46432 46433 46434 46435 46436 46437 46438 46439 46440 46441 46442 46443 46444 46445 46446 46447 46448 46449 46450 46451 46452 46453 46454 46455 46456 46457 46458 46459 46460 46461 46462 46463 46464 46465 46466 46467 46468 46469 46470 46471 46472 46473 46474 46475 46476 46477 46478 46479 46480 46481 46482 46483 46484 46485 46486 46487 46488 46489 46490 46491 46492 46493 46494 46495 46496 46497 46498 46499 |
/* Update the database size and return.
*/
if( pPager->dbSize<pPg->pgno ){
pPager->dbSize = pPg->pgno;
}
return rc;
}
/*
** This is a variant of sqlite3PagerWrite() that runs when the sector size
** is larger than the page size. SQLite makes the (reasonable) assumption that
** all bytes of a sector are written together by hardware. Hence, all bytes of
** a sector need to be journalled in case of a power loss in the middle of
** a write.
**
** Usually, the sector size is less than or equal to the page size, in which
** case pages can be individually written. This routine only runs in the exceptional
** case where the page size is smaller than the sector size.
*/
static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
int rc = SQLITE_OK; /* Return code */
Pgno nPageCount; /* Total number of pages in database file */
Pgno pg1; /* First page of the sector pPg is located on. */
int nPage = 0; /* Number of pages starting at pg1 to journal */
int ii; /* Loop counter */
int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
Pager *pPager = pPg->pPager; /* The pager that owns pPg */
Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
/* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
** a journal header to be written between the pages journaled by
** this function.
*/
assert( !MEMDB );
assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
pPager->doNotSpill |= SPILLFLAG_NOSYNC;
/* This trick assumes that both the page-size and sector-size are
** an integer power of 2. It sets variable pg1 to the identifier
** of the first page of the sector pPg is located on.
*/
pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
nPageCount = pPager->dbSize;
if( pPg->pgno>nPageCount ){
nPage = (pPg->pgno - pg1)+1;
}else if( (pg1+nPagePerSector-1)>nPageCount ){
nPage = nPageCount+1-pg1;
}else{
nPage = nPagePerSector;
}
assert(nPage>0);
assert(pg1<=pPg->pgno);
assert((pg1+nPage)>pPg->pgno);
for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
Pgno pg = pg1+ii;
PgHdr *pPage;
if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
if( pg!=PAGER_MJ_PGNO(pPager) ){
rc = sqlite3PagerGet(pPager, pg, &pPage);
if( rc==SQLITE_OK ){
rc = pager_write(pPage);
if( pPage->flags&PGHDR_NEED_SYNC ){
needSync = 1;
}
sqlite3PagerUnrefNotNull(pPage);
}
}
}else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
if( pPage->flags&PGHDR_NEED_SYNC ){
needSync = 1;
}
sqlite3PagerUnrefNotNull(pPage);
}
}
/* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages
** starting at pg1, then it needs to be set for all of them. Because
** writing to any of these nPage pages may damage the others, the
** journal file must contain sync()ed copies of all of them
** before any of them can be written out to the database file.
*/
if( rc==SQLITE_OK && needSync ){
assert( !MEMDB );
for(ii=0; ii<nPage; ii++){
PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
if( pPage ){
pPage->flags |= PGHDR_NEED_SYNC;
sqlite3PagerUnrefNotNull(pPage);
}
}
}
assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
return rc;
}
/*
** Mark a data page as writeable. This routine must be called before
** making changes to a page. The caller must check the return value
** of this function and be careful not to change any page data unless
** this routine returns SQLITE_OK.
**
** The difference between this function and pager_write() is that this
** function also deals with the special case where 2 or more pages
** fit on a single disk sector. In this case all co-resident pages
** must have been written to the journal file before returning.
**
** If an error occurs, SQLITE_NOMEM or an IO error code is returned
** as appropriate. Otherwise, SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
assert( (pPg->flags & PGHDR_MMAP)==0 );
assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
assert( pPg->pPager->eState!=PAGER_ERROR );
assert( assert_pager_state(pPg->pPager) );
if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
return pagerWriteLargeSector(pPg);
}else{
return pager_write(pPg);
}
}
/*
** Return TRUE if the page given in the argument was previously passed
** to sqlite3PagerWrite(). In other words, return TRUE if it is ok
** to change the content of the page.
*/
|
| ︙ | ︙ | |||
47013 47014 47015 47016 47017 47018 47019 | /* If the cache contains a page with page-number pgno, remove it ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for ** page pgno before the 'move' operation, it needs to be retained ** for the page moved there. */ pPg->flags &= ~PGHDR_NEED_SYNC; | | | 47381 47382 47383 47384 47385 47386 47387 47388 47389 47390 47391 47392 47393 47394 47395 |
/* If the cache contains a page with page-number pgno, remove it
** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for
** page pgno before the 'move' operation, it needs to be retained
** for the page moved there.
*/
pPg->flags &= ~PGHDR_NEED_SYNC;
pPgOld = sqlite3PagerLookup(pPager, pgno);
assert( !pPgOld || pPgOld->nRef==1 );
if( pPgOld ){
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
if( MEMDB ){
/* Do not discard pages from an in-memory database since we might
** need to rollback later. Just move the page out of the way. */
sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
|
| ︙ | ︙ | |||
51284 51285 51286 51287 51288 51289 51290 | p->locked = 1; } /* ** Release the BtShared mutex associated with B-Tree handle p and ** clear the p->locked boolean. */ | | > > > < < | 51652 51653 51654 51655 51656 51657 51658 51659 51660 51661 51662 51663 51664 51665 51666 51667 51668 51669 51670 51671 51672 51673 51674 51675 51676 51677 51678 51679 51680 51681 51682 51683 51684 51685 51686 51687 51688 51689 51690 51691 51692 51693 51694 51695 51696 |
p->locked = 1;
}
/*
** Release the BtShared mutex associated with B-Tree handle p and
** clear the p->locked boolean.
*/
static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){
BtShared *pBt = p->pBt;
assert( p->locked==1 );
assert( sqlite3_mutex_held(pBt->mutex) );
assert( sqlite3_mutex_held(p->db->mutex) );
assert( p->db==pBt->db );
sqlite3_mutex_leave(pBt->mutex);
p->locked = 0;
}
/* Forward reference */
static void SQLITE_NOINLINE btreeLockCarefully(Btree *p);
/*
** Enter a mutex on the given BTree object.
**
** If the object is not sharable, then no mutex is ever required
** and this routine is a no-op. The underlying mutex is non-recursive.
** But we keep a reference count in Btree.wantToLock so the behavior
** of this interface is recursive.
**
** To avoid deadlocks, multiple Btrees are locked in the same order
** by all database connections. The p->pNext is a list of other
** Btrees belonging to the same database connection as the p Btree
** which need to be locked after p. If we cannot get a lock on
** p, then first unlock all of the others on p->pNext, then wait
** for the lock to become available on p, then relock all of the
** subsequent Btrees that desire a lock.
*/
SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
/* Some basic sanity checking on the Btree. The list of Btrees
** connected by pNext and pPrev should be in sorted order by
** Btree.pBt value. All elements of the list should belong to
** the same connection. Only shared Btrees are on the list. */
assert( p->pNext==0 || p->pNext->pBt>p->pBt );
assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
assert( p->pNext==0 || p->pNext->db==p->db );
|
| ︙ | ︙ | |||
51338 51339 51340 51341 51342 51343 51344 51345 51346 51347 51348 51349 51350 51351 |
/* Unless the database is sharable and unlocked, then BtShared.db
** should already be set correctly. */
assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db );
if( !p->sharable ) return;
p->wantToLock++;
if( p->locked ) return;
/* In most cases, we should be able to acquire the lock we
** want without having to go throught the ascending lock
** procedure that follows. Just be sure not to block.
*/
if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
p->pBt->db = p->db;
| > > > > > > > > > > > | 51707 51708 51709 51710 51711 51712 51713 51714 51715 51716 51717 51718 51719 51720 51721 51722 51723 51724 51725 51726 51727 51728 51729 51730 51731 |
/* Unless the database is sharable and unlocked, then BtShared.db
** should already be set correctly. */
assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db );
if( !p->sharable ) return;
p->wantToLock++;
if( p->locked ) return;
btreeLockCarefully(p);
}
/* This is a helper function for sqlite3BtreeLock(). By moving
** complex, but seldom used logic, out of sqlite3BtreeLock() and
** into this routine, we avoid unnecessary stack pointer changes
** and thus help the sqlite3BtreeLock() routine to run much faster
** in the common case.
*/
static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){
Btree *pLater;
/* In most cases, we should be able to acquire the lock we
** want without having to go throught the ascending lock
** procedure that follows. Just be sure not to block.
*/
if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
p->pBt->db = p->db;
|
| ︙ | ︙ | |||
51369 51370 51371 51372 51373 51374 51375 51376 51377 51378 51379 51380 51381 51382 |
lockBtreeMutex(p);
for(pLater=p->pNext; pLater; pLater=pLater->pNext){
if( pLater->wantToLock ){
lockBtreeMutex(pLater);
}
}
}
/*
** Exit the recursive mutex on a Btree.
*/
SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
if( p->sharable ){
assert( p->wantToLock>0 );
| > | 51749 51750 51751 51752 51753 51754 51755 51756 51757 51758 51759 51760 51761 51762 51763 |
lockBtreeMutex(p);
for(pLater=p->pNext; pLater; pLater=pLater->pNext){
if( pLater->wantToLock ){
lockBtreeMutex(pLater);
}
}
}
/*
** Exit the recursive mutex on a Btree.
*/
SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
if( p->sharable ){
assert( p->wantToLock>0 );
|
| ︙ | ︙ | |||
52164 52165 52166 52167 52168 52169 52170 52171 52172 |
pCur->eState = CURSOR_REQUIRESEEK;
}
invalidateOverflowCache(pCur);
return rc;
}
/*
** Save the positions of all cursors (except pExcept) that are open on
| > > > > > > | | > > > > > > > > > > > > > > > > > > > > > | | 52545 52546 52547 52548 52549 52550 52551 52552 52553 52554 52555 52556 52557 52558 52559 52560 52561 52562 52563 52564 52565 52566 52567 52568 52569 52570 52571 52572 52573 52574 52575 52576 52577 52578 52579 52580 52581 52582 52583 52584 52585 52586 52587 52588 52589 52590 52591 52592 52593 52594 52595 52596 52597 52598 52599 52600 52601 52602 52603 52604 52605 52606 52607 |
pCur->eState = CURSOR_REQUIRESEEK;
}
invalidateOverflowCache(pCur);
return rc;
}
/* Forward reference */
static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*);
/*
** Save the positions of all cursors (except pExcept) that are open on
** the table with root-page iRoot. "Saving the cursor position" means that
** the location in the btree is remembered in such a way that it can be
** moved back to the same spot after the btree has been modified. This
** routine is called just before cursor pExcept is used to modify the
** table, for example in BtreeDelete() or BtreeInsert().
**
** Implementation note: This routine merely checks to see if any cursors
** need to be saved. It calls out to saveCursorsOnList() in the (unusual)
** event that cursors are in need to being saved.
*/
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
BtCursor *p;
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pExcept==0 || pExcept->pBt==pBt );
for(p=pBt->pCursor; p; p=p->pNext){
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break;
}
return p ? saveCursorsOnList(p, iRoot, pExcept) : SQLITE_OK;
}
/* This helper routine to saveAllCursors does the actual work of saving
** the cursors if and when a cursor is found that actually requires saving.
** The common case is that no cursors need to be saved, so this routine is
** broken out from its caller to avoid unnecessary stack pointer movement.
*/
static int SQLITE_NOINLINE saveCursorsOnList(
BtCursor *p, /* The first cursor that needs saving */
Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
BtCursor *pExcept /* Do not save this cursor */
){
do{
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
if( p->eState==CURSOR_VALID ){
int rc = saveCursorPosition(p);
if( SQLITE_OK!=rc ){
return rc;
}
}else{
testcase( p->iPage>0 );
btreeReleaseAllCursorPages(p);
}
}
p = p->pNext;
}while( p );
return SQLITE_OK;
}
/*
** Clear the current cursor position.
*/
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){
|
| ︙ | ︙ | |||
52270 52271 52272 52273 52274 52275 52276 |
#define restoreCursorPosition(p) \
(p->eState>=CURSOR_REQUIRESEEK ? \
btreeRestoreCursorPosition(p) : \
SQLITE_OK)
/*
| | > | | > | < | < > > | > > | < > | > | > > > > > > > > | > | < < < | | | | 52678 52679 52680 52681 52682 52683 52684 52685 52686 52687 52688 52689 52690 52691 52692 52693 52694 52695 52696 52697 52698 52699 52700 52701 52702 52703 52704 52705 52706 52707 52708 52709 52710 52711 52712 52713 52714 52715 52716 52717 52718 52719 52720 52721 52722 52723 52724 52725 52726 52727 52728 52729 52730 52731 52732 52733 |
#define restoreCursorPosition(p) \
(p->eState>=CURSOR_REQUIRESEEK ? \
btreeRestoreCursorPosition(p) : \
SQLITE_OK)
/*
** Determine whether or not a cursor has moved from the position where
** it was last placed, or has been invalidated for any other reason.
** Cursors can move when the row they are pointing at is deleted out
** from under them, for example. Cursor might also move if a btree
** is rebalanced.
**
** Calling this routine with a NULL cursor pointer returns false.
**
** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
** back to where it ought to be if this routine returns true.
*/
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
return pCur && pCur->eState!=CURSOR_VALID;
}
/*
** This routine restores a cursor back to its original position after it
** has been moved by some outside activity (such as a btree rebalance or
** a row having been deleted out from under the cursor).
**
** On success, the *pDifferentRow parameter is false if the cursor is left
** pointing at exactly the same row. *pDifferntRow is the row the cursor
** was pointing to has been deleted, forcing the cursor to point to some
** nearby row.
**
** This routine should only be called for a cursor that just returned
** TRUE from sqlite3BtreeCursorHasMoved().
*/
SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
int rc;
assert( pCur!=0 );
assert( pCur->eState!=CURSOR_VALID );
rc = restoreCursorPosition(pCur);
if( rc ){
*pDifferentRow = 1;
return rc;
}
if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
*pDifferentRow = 1;
}else{
*pDifferentRow = 0;
}
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Given a page number of a regular database page, return the page
|
| ︙ | ︙ | |||
52732 52733 52734 52735 52736 52737 52738 |
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
u8 * const data = pPage->aData; /* Local cache of pPage->aData */
| < < > | | | | | > | > | < < | | < | < < | > > > > > | | | > > | 53151 53152 53153 53154 53155 53156 53157 53158 53159 53160 53161 53162 53163 53164 53165 53166 53167 53168 53169 53170 53171 53172 53173 53174 53175 53176 53177 53178 53179 53180 53181 53182 53183 53184 53185 53186 53187 53188 53189 53190 53191 53192 53193 53194 53195 53196 53197 53198 53199 53200 53201 53202 53203 53204 53205 53206 53207 53208 53209 53210 53211 53212 53213 53214 53215 53216 53217 53218 53219 53220 53221 53222 53223 53224 53225 53226 53227 53228 53229 53230 53231 53232 53233 53234 53235 |
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
u8 * const data = pPage->aData; /* Local cache of pPage->aData */
int top; /* First byte of cell content area */
int gap; /* First byte of gap between cell pointers and cell content */
int rc; /* Integer return code */
int usableSize; /* Usable size of the page */
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( pPage->pBt );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( nByte>=0 ); /* Minimum cell size is 4 */
assert( pPage->nFree>=nByte );
assert( pPage->nOverflow==0 );
usableSize = pPage->pBt->usableSize;
assert( nByte < usableSize-8 );
assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
gap = pPage->cellOffset + 2*pPage->nCell;
assert( gap<=65536 );
top = get2byte(&data[hdr+5]);
if( gap>top ){
if( top==0 ){
top = 65536;
}else{
return SQLITE_CORRUPT_BKPT;
}
}
/* If there is enough space between gap and top for one more cell pointer
** array entry offset, and if the freelist is not empty, then search the
** freelist looking for a free slot big enough to satisfy the request.
*/
testcase( gap+2==top );
testcase( gap+1==top );
testcase( gap==top );
if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
int pc, addr;
for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
int size; /* Size of the free slot */
if( pc>usableSize-4 || pc<addr+4 ){
return SQLITE_CORRUPT_BKPT;
}
size = get2byte(&data[pc+2]);
if( size>=nByte ){
int x = size - nByte;
testcase( x==4 );
testcase( x==3 );
if( x<4 ){
if( data[hdr+7]>=60 ) goto defragment_page;
/* Remove the slot from the free-list. Update the number of
** fragmented bytes within the page. */
memcpy(&data[addr], &data[pc], 2);
data[hdr+7] += (u8)x;
}else if( size+pc > usableSize ){
return SQLITE_CORRUPT_BKPT;
}else{
/* The slot remains on the free-list. Reduce its size to account
** for the portion used by the new allocation. */
put2byte(&data[pc+2], x);
}
*pIdx = pc + x;
return SQLITE_OK;
}
}
}
/* The request could not be fulfilled using a freelist slot. Check
** to see if defragmentation is necessary.
*/
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
defragment_page:
testcase( pPage->nCell==0 );
rc = defragmentPage(pPage);
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
assert( gap+nByte<=top );
}
|
| ︙ | ︙ | |||
52822 52823 52824 52825 52826 52827 52828 | assert( top+nByte <= (int)pPage->pBt->usableSize ); *pIdx = top; return SQLITE_OK; } /* ** Return a section of the pPage->aData to the freelist. | | | | > > > | > > | > > | > > | > | | | | > < | | > | | < < < < < < | | | > | | < | < | | < | > | > | > > > > > > > | | | > | > > | | | < < < < | < | < < | > > > > > | > | > > > > | < | | < < < | < < < | < | | | | 53244 53245 53246 53247 53248 53249 53250 53251 53252 53253 53254 53255 53256 53257 53258 53259 53260 53261 53262 53263 53264 53265 53266 53267 53268 53269 53270 53271 53272 53273 53274 53275 53276 53277 53278 53279 53280 53281 53282 53283 53284 53285 53286 53287 53288 53289 53290 53291 53292 53293 53294 53295 53296 53297 53298 53299 53300 53301 53302 53303 53304 53305 53306 53307 53308 53309 53310 53311 53312 53313 53314 53315 53316 53317 53318 53319 53320 53321 53322 53323 53324 53325 53326 53327 53328 53329 53330 53331 53332 53333 53334 53335 53336 53337 53338 53339 53340 53341 53342 53343 53344 53345 53346 53347 53348 53349 53350 53351 |
assert( top+nByte <= (int)pPage->pBt->usableSize );
*pIdx = top;
return SQLITE_OK;
}
/*
** Return a section of the pPage->aData to the freelist.
** The first byte of the new free block is pPage->aData[iStart]
** and the size of the block is iSize bytes.
**
** Adjacent freeblocks are coalesced.
**
** Note that even though the freeblock list was checked by btreeInitPage(),
** that routine will not detect overlap between cells or freeblocks. Nor
** does it detect cells or freeblocks that encrouch into the reserved bytes
** at the end of the page. So do additional corruption checks inside this
** routine and return SQLITE_CORRUPT if any problems are found.
*/
static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
u16 iPtr; /* Address of pointer to next freeblock */
u16 iFreeBlk; /* Address of the next freeblock */
u8 hdr; /* Page header size. 0 or 100 */
u8 nFrag = 0; /* Reduction in fragmentation */
u16 iOrigSize = iSize; /* Original value of iSize */
u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
unsigned char *data = pPage->aData; /* Page content */
assert( pPage->pBt!=0 );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
assert( iEnd <= pPage->pBt->usableSize );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( iSize>=4 ); /* Minimum cell size is 4 */
assert( iStart<=iLast );
/* Overwrite deleted information with zeros when the secure_delete
** option is enabled */
if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
memset(&data[iStart], 0, iSize);
}
/* The list of freeblocks must be in ascending order. Find the
** spot on the list where iStart should be inserted.
*/
hdr = pPage->hdrOffset;
iPtr = hdr + 1;
if( data[iPtr+1]==0 && data[iPtr]==0 ){
iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
}else{
while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
iPtr = iFreeBlk;
}
if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
assert( iFreeBlk>iPtr || iFreeBlk==0 );
/* At this point:
** iFreeBlk: First freeblock after iStart, or zero if none
** iPtr: The address of a pointer iFreeBlk
**
** Check to see if iFreeBlk should be coalesced onto the end of iStart.
*/
if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]);
}
/* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
** in the page header) then check to see if iStart should be coalesced
** onto the end of iPtr.
*/
if( iPtr>hdr+1 ){
int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
if( iPtrEnd+3>=iStart ){
if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
nFrag += iStart - iPtrEnd;
iSize = iEnd - iPtr;
iStart = iPtr;
}
}
if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
data[hdr+7] -= nFrag;
}
if( iStart==get2byte(&data[hdr+5]) ){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
put2byte(&data[hdr+1], iFreeBlk);
put2byte(&data[hdr+5], iEnd);
}else{
/* Insert the new freeblock into the freelist */
put2byte(&data[iPtr], iStart);
put2byte(&data[iStart], iFreeBlk);
put2byte(&data[iStart+2], iSize);
}
pPage->nFree += iOrigSize;
return SQLITE_OK;
}
/*
** Decode the flags byte (the first byte of the header) for a page
** and initialize fields of the MemPage structure accordingly.
**
|
| ︙ | ︙ | |||
55997 55998 55999 56000 56001 56002 56003 |
static int moveToRightmost(BtCursor *pCur){
Pgno pgno;
int rc = SQLITE_OK;
MemPage *pPage = 0;
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
| | > < | | | < | | 56429 56430 56431 56432 56433 56434 56435 56436 56437 56438 56439 56440 56441 56442 56443 56444 56445 56446 56447 56448 56449 56450 56451 56452 |
static int moveToRightmost(BtCursor *pCur){
Pgno pgno;
int rc = SQLITE_OK;
MemPage *pPage = 0;
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
pCur->aiIdx[pCur->iPage] = pPage->nCell;
rc = moveToChild(pCur, pgno);
if( rc ) return rc;
}
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
return SQLITE_OK;
}
/* Move the cursor to the first entry in the table. Return SQLITE_OK
** on success. Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
| ︙ | ︙ | |||
56138 56139 56140 56141 56142 56143 56144 |
*pRes = -1;
return SQLITE_OK;
}
}
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
| | | 56569 56570 56571 56572 56573 56574 56575 56576 56577 56578 56579 56580 56581 56582 56583 |
*pRes = -1;
return SQLITE_OK;
}
}
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
pIdxKey->errCode = 0;
assert( pIdxKey->default_rc==1
|| pIdxKey->default_rc==0
|| pIdxKey->default_rc==-1
);
}else{
xRecordCompare = 0; /* All keys are integers */
}
|
| ︙ | ︙ | |||
56262 56263 56264 56265 56266 56267 56268 |
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
}
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
sqlite3_free(pCellKey);
}
| | > > > | | 56693 56694 56695 56696 56697 56698 56699 56700 56701 56702 56703 56704 56705 56706 56707 56708 56709 56710 56711 56712 56713 56714 56715 56716 56717 56718 56719 56720 |
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
}
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
sqlite3_free(pCellKey);
}
assert(
(pIdxKey->errCode!=SQLITE_CORRUPT || c==0)
&& (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed)
);
if( c<0 ){
lwr = idx+1;
}else if( c>0 ){
upr = idx-1;
}else{
assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
pCur->aiIdx[pCur->iPage] = (u16)idx;
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
if( lwr>upr ) break;
assert( lwr+upr>=0 );
idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
}
}
|
| ︙ | ︙ | |||
56326 56327 56328 56329 56330 56331 56332 56333 56334 56335 56336 56337 56338 56339 56340 56341 56342 | } /* ** Advance the cursor to the next entry in the database. If ** successful then set *pRes=0. If the cursor ** was already pointing to the last entry in the database before ** this routine was called, then set *pRes=1. ** ** The calling function will set *pRes to 0 or 1. The initial *pRes value ** will be 1 if the cursor being stepped corresponds to an SQL index and ** if this routine could have been skipped if that SQL index had been ** a unique index. Otherwise the caller will have set *pRes to zero. ** Zero is the common case. The btree implementation is free to use the ** initial *pRes value as a hint to improve performance, but the current ** SQLite btree implementation does not. (Note that the comdb2 btree ** implementation does use this hint, however.) */ | > > > > > > | | | < | < < < < | < < < | < < < | | > > | > > > > > > > > > > > > > > > > > | | < | | > > > > > > | | | > | | | < | < < | < < < | | > > > > > > > > > > > > > > > > | | 56760 56761 56762 56763 56764 56765 56766 56767 56768 56769 56770 56771 56772 56773 56774 56775 56776 56777 56778 56779 56780 56781 56782 56783 56784 56785 56786 56787 56788 56789 56790 56791 56792 56793 56794 56795 56796 56797 56798 56799 56800 56801 56802 56803 56804 56805 56806 56807 56808 56809 56810 56811 56812 56813 56814 56815 56816 56817 56818 56819 56820 56821 56822 56823 56824 56825 56826 56827 56828 56829 56830 56831 56832 56833 56834 56835 56836 56837 56838 56839 56840 56841 56842 56843 56844 56845 56846 56847 56848 56849 56850 56851 56852 56853 56854 56855 56856 56857 56858 56859 56860 56861 56862 56863 56864 56865 56866 56867 56868 56869 56870 56871 56872 56873 56874 56875 56876 56877 56878 56879 56880 56881 56882 56883 56884 56885 56886 56887 56888 56889 56890 56891 56892 56893 56894 56895 56896 56897 56898 56899 56900 56901 56902 56903 56904 56905 56906 56907 56908 56909 56910 56911 56912 56913 56914 56915 56916 56917 56918 56919 56920 56921 56922 56923 56924 56925 56926 56927 56928 56929 56930 56931 56932 56933 56934 56935 56936 56937 56938 56939 56940 56941 56942 56943 56944 56945 56946 56947 56948 56949 56950 56951 56952 56953 56954 56955 56956 56957 56958 56959 56960 56961 56962 56963 56964 56965 56966 56967 56968 56969 56970 56971 56972 56973 56974 56975 |
}
/*
** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor
** was already pointing to the last entry in the database before
** this routine was called, then set *pRes=1.
**
** The main entry point is sqlite3BtreeNext(). That routine is optimized
** for the common case of merely incrementing the cell counter BtCursor.aiIdx
** to the next cell on the current page. The (slower) btreeNext() helper
** routine is called when it is necessary to move to a different page or
** to restore the cursor.
**
** The calling function will set *pRes to 0 or 1. The initial *pRes value
** will be 1 if the cursor being stepped corresponds to an SQL index and
** if this routine could have been skipped if that SQL index had been
** a unique index. Otherwise the caller will have set *pRes to zero.
** Zero is the common case. The btree implementation is free to use the
** initial *pRes value as a hint to improve performance, but the current
** SQLite btree implementation does not. (Note that the comdb2 btree
** implementation does use this hint, however.)
*/
static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
int rc;
int idx;
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
assert( *pRes==0 );
if( pCur->eState!=CURSOR_VALID ){
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
rc = restoreCursorPosition(pCur);
if( rc!=SQLITE_OK ){
return rc;
}
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
if( pCur->skipNext ){
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
pCur->eState = CURSOR_VALID;
if( pCur->skipNext>0 ){
pCur->skipNext = 0;
return SQLITE_OK;
}
pCur->skipNext = 0;
}
}
pPage = pCur->apPage[pCur->iPage];
idx = ++pCur->aiIdx[pCur->iPage];
assert( pPage->isInit );
/* If the database file is corrupt, it is possible for the value of idx
** to be invalid here. This can only occur if a second cursor modifies
** the page while cursor pCur is holding a reference to it. Which can
** only happen if the database is corrupt in such a way as to link the
** page into more than one b-tree structure. */
testcase( idx>pPage->nCell );
if( idx>=pPage->nCell ){
if( !pPage->leaf ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
if( rc ) return rc;
return moveToLeftmost(pCur);
}
do{
if( pCur->iPage==0 ){
*pRes = 1;
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}
moveToParent(pCur);
pPage = pCur->apPage[pCur->iPage];
}while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
if( pPage->intKey ){
return sqlite3BtreeNext(pCur, pRes);
}else{
return SQLITE_OK;
}
}
if( pPage->leaf ){
return SQLITE_OK;
}else{
return moveToLeftmost(pCur);
}
}
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
assert( pRes!=0 );
assert( *pRes==0 || *pRes==1 );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
*pRes = 0;
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
pPage = pCur->apPage[pCur->iPage];
if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
pCur->aiIdx[pCur->iPage]--;
return btreeNext(pCur, pRes);
}
if( pPage->leaf ){
return SQLITE_OK;
}else{
return moveToLeftmost(pCur);
}
}
/*
** Step the cursor to the back to the previous entry in the database. If
** successful then set *pRes=0. If the cursor
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
**
** The main entry point is sqlite3BtreePrevious(). That routine is optimized
** for the common case of merely decrementing the cell counter BtCursor.aiIdx
** to the previous cell on the current page. The (slower) btreePrevious() helper
** routine is called when it is necessary to move to a different page or
** to restore the cursor.
**
** The calling function will set *pRes to 0 or 1. The initial *pRes value
** will be 1 if the cursor being stepped corresponds to an SQL index and
** if this routine could have been skipped if that SQL index had been
** a unique index. Otherwise the caller will have set *pRes to zero.
** Zero is the common case. The btree implementation is free to use the
** initial *pRes value as a hint to improve performance, but the current
** SQLite btree implementation does not. (Note that the comdb2 btree
** implementation does use this hint, however.)
*/
static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
int rc;
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
assert( pRes!=0 );
assert( *pRes==0 );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
assert( pCur->info.nSize==0 );
if( pCur->eState!=CURSOR_VALID ){
assert( pCur->eState>=CURSOR_REQUIRESEEK );
rc = btreeRestoreCursorPosition(pCur);
if( rc!=SQLITE_OK ){
return rc;
}
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
if( pCur->skipNext ){
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
pCur->eState = CURSOR_VALID;
if( pCur->skipNext<0 ){
pCur->skipNext = 0;
return SQLITE_OK;
}
pCur->skipNext = 0;
}
}
pPage = pCur->apPage[pCur->iPage];
assert( pPage->isInit );
if( !pPage->leaf ){
int idx = pCur->aiIdx[pCur->iPage];
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ) return rc;
rc = moveToRightmost(pCur);
}else{
while( pCur->aiIdx[pCur->iPage]==0 ){
if( pCur->iPage==0 ){
pCur->eState = CURSOR_INVALID;
*pRes = 1;
return SQLITE_OK;
}
moveToParent(pCur);
}
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
pCur->aiIdx[pCur->iPage]--;
pPage = pCur->apPage[pCur->iPage];
if( pPage->intKey && !pPage->leaf ){
rc = sqlite3BtreePrevious(pCur, pRes);
}else{
rc = SQLITE_OK;
}
}
return rc;
}
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
assert( cursorHoldsMutex(pCur) );
assert( pRes!=0 );
assert( *pRes==0 || *pRes==1 );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
*pRes = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
if( pCur->eState!=CURSOR_VALID
|| pCur->aiIdx[pCur->iPage]==0
|| pCur->apPage[pCur->iPage]->leaf==0
){
return btreePrevious(pCur, pRes);
}
pCur->aiIdx[pCur->iPage]--;
return SQLITE_OK;
}
/*
** Allocate a new page from the database file.
**
** The new page is marked as dirty. (In other words, sqlite3PagerWrite()
** has already been called on the new page.) The new page has also
|
| ︙ | ︙ | |||
60153 60154 60155 60156 60157 60158 60159 |
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
Parse *pParse;
int rc = 0;
pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
if( pParse==0 ){
| | | | | 60617 60618 60619 60620 60621 60622 60623 60624 60625 60626 60627 60628 60629 60630 60631 60632 60633 60634 60635 60636 60637 60638 60639 60640 60641 60642 60643 60644 60645 60646 60647 60648 60649 |
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
Parse *pParse;
int rc = 0;
pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
if( pParse==0 ){
sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
rc = SQLITE_NOMEM;
}else{
pParse->db = pDb;
if( sqlite3OpenTempDatabase(pParse) ){
sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
rc = SQLITE_ERROR;
}
sqlite3DbFree(pErrorDb, pParse->zErrMsg);
sqlite3ParserReset(pParse);
sqlite3StackFree(pErrorDb, pParse);
}
if( rc ){
return 0;
}
}
if( i<0 ){
sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
return 0;
}
return pDb->aDb[i].pBt;
}
/*
|
| ︙ | ︙ | |||
60216 60217 60218 60219 60220 60221 60222 |
** database connection while a backup is in progress may cause
** a malfunction or a deadlock.
*/
sqlite3_mutex_enter(pSrcDb->mutex);
sqlite3_mutex_enter(pDestDb->mutex);
if( pSrcDb==pDestDb ){
| | | | 60680 60681 60682 60683 60684 60685 60686 60687 60688 60689 60690 60691 60692 60693 60694 60695 60696 60697 60698 60699 60700 60701 60702 60703 60704 60705 |
** database connection while a backup is in progress may cause
** a malfunction or a deadlock.
*/
sqlite3_mutex_enter(pSrcDb->mutex);
sqlite3_mutex_enter(pDestDb->mutex);
if( pSrcDb==pDestDb ){
sqlite3ErrorWithMsg(
pDestDb, SQLITE_ERROR, "source and destination must be distinct"
);
p = 0;
}else {
/* Allocate space for a new sqlite3_backup object...
** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
** call to sqlite3_backup_init() and is destroyed by a call to
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
sqlite3Error(pDestDb, SQLITE_NOMEM);
}
}
/* If the allocation succeeded, populate the new object. */
if( p ){
p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
|
| ︙ | ︙ | |||
60668 60669 60670 60671 60672 60673 60674 |
/* If a transaction is still open on the Btree, roll it back. */
sqlite3BtreeRollback(p->pDest, SQLITE_OK);
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
if( p->pDestDb ){
| | | 61132 61133 61134 61135 61136 61137 61138 61139 61140 61141 61142 61143 61144 61145 61146 |
/* If a transaction is still open on the Btree, roll it back. */
sqlite3BtreeRollback(p->pDest, SQLITE_OK);
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
if( p->pDestDb ){
sqlite3Error(p->pDestDb, rc);
/* Exit the mutexes and free the backup context structure. */
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
}
sqlite3BtreeLeave(p->pSrc);
if( p->pDestDb ){
/* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
|
| ︙ | ︙ | |||
60936 60937 60938 60939 60940 60941 60942 |
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
bPreserve = 0;
}else{
sqlite3DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
if( pMem->zMalloc==0 ){
| | | 61400 61401 61402 61403 61404 61405 61406 61407 61408 61409 61410 61411 61412 61413 61414 |
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
bPreserve = 0;
}else{
sqlite3DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
if( pMem->zMalloc==0 ){
VdbeMemReleaseExtern(pMem);
pMem->z = 0;
pMem->flags = MEM_Null;
return SQLITE_NOMEM;
}
}
if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
|
| ︙ | ︙ | |||
61015 61016 61017 61018 61019 61020 61021 |
pMem->n += pMem->u.nZero;
pMem->flags &= ~(MEM_Zero|MEM_Term);
}
return SQLITE_OK;
}
#endif
| < > | | < < < < > > > > > > > > > > > > > > | > | < | > | > > | | > | > > > > > > > > > > > > > > > > > > > > > > > | < | | < | | 61479 61480 61481 61482 61483 61484 61485 61486 61487 61488 61489 61490 61491 61492 61493 61494 61495 61496 61497 61498 61499 61500 61501 61502 61503 61504 61505 61506 61507 61508 61509 61510 61511 61512 61513 61514 61515 61516 61517 61518 61519 61520 61521 61522 61523 61524 61525 61526 61527 61528 61529 61530 61531 61532 61533 61534 61535 61536 61537 61538 61539 61540 61541 61542 61543 61544 61545 61546 61547 61548 61549 61550 61551 61552 61553 61554 61555 61556 61557 61558 61559 61560 61561 61562 61563 61564 61565 61566 61567 61568 61569 61570 61571 61572 61573 61574 61575 61576 61577 61578 61579 61580 61581 61582 61583 61584 61585 61586 61587 61588 61589 61590 61591 61592 61593 61594 61595 61596 61597 61598 61599 61600 61601 61602 61603 61604 61605 61606 61607 61608 61609 61610 61611 61612 61613 61614 61615 61616 61617 61618 61619 61620 61621 61622 61623 61624 61625 61626 61627 61628 61629 61630 61631 61632 61633 61634 61635 61636 61637 61638 61639 61640 61641 61642 61643 61644 61645 61646 61647 61648 61649 61650 61651 61652 61653 61654 61655 61656 61657 61658 61659 |
pMem->n += pMem->u.nZero;
pMem->flags &= ~(MEM_Zero|MEM_Term);
}
return SQLITE_OK;
}
#endif
/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
return SQLITE_NOMEM;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
/*
** Make sure the given Mem is \u0000 terminated.
*/
SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) );
testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 );
if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){
return SQLITE_OK; /* Nothing to do */
}else{
return vdbeMemAddTerminator(pMem);
}
}
/*
** Add MEM_Str to the set of representations for the given Mem. Numbers
** are converted using sqlite3_snprintf(). Converting a BLOB to a string
** is a no-op.
**
** Existing representations MEM_Int and MEM_Real are invalidated if
** bForce is true but are retained if bForce is false.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
** sqlite3_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error.
*/
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
int fg = pMem->flags;
const int nByte = 32;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( !(fg&MEM_Zero) );
assert( !(fg&(MEM_Str|MEM_Blob)) );
assert( fg&(MEM_Int|MEM_Real) );
assert( (pMem->flags&MEM_RowSet)==0 );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
return SQLITE_NOMEM;
}
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
** string representation of the value. Then, if the required encoding
** is UTF-16le or UTF-16be do a translation.
**
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
*/
if( fg & MEM_Int ){
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
}else{
assert( fg & MEM_Real );
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
}
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
sqlite3VdbeChangeEncoding(pMem, enc);
return SQLITE_OK;
}
/*
** Memory cell pMem contains the context of an aggregate function.
** This routine calls the finalize method for that function. The
** result of the aggregate is stored back into pMem.
**
** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK
** otherwise.
*/
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
int rc = SQLITE_OK;
if( ALWAYS(pFunc && pFunc->xFinalize) ){
sqlite3_context ctx;
Mem t;
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
memset(&ctx, 0, sizeof(ctx));
memset(&t, 0, sizeof(t));
t.flags = MEM_Null;
t.db = pMem->db;
ctx.pOut = &t;
ctx.pMem = pMem;
ctx.pFunc = pFunc;
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
sqlite3DbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
rc = ctx.isError;
}
return rc;
}
/*
** If the memory cell contains a string value that must be freed by
** invoking an external callback, free it now. Calling this function
** does not free any Mem.zMalloc buffer.
**
** The VdbeMemReleaseExtern() macro invokes this routine if only if there
** is work for this routine to do.
*/
SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
if( p->flags&MEM_Agg ){
sqlite3VdbeMemFinalize(p, p->u.pDef);
assert( (p->flags & MEM_Agg)==0 );
sqlite3VdbeMemRelease(p);
}else if( p->flags&MEM_Dyn ){
assert( (p->flags&MEM_RowSet)==0 );
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
p->xDel((void *)p->z);
p->xDel = 0;
}else if( p->flags&MEM_RowSet ){
sqlite3RowSetClear(p->u.pRowSet);
}else if( p->flags&MEM_Frame ){
sqlite3VdbeMemSetNull(p);
}
}
/*
** Release memory held by the Mem p, both external memory cleared
** by p->xDel and memory in p->zMalloc.
**
** This is a helper routine invoked by sqlite3VdbeMemRelease() in
** the uncommon case when there really is memory in p that is
** need of freeing.
*/
static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){
if( VdbeMemDynamic(p) ){
sqlite3VdbeMemReleaseExternal(p);
}
if( p->zMalloc ){
sqlite3DbFree(p->db, p->zMalloc);
p->zMalloc = 0;
}
p->z = 0;
}
/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.flags==MEM_Str).
*/
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
assert( sqlite3VdbeCheckMemInvariants(p) );
if( VdbeMemDynamic(p) || p->zMalloc ){
vdbeMemRelease(p);
}else{
p->z = 0;
}
assert( p->xDel==0 );
}
/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is out of range of a 64-bit signed integer then
** return the closest available 64-bit signed integer.
*/
|
| ︙ | ︙ | |||
61202 61203 61204 61205 61206 61207 61208 |
if( flags & MEM_Int ){
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->r);
}else if( flags & (MEM_Str|MEM_Blob) ){
i64 value = 0;
assert( pMem->z || pMem->n==0 );
| < | 61701 61702 61703 61704 61705 61706 61707 61708 61709 61710 61711 61712 61713 61714 |
if( flags & MEM_Int ){
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->r);
}else if( flags & (MEM_Str|MEM_Blob) ){
i64 value = 0;
assert( pMem->z || pMem->n==0 );
sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
return value;
}else{
return 0;
}
}
|
| ︙ | ︙ | |||
61314 61315 61316 61317 61318 61319 61320 61321 61322 61323 61324 61325 61326 61327 |
sqlite3VdbeIntegerAffinity(pMem);
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob);
return SQLITE_OK;
}
/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
if( pMem->flags & MEM_Frame ){
VdbeFrame *pFrame = pMem->u.pFrame;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 61812 61813 61814 61815 61816 61817 61818 61819 61820 61821 61822 61823 61824 61825 61826 61827 61828 61829 61830 61831 61832 61833 61834 61835 61836 61837 61838 61839 61840 61841 61842 61843 61844 61845 61846 61847 61848 61849 61850 61851 61852 61853 61854 61855 61856 61857 61858 61859 61860 61861 61862 61863 61864 61865 61866 61867 61868 61869 61870 |
sqlite3VdbeIntegerAffinity(pMem);
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob);
return SQLITE_OK;
}
/*
** Cast the datatype of the value in pMem according to the affinity
** "aff". Casting is different from applying affinity in that a cast
** is forced. In other words, the value is converted into the desired
** affinity even if that results in loss of data. This routine is
** used (for example) to implement the SQL "cast()" operator.
*/
SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
if( pMem->flags & MEM_Null ) return;
switch( aff ){
case SQLITE_AFF_NONE: { /* Really a cast to BLOB */
if( (pMem->flags & MEM_Blob)==0 ){
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
MemSetTypeFlag(pMem, MEM_Blob);
}else{
pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
}
break;
}
case SQLITE_AFF_NUMERIC: {
sqlite3VdbeMemNumerify(pMem);
break;
}
case SQLITE_AFF_INTEGER: {
sqlite3VdbeMemIntegerify(pMem);
break;
}
case SQLITE_AFF_REAL: {
sqlite3VdbeMemRealify(pMem);
break;
}
default: {
assert( aff==SQLITE_AFF_TEXT );
assert( MEM_Str==(MEM_Blob>>3) );
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
break;
}
}
}
/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
if( pMem->flags & MEM_Frame ){
VdbeFrame *pFrame = pMem->u.pFrame;
|
| ︙ | ︙ | |||
61353 61354 61355 61356 61357 61358 61359 61360 61361 61362 61363 61364 61365 |
sqlite3VdbeMemGrow(pMem, n, 0);
if( pMem->z ){
pMem->n = n;
memset(pMem->z, 0, n);
}
#endif
}
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
| > > > > > > > > > > > | > > | | > | 61896 61897 61898 61899 61900 61901 61902 61903 61904 61905 61906 61907 61908 61909 61910 61911 61912 61913 61914 61915 61916 61917 61918 61919 61920 61921 61922 61923 61924 61925 61926 61927 61928 61929 61930 61931 61932 |
sqlite3VdbeMemGrow(pMem, n, 0);
if( pMem->z ){
pMem->n = n;
memset(pMem->z, 0, n);
}
#endif
}
/*
** The pMem is known to contain content that needs to be destroyed prior
** to a value change. So invoke the destructor, then set the value to
** a 64-bit integer.
*/
static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){
sqlite3VdbeMemReleaseExternal(pMem);
pMem->u.i = val;
pMem->flags = MEM_Int;
}
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
if( VdbeMemDynamic(pMem) ){
vdbeReleaseAndSetInt64(pMem, val);
}else{
pMem->u.i = val;
pMem->flags = MEM_Int;
}
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type REAL.
*/
|
| ︙ | ︙ | |||
61452 61453 61454 61455 61456 61457 61458 |
** Make an shallow copy of pFrom into pTo. Prior contents of
** pTo are freed. The pFrom->z field is not duplicated. If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
assert( (pFrom->flags & MEM_RowSet)==0 );
| | | | 62009 62010 62011 62012 62013 62014 62015 62016 62017 62018 62019 62020 62021 62022 62023 62024 62025 62026 62027 62028 62029 62030 62031 62032 62033 62034 62035 62036 62037 62038 62039 62040 62041 |
** Make an shallow copy of pFrom into pTo. Prior contents of
** pTo are freed. The pFrom->z field is not duplicated. If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
assert( (pFrom->flags & MEM_RowSet)==0 );
VdbeMemReleaseExtern(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->xDel = 0;
if( (pFrom->flags&MEM_Static)==0 ){
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
assert( srcType==MEM_Ephem || srcType==MEM_Static );
pTo->flags |= srcType;
}
}
/*
** Make a full copy of pFrom into pTo. Prior contents of pTo are
** freed before the copy is made.
*/
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
int rc = SQLITE_OK;
assert( (pFrom->flags & MEM_RowSet)==0 );
VdbeMemReleaseExtern(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->flags &= ~MEM_Dyn;
pTo->xDel = 0;
if( pTo->flags&(MEM_Str|MEM_Blob) ){
if( 0==(pFrom->flags&MEM_Static) ){
pTo->flags |= MEM_Ephem;
|
| ︙ | ︙ | |||
61657 61658 61659 61660 61661 61662 61663 61664 61665 61666 61667 61668 61669 61670 61671 61672 61673 61674 61675 61676 |
}else{
sqlite3VdbeMemRelease(pMem);
}
}
return rc;
}
/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite3_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
**
** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
** If that is the case, then the result must be aligned on an even byte
** boundary.
*/
SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
if( !pVal ) return 0;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | < | < < < | < < < < | | < < < < < < < < < < < < | < | 62214 62215 62216 62217 62218 62219 62220 62221 62222 62223 62224 62225 62226 62227 62228 62229 62230 62231 62232 62233 62234 62235 62236 62237 62238 62239 62240 62241 62242 62243 62244 62245 62246 62247 62248 62249 62250 62251 62252 62253 62254 62255 62256 62257 62258 62259 62260 62261 62262 62263 62264 62265 62266 62267 62268 62269 62270 62271 62272 62273 62274 62275 62276 62277 62278 62279 62280 62281 62282 62283 62284 62285 62286 62287 62288 62289 |
}else{
sqlite3VdbeMemRelease(pMem);
}
}
return rc;
}
/*
** The pVal argument is known to be a value other than NULL.
** Convert it into a string with encoding enc and return a pointer
** to a zero-terminated version of that string.
*/
SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert( pVal!=0 );
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( (pVal->flags & MEM_RowSet)==0 );
assert( (pVal->flags & (MEM_Null))==0 );
if( pVal->flags & (MEM_Blob|MEM_Str) ){
pVal->flags |= MEM_Str;
if( pVal->flags & MEM_Zero ){
sqlite3VdbeMemExpandBlob(pVal);
}
if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){
sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
}
if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
return 0;
}
}
sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
}else{
sqlite3VdbeMemStringify(pVal, enc, 0);
assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
}
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
return pVal->z;
}else{
return 0;
}
}
/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite3_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
**
** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
** If that is the case, then the result must be aligned on an even byte
** boundary.
*/
SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
if( !pVal ) return 0;
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( (pVal->flags & MEM_RowSet)==0 );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
return pVal->z;
}
if( pVal->flags&MEM_Null ){
return 0;
}
return valueToText(pVal, enc);
}
/*
** Create a new sqlite3_value object.
*/
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
|
| ︙ | ︙ | |||
61808 61809 61810 61811 61812 61813 61814 |
const char *zNeg = "";
int rc = SQLITE_OK;
if( !pExpr ){
*ppVal = 0;
return SQLITE_OK;
}
| | > > > > > > > > > > > | 62382 62383 62384 62385 62386 62387 62388 62389 62390 62391 62392 62393 62394 62395 62396 62397 62398 62399 62400 62401 62402 62403 62404 62405 62406 62407 62408 |
const char *zNeg = "";
int rc = SQLITE_OK;
if( !pExpr ){
*ppVal = 0;
return SQLITE_OK;
}
while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
if( op==TK_CAST ){
u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
testcase( rc!=SQLITE_OK );
if( *ppVal ){
sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
}
return rc;
}
/* Handle negative integers in a single step. This is needed in the
** case when the value is -9223372036854775808.
*/
if( op==TK_UMINUS
&& (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
pExpr = pExpr->pLeft;
|
| ︙ | ︙ | |||
61945 61946 61947 61948 61949 61950 61951 |
nRet = 1 + nSerial + nVal;
aRet = sqlite3DbMallocRaw(db, nRet);
if( aRet==0 ){
sqlite3_result_error_nomem(context);
}else{
aRet[0] = nSerial+1;
| | | 62530 62531 62532 62533 62534 62535 62536 62537 62538 62539 62540 62541 62542 62543 62544 |
nRet = 1 + nSerial + nVal;
aRet = sqlite3DbMallocRaw(db, nRet);
if( aRet==0 ){
sqlite3_result_error_nomem(context);
}else{
aRet[0] = nSerial+1;
putVarint32(&aRet[1], iSerial);
sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
sqlite3DbFree(db, aRet);
}
}
/*
|
| ︙ | ︙ | |||
64707 64708 64709 64710 64711 64712 64713 |
sqlite3BeginBenignMalloc();
if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite3EndBenignMalloc();
db->mallocFailed = mallocFailed;
db->errCode = rc;
}else{
| | | 65292 65293 65294 65295 65296 65297 65298 65299 65300 65301 65302 65303 65304 65305 65306 |
sqlite3BeginBenignMalloc();
if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite3EndBenignMalloc();
db->mallocFailed = mallocFailed;
db->errCode = rc;
}else{
sqlite3Error(db, rc);
}
return rc;
}
#ifdef SQLITE_ENABLE_SQLLOG
/*
** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run,
|
| ︙ | ︙ | |||
64770 64771 64772 64773 64774 64775 64776 |
p->zErrMsg = 0;
if( p->runOnlyOnce ) p->expired = 1;
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
** to sqlite3_step(). For consistency (since sqlite3_step() was
** called), set the database error in this case as well.
*/
| | | 65355 65356 65357 65358 65359 65360 65361 65362 65363 65364 65365 65366 65367 65368 65369 |
p->zErrMsg = 0;
if( p->runOnlyOnce ) p->expired = 1;
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
** to sqlite3_step(). For consistency (since sqlite3_step() was
** called), set the database error in this case as well.
*/
sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
/* Reclaim all memory used by the VDBE
*/
Cleanup(p);
|
| ︙ | ︙ | |||
64922 64923 64924 64925 64926 64927 64928 64929 64930 64931 64932 64933 64934 64935 64936 64937 64938 64939 64940 64941 64942 64943 64944 |
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
}
p->magic = VDBE_MAGIC_DEAD;
p->db = 0;
sqlite3DbFree(db, p);
}
/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned. Return an error code if an OOM fault or I/O error
** prevents us from positioning the cursor to its correct position.
**
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now. If no move is pending, check to see if the row has been
** deleted out from under the cursor and if it has, mark the row as
** a NULL row.
**
** If the cursor is already pointing to the correct row and that row has
** not been deleted out from under the cursor, then this routine is a no-op.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
if( p->deferredMoveto ){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < | < < < < < < < < | > > | 65507 65508 65509 65510 65511 65512 65513 65514 65515 65516 65517 65518 65519 65520 65521 65522 65523 65524 65525 65526 65527 65528 65529 65530 65531 65532 65533 65534 65535 65536 65537 65538 65539 65540 65541 65542 65543 65544 65545 65546 65547 65548 65549 65550 65551 65552 65553 65554 65555 65556 65557 65558 65559 65560 65561 65562 65563 65564 65565 65566 65567 65568 65569 65570 65571 65572 65573 65574 65575 65576 65577 65578 65579 65580 65581 65582 |
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
}
p->magic = VDBE_MAGIC_DEAD;
p->db = 0;
sqlite3DbFree(db, p);
}
/*
** The cursor "p" has a pending seek operation that has not yet been
** carried out. Seek the cursor now. If an error occurs, return
** the appropriate error code.
*/
static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
int res, rc;
#ifdef SQLITE_TEST
extern int sqlite3_search_count;
#endif
assert( p->deferredMoveto );
assert( p->isTable );
rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
if( rc ) return rc;
p->lastRowid = p->movetoTarget;
if( res!=0 ) return SQLITE_CORRUPT_BKPT;
p->rowidIsValid = 1;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
p->deferredMoveto = 0;
p->cacheStatus = CACHE_STALE;
return SQLITE_OK;
}
/*
** Something has moved cursor "p" out of place. Maybe the row it was
** pointed to was deleted out from under it. Or maybe the btree was
** rebalanced. Whatever the cause, try to restore "p" to the place it
** is suppose to be pointing. If the row was deleted out from under the
** cursor, set the cursor to point to a NULL row.
*/
static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
int isDifferentRow, rc;
assert( p->pCursor!=0 );
assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
p->cacheStatus = CACHE_STALE;
if( isDifferentRow ) p->nullRow = 1;
return rc;
}
/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned. Return an error code if an OOM fault or I/O error
** prevents us from positioning the cursor to its correct position.
**
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now. If no move is pending, check to see if the row has been
** deleted out from under the cursor and if it has, mark the row as
** a NULL row.
**
** If the cursor is already pointing to the correct row and that row has
** not been deleted out from under the cursor, then this routine is a no-op.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
if( p->deferredMoveto ){
return handleDeferredMoveto(p);
}
if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
}
/*
** The following functions:
**
|
| ︙ | ︙ | |||
65143 65144 65145 65146 65147 65148 65149 |
assert( sizeof(v)==sizeof(pMem->r) );
memcpy(&v, &pMem->r, sizeof(v));
swapMixedEndianFloat(v);
}else{
v = pMem->u.i;
}
len = i = sqlite3VdbeSerialTypeLen(serial_type);
| | > | | | 65751 65752 65753 65754 65755 65756 65757 65758 65759 65760 65761 65762 65763 65764 65765 65766 65767 65768 65769 |
assert( sizeof(v)==sizeof(pMem->r) );
memcpy(&v, &pMem->r, sizeof(v));
swapMixedEndianFloat(v);
}else{
v = pMem->u.i;
}
len = i = sqlite3VdbeSerialTypeLen(serial_type);
assert( i>0 );
do{
buf[--i] = (u8)(v&0xFF);
v >>= 8;
}while( i );
return len;
}
/* String or blob */
if( serial_type>=12 ){
assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
== (int)sqlite3VdbeSerialTypeLen(serial_type) );
|
| ︙ | ︙ | |||
65170 65171 65172 65173 65174 65175 65176 65177 65178 65179 65180 65181 65182 65183 65184 65185 65186 |
/* Input "x" is a sequence of unsigned characters that represent a
** big-endian integer. Return the equivalent native integer
*/
#define ONE_BYTE_INT(x) ((i8)(x)[0])
#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1])
#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
*/
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < | 65779 65780 65781 65782 65783 65784 65785 65786 65787 65788 65789 65790 65791 65792 65793 65794 65795 65796 65797 65798 65799 65800 65801 65802 65803 65804 65805 65806 65807 65808 65809 65810 65811 65812 65813 65814 65815 65816 65817 65818 65819 65820 65821 65822 65823 65824 65825 65826 65827 65828 65829 65830 65831 65832 65833 65834 65835 65836 65837 65838 65839 65840 |
/* Input "x" is a sequence of unsigned characters that represent a
** big-endian integer. Return the equivalent native integer
*/
#define ONE_BYTE_INT(x) ((i8)(x)[0])
#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1])
#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
**
** This function is implemented as two separate routines for performance.
** The few cases that require local variables are broken out into a separate
** routine so that in most cases the overhead of moving the stack pointer
** is avoided.
*/
static u32 SQLITE_NOINLINE serialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
u64 x = FOUR_BYTE_UINT(buf);
u32 y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) + y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
}else{
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
** defined that 64-bit floating point values really are mixed
** endian.
*/
static const u64 t1 = ((u64)0x3ff00000)<<32;
static const double r1 = 1.0;
u64 t2 = t1;
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->r, &x, sizeof(x));
pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
}
return 8;
}
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
case 0: { /* NULL */
pMem->flags = MEM_Null;
break;
}
|
| ︙ | ︙ | |||
65208 65209 65210 65211 65212 65213 65214 |
case 3: { /* 3-byte signed integer */
pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 3;
}
case 4: { /* 4-byte signed integer */
| | < | | < < < < < < < < < < < < < < < < < < < < < < < | < | | < | 65853 65854 65855 65856 65857 65858 65859 65860 65861 65862 65863 65864 65865 65866 65867 65868 65869 65870 65871 65872 65873 65874 65875 65876 65877 65878 65879 65880 65881 65882 65883 65884 65885 65886 65887 65888 65889 65890 65891 65892 65893 65894 65895 65896 65897 65898 65899 65900 |
case 3: { /* 3-byte signed integer */
pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 3;
}
case 4: { /* 4-byte signed integer */
pMem->u.i = FOUR_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
}
case 5: { /* 6-byte signed integer */
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 6;
}
case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */
/* These use local variables, so do them in a separate routine
** to avoid having to move the frame pointer in the common case */
return serialGet(buf,serial_type,pMem);
}
case 8: /* Integer 0 */
case 9: { /* Integer 1 */
pMem->u.i = serial_type-8;
pMem->flags = MEM_Int;
return 0;
}
default: {
static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
pMem->z = (char *)buf;
pMem->n = (serial_type-12)/2;
pMem->xDel = 0;
pMem->flags = aFlag[serial_type&1];
return pMem->n;
}
}
return 0;
}
/*
** This routine is used to allocate sufficient space for an UnpackedRecord
** structure large enough to be used with sqlite3VdbeRecordUnpack() if
** the first argument is a pointer to KeyInfo structure pKeyInfo.
**
** The space is either allocated using sqlite3DbMallocRaw() or from within
** the unaligned buffer passed via the second and third arguments (presumably
|
| ︙ | ︙ | |||
65361 65362 65363 65364 65365 65366 65367 65368 65369 65370 | /* ** This function compares two index or table record keys in the same way ** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), ** this function deserializes and compares values using the ** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used ** in assert() statements to ensure that the optimized code in ** sqlite3VdbeRecordCompare() returns results with these two primitives. */ static int vdbeRecordCompareDebug( int nKey1, const void *pKey1, /* Left key */ | > > > | > > | 65980 65981 65982 65983 65984 65985 65986 65987 65988 65989 65990 65991 65992 65993 65994 65995 65996 65997 65998 65999 66000 66001 66002 66003 66004 66005 66006 66007 66008 66009 66010 66011 66012 66013 |
/*
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
** this function deserializes and compares values using the
** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
** in assert() statements to ensure that the optimized code in
** sqlite3VdbeRecordCompare() returns results with these two primitives.
**
** Return true if the result of comparison is equivalent to desiredResult.
** Return false if there is a disagreement.
*/
static int vdbeRecordCompareDebug(
int nKey1, const void *pKey1, /* Left key */
const UnpackedRecord *pPKey2, /* Right key */
int desiredResult /* Correct answer */
){
u32 d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
u32 szHdr1; /* Number of bytes in header */
int i = 0;
int rc = 0;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
KeyInfo *pKeyInfo;
Mem mem1;
pKeyInfo = pPKey2->pKeyInfo;
if( pKeyInfo->db==0 ) return 1;
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
/* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */
VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
/* Compilers may complain that mem1.u.i is potentially uninitialized.
** We could initialize it, as shown here, to silence those complaints.
|
| ︙ | ︙ | |||
65426 65427 65428 65429 65430 65431 65432 |
*/
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
if( rc!=0 ){
assert( mem1.zMalloc==0 ); /* See comment below */
if( pKeyInfo->aSortOrder[i] ){
rc = -rc; /* Invert the result for DESC sort order. */
}
| | | > > > > > > > > | > | 66050 66051 66052 66053 66054 66055 66056 66057 66058 66059 66060 66061 66062 66063 66064 66065 66066 66067 66068 66069 66070 66071 66072 66073 66074 66075 66076 66077 66078 66079 66080 66081 66082 66083 66084 66085 66086 66087 66088 66089 66090 66091 66092 66093 66094 66095 66096 66097 66098 66099 66100 |
*/
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
if( rc!=0 ){
assert( mem1.zMalloc==0 ); /* See comment below */
if( pKeyInfo->aSortOrder[i] ){
rc = -rc; /* Invert the result for DESC sort order. */
}
goto debugCompareEnd;
}
i++;
}while( idx1<szHdr1 && i<pPKey2->nField );
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
*/
assert( mem1.zMalloc==0 );
/* rc==0 here means that one of the keys ran out of fields and
** all the fields up to that point were equal. Return the the default_rc
** value. */
rc = pPKey2->default_rc;
debugCompareEnd:
if( desiredResult==0 && rc==0 ) return 1;
if( desiredResult<0 && rc<0 ) return 1;
if( desiredResult>0 && rc>0 ) return 1;
if( CORRUPT_DB ) return 1;
if( pKeyInfo->db->mallocFailed ) return 1;
return 0;
}
#endif
/*
** Both *pMem1 and *pMem2 contain string values. Compare the two values
** using the collation sequence pColl. As usual, return a negative , zero
** or positive value if *pMem1 is less than, equal to or greater than
** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);".
*/
static int vdbeCompareMemString(
const Mem *pMem1,
const Mem *pMem2,
const CollSeq *pColl,
u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */
){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
int rc;
|
| ︙ | ︙ | |||
65476 65477 65478 65479 65480 65481 65482 65483 65484 65485 65486 65487 65488 65489 |
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
n1 = v1==0 ? 0 : c1.n;
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
}
}
/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
| > | 66109 66110 66111 66112 66113 66114 66115 66116 66117 66118 66119 66120 66121 66122 66123 |
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
n1 = v1==0 ? 0 : c1.n;
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
return rc;
}
}
/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
|
| ︙ | ︙ | |||
65558 65559 65560 65561 65562 65563 65564 |
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
assert( !pColl || pColl->xCmp );
if( pColl ){
| | | 66192 66193 66194 66195 66196 66197 66198 66199 66200 66201 66202 66203 66204 66205 66206 |
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
assert( !pColl || pColl->xCmp );
if( pColl ){
return vdbeCompareMemString(pMem1, pMem2, pColl, 0);
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
}
/* Both values must be blobs. Compare using memcmp(). */
rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
|
| ︙ | ︙ | |||
65630 65631 65632 65633 65634 65635 65636 | ** If argument bSkip is non-zero, it is assumed that the caller has already ** determined that the first fields of the keys are equal. ** ** Key1 and Key2 do not have to contain the same number of fields. If all ** fields that appear in both keys are equal, then pPKey2->default_rc is ** returned. ** | | | > > | 66264 66265 66266 66267 66268 66269 66270 66271 66272 66273 66274 66275 66276 66277 66278 66279 66280 66281 |
** If argument bSkip is non-zero, it is assumed that the caller has already
** determined that the first fields of the keys are equal.
**
** Key1 and Key2 do not have to contain the same number of fields. If all
** fields that appear in both keys are equal, then pPKey2->default_rc is
** returned.
**
** If database corruption is discovered, set pPKey2->errCode to
** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */
){
u32 d1; /* Offset into aKey[] of next data element */
|
| ︙ | ︙ | |||
65662 65663 65664 65665 65666 65667 65668 |
d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
i = 1;
pRhs++;
}else{
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
if( d1>(unsigned)nKey1 ){
| | | 66298 66299 66300 66301 66302 66303 66304 66305 66306 66307 66308 66309 66310 66311 66312 |
d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
i = 1;
pRhs++;
}else{
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
if( d1>(unsigned)nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}
i = 0;
}
VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
|
| ︙ | ︙ | |||
65741 65742 65743 65744 65745 65746 65747 |
}else if( !(serial_type & 0x01) ){
rc = +1;
}else{
mem1.n = (serial_type - 12) / 2;
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
if( (d1+mem1.n) > (unsigned)nKey1 ){
| | | > > | < | < < < | | 66377 66378 66379 66380 66381 66382 66383 66384 66385 66386 66387 66388 66389 66390 66391 66392 66393 66394 66395 66396 66397 66398 66399 66400 66401 66402 66403 66404 66405 66406 66407 66408 66409 66410 66411 66412 66413 66414 66415 66416 66417 66418 66419 66420 66421 66422 66423 66424 66425 66426 66427 66428 66429 66430 66431 66432 66433 66434 66435 66436 66437 66438 66439 66440 66441 66442 66443 66444 66445 66446 66447 66448 66449 66450 66451 66452 66453 66454 66455 66456 66457 66458 66459 66460 |
}else if( !(serial_type & 0x01) ){
rc = +1;
}else{
mem1.n = (serial_type - 12) / 2;
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
if( (d1+mem1.n) > (unsigned)nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}else if( pKeyInfo->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
mem1.z = (char*)&aKey1[d1];
rc = vdbeCompareMemString(
&mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode
);
}else{
int nCmp = MIN(mem1.n, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
if( rc==0 ) rc = mem1.n - pRhs->n;
}
}
}
/* RHS is a blob */
else if( pRhs->flags & MEM_Blob ){
getVarint32(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 || (serial_type & 0x01) ){
rc = -1;
}else{
int nStr = (serial_type - 12) / 2;
testcase( (d1+nStr)==(unsigned)nKey1 );
testcase( (d1+nStr+1)==(unsigned)nKey1 );
if( (d1+nStr) > (unsigned)nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}else{
int nCmp = MIN(nStr, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
if( rc==0 ) rc = nStr - pRhs->n;
}
}
}
/* RHS is null */
else{
serial_type = aKey1[idx1];
rc = (serial_type!=0);
}
if( rc!=0 ){
if( pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
assert( mem1.zMalloc==0 ); /* See comment below */
return rc;
}
i++;
pRhs++;
d1 += sqlite3VdbeSerialTypeLen(serial_type);
idx1 += sqlite3VarintLen(serial_type);
}while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */
assert( mem1.zMalloc==0 );
/* rc==0 here means that one or both of the keys ran out of fields and
** all the fields up to that point were equal. Return the the default_rc
** value. */
assert( CORRUPT_DB
|| vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc)
|| pKeyInfo->db->mallocFailed
);
return pPKey2->default_rc;
}
/*
** This function is an optimized version of sqlite3VdbeRecordCompare()
|
| ︙ | ︙ | |||
65911 65912 65913 65914 65915 65916 65917 |
res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
}else{
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
res = pPKey2->default_rc;
}
| < | < < < | 66545 66546 66547 66548 66549 66550 66551 66552 66553 66554 66555 66556 66557 66558 66559 |
res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
}else{
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
res = pPKey2->default_rc;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
return res;
}
/*
** This function is an optimized version of sqlite3VdbeRecordCompare()
** that (a) the first field of pPKey2 is a string, that (b) the first field
** uses the collation sequence BINARY and (c) that the size-of-header varint
|
| ︙ | ︙ | |||
65949 65950 65951 65952 65953 65954 65955 |
}else{
int nCmp;
int nStr;
int szHdr = aKey1[0];
nStr = (serial_type-12) / 2;
if( (szHdr + nStr) > nKey1 ){
| | | 66579 66580 66581 66582 66583 66584 66585 66586 66587 66588 66589 66590 66591 66592 66593 |
}else{
int nCmp;
int nStr;
int szHdr = aKey1[0];
nStr = (serial_type-12) / 2;
if( (szHdr + nStr) > nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}
nCmp = MIN( pPKey2->aMem[0].n, nStr );
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
if( res==0 ){
res = nStr - pPKey2->aMem[0].n;
|
| ︙ | ︙ | |||
65975 65976 65977 65978 65979 65980 65981 |
}else if( res>0 ){
res = pPKey2->r2;
}else{
res = pPKey2->r1;
}
}
| < | < | 66605 66606 66607 66608 66609 66610 66611 66612 66613 66614 66615 66616 66617 66618 66619 |
}else if( res>0 ){
res = pPKey2->r2;
}else{
res = pPKey2->r1;
}
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res)
|| CORRUPT_DB
|| pPKey2->pKeyInfo->db->mallocFailed
);
return res;
}
/*
|
| ︙ | ︙ | |||
66464 66465 66466 66467 66468 66469 66470 |
static void setResultStrOrError(
sqlite3_context *pCtx, /* Function context */
const char *z, /* String pointer */
int n, /* Bytes in string, or negative */
u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */
){
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 67092 67093 67094 67095 67096 67097 67098 67099 67100 67101 67102 67103 67104 67105 67106 67107 67108 67109 67110 67111 67112 67113 67114 67115 67116 67117 67118 67119 67120 67121 67122 67123 67124 67125 67126 67127 67128 67129 67130 67131 67132 67133 67134 67135 67136 67137 67138 67139 67140 67141 67142 67143 67144 67145 67146 67147 67148 67149 67150 67151 67152 67153 67154 67155 67156 67157 67158 67159 67160 67161 67162 67163 67164 67165 67166 67167 67168 67169 67170 67171 67172 67173 67174 67175 67176 67177 67178 67179 67180 67181 67182 67183 67184 67185 67186 67187 67188 67189 67190 67191 67192 67193 67194 67195 67196 67197 67198 67199 67200 67201 67202 67203 67204 67205 67206 67207 67208 67209 67210 67211 67212 67213 67214 67215 67216 67217 67218 67219 67220 |
static void setResultStrOrError(
sqlite3_context *pCtx, /* Function context */
const char *z, /* String pointer */
int n, /* Bytes in string, or negative */
u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */
){
if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){
sqlite3_result_error_toobig(pCtx);
}
}
SQLITE_API void sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( n>=0 );
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
}
SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
}
SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
SQLITE_API void sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
SQLITE_API void sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
SQLITE_API void sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pCtx->pOut, pValue);
}
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
}
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
if( pCtx->pOut->flags & MEM_Null ){
sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
}
}
/* Force an SQLITE_TOOBIG error. */
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
/* An SQLITE_NOMEM error. */
SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM;
pCtx->fErrorOrAux = 1;
pCtx->pOut->db->mallocFailed = 1;
}
/*
** This function is called after a transaction has been committed. It
** invokes callbacks registered with sqlite3_wal_hook() as required.
*/
static int doWalCallbacks(sqlite3 *db){
|
| ︙ | ︙ | |||
66754 66755 66756 66757 66758 66759 66760 |
if( vdbeSafetyNotNull(v) ){
return SQLITE_MISUSE_BKPT;
}
db = v->db;
sqlite3_mutex_enter(db->mutex);
v->doingRerun = 0;
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
| | > | > | | 67382 67383 67384 67385 67386 67387 67388 67389 67390 67391 67392 67393 67394 67395 67396 67397 67398 67399 67400 67401 |
if( vdbeSafetyNotNull(v) ){
return SQLITE_MISUSE_BKPT;
}
db = v->db;
sqlite3_mutex_enter(db->mutex);
v->doingRerun = 0;
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
int savedPc = v->pc;
rc2 = rc = sqlite3Reprepare(v);
if( rc!=SQLITE_OK) break;
sqlite3_reset(pStmt);
if( savedPc>=0 ) v->doingRerun = 1;
assert( v->expired==0 );
}
if( rc2!=SQLITE_OK ){
/* This case occurs after failing to recompile an sql statement.
** The error message from the SQL compiler has already been loaded
** into the database handle. This block copies the error message
** from the database handle into the statement and sets the statement
|
| ︙ | ︙ | |||
66807 66808 66809 66810 66811 66812 66813 |
** returns a copy of the pointer to the database connection (the 1st
** parameter) of the sqlite3_create_function() and
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
assert( p && p->pFunc );
| | | | 67437 67438 67439 67440 67441 67442 67443 67444 67445 67446 67447 67448 67449 67450 67451 67452 67453 67454 67455 67456 67457 67458 67459 67460 67461 |
** returns a copy of the pointer to the database connection (the 1st
** parameter) of the sqlite3_create_function() and
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
assert( p && p->pFunc );
return p->pOut->db;
}
/*
** Return the current time for a statement
*/
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
Vdbe *v = p->pVdbe;
int rc;
if( v->iCurrentTime==0 ){
rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime);
if( rc ) v->iCurrentTime = 0;
}
return v->iCurrentTime;
}
/*
** The following is the implementation of an SQL function that always
|
| ︙ | ︙ | |||
66844 66845 66846 66847 66848 66849 66850 66851 66852 66853 66854 66855 66856 66857 |
char *zErr;
UNUSED_PARAMETER2(NotUsed, NotUsed2);
zErr = sqlite3_mprintf(
"unable to use function %s in the requested context", zName);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
}
/*
** Allocate or return the aggregate context for a user function. A new
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
| > > > > > > > > > > > > > > > > > > > > > > < | < | | < < < | < < < | < | < < < | | 67474 67475 67476 67477 67478 67479 67480 67481 67482 67483 67484 67485 67486 67487 67488 67489 67490 67491 67492 67493 67494 67495 67496 67497 67498 67499 67500 67501 67502 67503 67504 67505 67506 67507 67508 67509 67510 67511 67512 67513 67514 67515 67516 67517 67518 67519 67520 67521 67522 67523 67524 67525 67526 67527 67528 67529 67530 67531 67532 67533 67534 |
char *zErr;
UNUSED_PARAMETER2(NotUsed, NotUsed2);
zErr = sqlite3_mprintf(
"unable to use function %s in the requested context", zName);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
}
/*
** Create a new aggregate context for p and return a pointer to
** its pMem->z element.
*/
static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
Mem *pMem = p->pMem;
assert( (pMem->flags & MEM_Agg)==0 );
if( nByte<=0 ){
sqlite3VdbeMemReleaseExternal(pMem);
pMem->flags = MEM_Null;
pMem->z = 0;
}else{
sqlite3VdbeMemGrow(pMem, nByte, 0);
pMem->flags = MEM_Agg;
pMem->u.pDef = p->pFunc;
if( pMem->z ){
memset(pMem->z, 0, nByte);
}
}
return (void*)pMem->z;
}
/*
** Allocate or return the aggregate context for a user function. A new
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
assert( sqlite3_mutex_held(p->pOut->db->mutex) );
testcase( nByte<0 );
if( (p->pMem->flags & MEM_Agg)==0 ){
return createAggContext(p, nByte);
}else{
return (void*)p->pMem->z;
}
}
/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
return (pAuxData ? pAuxData->pAux : 0);
}
|
| ︙ | ︙ | |||
66902 66903 66904 66905 66906 66907 66908 |
int iArg,
void *pAux,
void (*xDelete)(void*)
){
AuxData *pAuxData;
Vdbe *pVdbe = pCtx->pVdbe;
| | | 67542 67543 67544 67545 67546 67547 67548 67549 67550 67551 67552 67553 67554 67555 67556 |
int iArg,
void *pAux,
void (*xDelete)(void*)
){
AuxData *pAuxData;
Vdbe *pVdbe = pCtx->pVdbe;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( iArg<0 ) goto failed;
for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
if( pAuxData==0 ){
pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
|
| ︙ | ︙ | |||
67009 67010 67011 67012 67013 67014 67015 |
pVm = (Vdbe *)pStmt;
if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
sqlite3_mutex_enter(pVm->db->mutex);
pOut = &pVm->pResultSet[i];
}else{
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
| | | 67649 67650 67651 67652 67653 67654 67655 67656 67657 67658 67659 67660 67661 67662 67663 |
pVm = (Vdbe *)pStmt;
if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
sqlite3_mutex_enter(pVm->db->mutex);
pOut = &pVm->pResultSet[i];
}else{
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE);
}
pOut = (Mem*)columnNullValue();
}
return pOut;
}
/*
|
| ︙ | ︙ | |||
67274 67275 67276 67277 67278 67279 67280 |
static int vdbeUnbind(Vdbe *p, int i){
Mem *pVar;
if( vdbeSafetyNotNull(p) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(p->db->mutex);
if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
| | | | | 67914 67915 67916 67917 67918 67919 67920 67921 67922 67923 67924 67925 67926 67927 67928 67929 67930 67931 67932 67933 67934 67935 67936 67937 67938 67939 67940 67941 67942 67943 |
static int vdbeUnbind(Vdbe *p, int i){
Mem *pVar;
if( vdbeSafetyNotNull(p) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(p->db->mutex);
if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
sqlite3Error(p->db, SQLITE_MISUSE);
sqlite3_mutex_leave(p->db->mutex);
sqlite3_log(SQLITE_MISUSE,
"bind on a busy prepared statement: [%s]", p->zSql);
return SQLITE_MISUSE_BKPT;
}
if( i<1 || i>p->nVar ){
sqlite3Error(p->db, SQLITE_RANGE);
sqlite3_mutex_leave(p->db->mutex);
return SQLITE_RANGE;
}
i--;
pVar = &p->aVar[i];
sqlite3VdbeMemRelease(pVar);
pVar->flags = MEM_Null;
sqlite3Error(p->db, SQLITE_OK);
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
**
** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
** parameter in the WHERE clause might influence the choice of query plan
** for a statement, then the statement will be automatically recompiled,
|
| ︙ | ︙ | |||
67331 67332 67333 67334 67335 67336 67337 |
if( rc==SQLITE_OK ){
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
| | | 67971 67972 67973 67974 67975 67976 67977 67978 67979 67980 67981 67982 67983 67984 67985 |
if( rc==SQLITE_OK ){
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
sqlite3Error(p->db, rc);
rc = sqlite3ApiExit(p->db, rc);
}
sqlite3_mutex_leave(p->db->mutex);
}else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){
xDel((void*)zData);
}
return rc;
|
| ︙ | ︙ | |||
68044 68045 68046 68047 68048 68049 68050 | #endif /* ** Convert the given register into a string if it isn't one ** already. Return non-zero if a malloc() fails. */ #define Stringify(P, enc) \ | | | 68684 68685 68686 68687 68688 68689 68690 68691 68692 68693 68694 68695 68696 68697 68698 |
#endif
/*
** Convert the given register into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
{ goto no_mem; }
/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string. Because the register
** does not control the string, it might be deleted without the register
|
| ︙ | ︙ | |||
68126 68127 68128 68129 68130 68131 68132 68133 | } /* ** Try to convert a value into a numeric representation if we can ** do so without loss of information. In other words, if the string ** looks like a number, convert it into a number. If it does not ** look like a number, leave it alone. */ | > > > > > > > > > | > < < | 68766 68767 68768 68769 68770 68771 68772 68773 68774 68775 68776 68777 68778 68779 68780 68781 68782 68783 68784 68785 68786 68787 68788 68789 68790 68791 68792 68793 68794 68795 68796 68797 68798 68799 68800 68801 68802 68803 68804 |
}
/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information. In other words, if the string
** looks like a number, convert it into a number. If it does not
** look like a number, leave it alone.
**
** If the bTryForInt flag is true, then extra effort is made to give
** an integer representation. Strings that look like floating point
** values but which have no fractional component (example: '48.00')
** will have a MEM_Int representation when bTryForInt is true.
**
** If bTryForInt is false, then if the input string contains a decimal
** point or exponential notation, the result is only MEM_Real, even
** if there is an exact integer representation of the quantity.
*/
static void applyNumericAffinity(Mem *pRec, int bTryForInt){
double rValue;
i64 iValue;
u8 enc = pRec->enc;
if( (pRec->flags&MEM_Str)==0 ) return;
if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
pRec->u.i = iValue;
pRec->flags |= MEM_Int;
}else{
pRec->r = rValue;
pRec->flags |= MEM_Real;
if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
}
}
/*
** Processing is determine by the affinity parameter:
**
** SQLITE_AFF_INTEGER:
** SQLITE_AFF_REAL:
** SQLITE_AFF_NUMERIC:
|
| ︙ | ︙ | |||
68173 68174 68175 68176 68177 68178 68179 |
){
if( affinity==SQLITE_AFF_TEXT ){
/* Only attempt the conversion to TEXT if there is an integer or real
** representation (blob and NULL do not get converted) but no string
** representation.
*/
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
| | < | | > > | > | > > > > > > > > > > > > > > > > > > < | < < < < < | 68821 68822 68823 68824 68825 68826 68827 68828 68829 68830 68831 68832 68833 68834 68835 68836 68837 68838 68839 68840 68841 68842 68843 68844 68845 68846 68847 68848 68849 68850 68851 68852 68853 68854 68855 68856 68857 68858 68859 68860 68861 68862 68863 68864 68865 68866 68867 68868 68869 68870 68871 68872 68873 68874 68875 68876 68877 68878 68879 68880 68881 68882 68883 68884 68885 68886 68887 68888 68889 68890 68891 68892 68893 68894 68895 68896 68897 68898 68899 68900 68901 68902 68903 68904 68905 68906 68907 68908 |
){
if( affinity==SQLITE_AFF_TEXT ){
/* Only attempt the conversion to TEXT if there is an integer or real
** representation (blob and NULL do not get converted) but no string
** representation.
*/
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
sqlite3VdbeMemStringify(pRec, enc, 1);
}
}else if( affinity!=SQLITE_AFF_NONE ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|| affinity==SQLITE_AFF_NUMERIC );
if( (pRec->flags & MEM_Int)==0 ){
if( (pRec->flags & MEM_Real)==0 ){
applyNumericAffinity(pRec,1);
}else{
sqlite3VdbeIntegerAffinity(pRec);
}
}
}
}
/*
** Try to convert the type of a function argument or a result column
** into a numeric representation. Use either INTEGER or REAL whichever
** is appropriate. But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.
*/
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
int eType = sqlite3_value_type(pVal);
if( eType==SQLITE_TEXT ){
Mem *pMem = (Mem*)pVal;
applyNumericAffinity(pMem, 0);
eType = sqlite3_value_type(pVal);
}
return eType;
}
/*
** Exported version of applyAffinity(). This one works on sqlite3_value*,
** not the internal Mem* type.
*/
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
sqlite3_value *pVal,
u8 affinity,
u8 enc
){
applyAffinity((Mem *)pVal, affinity, enc);
}
/*
** pMem currently only holds a string type (or maybe a BLOB that we can
** interpret as a string if we want to). Compute its corresponding
** numeric type, if has one. Set the pMem->r and pMem->u.i fields
** accordingly.
*/
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
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 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) ){
return computeNumericType(pMem);
}
return 0;
}
#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
|
| ︙ | ︙ | |||
68605 68606 68607 68608 68609 68610 68611 |
*/
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
| | | 69267 69268 69269 69270 69271 69272 69273 69274 69275 69276 69277 69278 69279 69280 69281 |
*/
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
VdbeMemReleaseExtern(pOut);
pOut->flags = MEM_Int;
}
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
|
| ︙ | ︙ | |||
69044 69045 69046 69047 69048 69049 69050 |
u16 nullFlag;
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
| | | 69706 69707 69708 69709 69710 69711 69712 69713 69714 69715 69716 69717 69718 69719 69720 |
u16 nullFlag;
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemReleaseExtern(pOut);
pOut->flags = nullFlag;
cnt--;
}
break;
}
/* Opcode: SoftNull P1 * * * *
|
| ︙ | ︙ | |||
69130 69131 69132 69133 69134 69135 69136 |
pIn1 = &aMem[p1];
pOut = &aMem[p2];
do{
assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
| | | 69792 69793 69794 69795 69796 69797 69798 69799 69800 69801 69802 69803 69804 69805 69806 |
pIn1 = &aMem[p1];
pOut = &aMem[p2];
do{
assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
sqlite3VdbeMemRelease(pOut);
zMalloc = pOut->zMalloc;
memcpy(pOut, pIn1, sizeof(Mem));
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
pOut->pScopyFrom += p1 - pOp->p2;
}
#endif
|
| ︙ | ︙ | |||
69510 69511 69512 69513 69514 69515 69516 | sqlite3_value **apVal; int n; n = pOp->p5; apVal = p->apArg; assert( apVal || n==0 ); assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | | | < < < < < < < < < | < < < < < < < < < < | | < < | < < < < < < < < | | | 70172 70173 70174 70175 70176 70177 70178 70179 70180 70181 70182 70183 70184 70185 70186 70187 70188 70189 70190 70191 70192 70193 70194 70195 70196 70197 70198 70199 70200 70201 70202 70203 70204 70205 70206 70207 70208 70209 70210 70211 70212 70213 70214 70215 70216 70217 70218 70219 70220 70221 70222 70223 70224 70225 70226 70227 70228 70229 70230 70231 70232 |
sqlite3_value **apVal;
int n;
n = pOp->p5;
apVal = p->apArg;
assert( apVal || n==0 );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pOut = &aMem[pOp->p3];
memAboutToChange(p, ctx.pOut);
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pArg = &aMem[pOp->p2];
for(i=0; i<n; i++, pArg++){
assert( memIsValid(pArg) );
apVal[i] = pArg;
Deephemeralize(pArg);
REGISTER_TRACE(pOp->p2+i, pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
ctx.iOp = pc;
ctx.pVdbe = p;
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
ctx.pColl = pOp[-1].p4.pColl;
}
db->lastRowid = lastRowid;
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
/* If the function returned an error, throw an exception */
if( ctx.fErrorOrAux ){
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
rc = ctx.isError;
}
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
}
/* Copy the result of the function into register P3 */
sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
if( sqlite3VdbeMemTooBig(ctx.pOut) ){
goto too_big;
}
REGISTER_TRACE(pOp->p3, ctx.pOut);
UPDATE_MAX_BLOBSIZE(ctx.pOut);
break;
}
/* Opcode: BitAnd P1 P2 P3 * *
** Synopsis: r[P3]=r[P1]&r[P2]
**
** Take the bit-wise AND of the values in register P1 and P2 and
|
| ︙ | ︙ | |||
69733 69734 69735 69736 69737 69738 69739 |
sqlite3VdbeMemRealify(pIn1);
}
break;
}
#endif
#ifndef SQLITE_OMIT_CAST
| | > | < < < | < | < < < < < < | < < < | < < | < | | < < | < < < < < < < < < < < < < < < < < < < < < < < < | | < < < | | < < < < < < < < < < | < < < < < | | < < < < < < < < < < | | < > | | 70366 70367 70368 70369 70370 70371 70372 70373 70374 70375 70376 70377 70378 70379 70380 70381 70382 70383 70384 70385 70386 70387 70388 70389 70390 70391 70392 70393 70394 70395 70396 70397 70398 70399 70400 70401 70402 70403 70404 70405 70406 70407 70408 70409 |
sqlite3VdbeMemRealify(pIn1);
}
break;
}
#endif
#ifndef SQLITE_OMIT_CAST
/* Opcode: Cast P1 P2 * * *
** Synopsis: affinity(r[P1])
**
** Force the value in register P1 to be the type defined by P2.
**
** <ul>
** <li value="97"> TEXT
** <li value="98"> BLOB
** <li value="99"> NUMERIC
** <li value="100"> INTEGER
** <li value="101"> REAL
** </ul>
**
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_Cast: { /* in1 */
assert( pOp->p2>=SQLITE_AFF_TEXT && pOp->p2<=SQLITE_AFF_REAL );
testcase( pOp->p2==SQLITE_AFF_TEXT );
testcase( pOp->p2==SQLITE_AFF_NONE );
testcase( pOp->p2==SQLITE_AFF_NUMERIC );
testcase( pOp->p2==SQLITE_AFF_INTEGER );
testcase( pOp->p2==SQLITE_AFF_REAL );
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
rc = ExpandBlob(pIn1);
sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
UPDATE_MAX_BLOBSIZE(pIn1);
break;
}
#endif /* SQLITE_OMIT_CAST */
/* Opcode: Lt P1 P2 P3 P4 P5
** Synopsis: if r[P1]<r[P3] goto P2
**
** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
** jump to address P2.
**
|
| ︙ | ︙ | |||
70503 70504 70505 70506 70507 70508 70509 |
*/
assert( p2<pC->nHdrParsed );
assert( rc==SQLITE_OK );
assert( sqlite3VdbeCheckMemInvariants(pDest) );
if( pC->szRow>=aOffset[p2+1] ){
/* This is the common case where the desired content fits on the original
** page - where the content is not on an overflow page */
| | | 71067 71068 71069 71070 71071 71072 71073 71074 71075 71076 71077 71078 71079 71080 71081 |
*/
assert( p2<pC->nHdrParsed );
assert( rc==SQLITE_OK );
assert( sqlite3VdbeCheckMemInvariants(pDest) );
if( pC->szRow>=aOffset[p2+1] ){
/* This is the common case where the desired content fits on the original
** page - where the content is not on an overflow page */
VdbeMemReleaseExtern(pDest);
sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
}else{
/* This branch happens only when content is on overflow pages */
t = aType[p2];
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
|| (len = sqlite3VdbeSerialTypeLen(t))==0
|
| ︙ | ︙ | |||
71425 71426 71427 71428 71429 71430 71431 |
pCx->isTable = 1;
}
}
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
| | > > > > | > > > > > > > > > > > > > > > > > > | 71989 71990 71991 71992 71993 71994 71995 71996 71997 71998 71999 72000 72001 72002 72003 72004 72005 72006 72007 72008 72009 72010 72011 72012 72013 72014 72015 72016 72017 72018 72019 72020 72021 72022 72023 72024 72025 72026 72027 72028 72029 72030 72031 72032 72033 72034 72035 72036 72037 72038 72039 72040 72041 |
pCx->isTable = 1;
}
}
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
/* Opcode: SorterOpen P1 P2 P3 P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
**
** If argument P3 is non-zero, then it indicates that the sorter may
** assume that a stable sort considering the first P3 fields of each
** key is sufficient to produce the required results.
*/
case OP_SorterOpen: {
VdbeCursor *pCx;
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
if( pCx==0 ) goto no_mem;
pCx->pKeyInfo = pOp->p4.pKeyInfo;
assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) );
rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
break;
}
/* Opcode: SequenceTest P1 P2 * * *
** Synopsis: if( cursor[P1].ctr++ ) pc = P2
**
** P1 is a sorter cursor. If the sequence counter is currently zero, jump
** to P2. Regardless of whether or not the jump is taken, increment the
** the sequence value.
*/
case OP_SequenceTest: {
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * *
** Synopsis: P3 columns in r[P2]
**
** Open a new cursor that points to a fake table that contains a single
|
| ︙ | ︙ | |||
71590 71591 71592 71593 71594 71595 71596 |
pC->seekOp = pOp->opcode;
#endif
if( pC->isTable ){
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so covert it. */
pIn3 = &aMem[pOp->p3];
| > | > | 72176 72177 72178 72179 72180 72181 72182 72183 72184 72185 72186 72187 72188 72189 72190 72191 72192 |
pC->seekOp = pOp->opcode;
#endif
if( pC->isTable ){
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so covert it. */
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & (MEM_Int|MEM_Real))==0 ){
applyNumericAffinity(pIn3, 0);
}
iKey = sqlite3VdbeIntValue(pIn3);
pC->rowidIsValid = 0;
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
if( (pIn3->flags & MEM_Int)==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
|
| ︙ | ︙ | |||
72288 72289 72290 72291 72292 72293 72294 72295 72296 72297 72298 72299 72300 72301 |
int nKeyCol;
pC = p->apCsr[pOp->p1];
assert( isSorter(pC) );
assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
nKeyCol = pOp->p4.i;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2-1;
}
break;
};
| > | 72876 72877 72878 72879 72880 72881 72882 72883 72884 72885 72886 72887 72888 72889 72890 |
int nKeyCol;
pC = p->apCsr[pOp->p1];
assert( isSorter(pC) );
assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
nKeyCol = pOp->p4.i;
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2-1;
}
break;
};
|
| ︙ | ︙ | |||
72552 72553 72554 72555 72556 72557 72558 |
assert( pC!=0 );
assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
res = 1;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Rewind;
#endif
if( isSorter(pC) ){
| | | 73141 73142 73143 73144 73145 73146 73147 73148 73149 73150 73151 73152 73153 73154 73155 |
assert( pC!=0 );
assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
res = 1;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Rewind;
#endif
if( isSorter(pC) ){
rc = sqlite3VdbeSorterRewind(pC, &res);
}else{
pCrsr = pC->pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
pC->rowidIsValid = 0;
|
| ︙ | ︙ | |||
72730 72731 72732 72733 72734 72735 72736 |
pCrsr = pC->pCursor;
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
assert( pCrsr!=0 );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
if( isSorter(pC) ){
| | | 73319 73320 73321 73322 73323 73324 73325 73326 73327 73328 73329 73330 73331 73332 73333 |
pCrsr = pC->pCursor;
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
assert( pCrsr!=0 );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
if( isSorter(pC) ){
rc = sqlite3VdbeSorterWrite(pC, pIn2);
}else{
nKey = pIn2->n;
zKey = pIn2->z;
rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3,
((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
);
assert( pC->deferredMoveto==0 );
|
| ︙ | ︙ | |||
73643 73644 73645 73646 73647 73648 73649 73650 73651 73652 73653 73654 73655 73656 73657 73658 73659 73660 73661 73662 73663 73664 73665 73666 |
** successors.
*/
case OP_AggStep: {
int n;
int i;
Mem *pMem;
Mem *pRec;
sqlite3_context ctx;
sqlite3_value **apVal;
n = pOp->p5;
assert( n>=0 );
pRec = &aMem[pOp->p2];
apVal = p->apArg;
assert( apVal || n==0 );
for(i=0; i<n; i++, pRec++){
assert( memIsValid(pRec) );
apVal[i] = pRec;
memAboutToChange(p, pRec);
}
ctx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pMem = pMem = &aMem[pOp->p3];
pMem->n++;
| > | | | | | > | < | < | 74232 74233 74234 74235 74236 74237 74238 74239 74240 74241 74242 74243 74244 74245 74246 74247 74248 74249 74250 74251 74252 74253 74254 74255 74256 74257 74258 74259 74260 74261 74262 74263 74264 74265 74266 74267 74268 74269 74270 74271 74272 74273 74274 74275 74276 74277 74278 74279 74280 74281 74282 74283 74284 74285 74286 74287 74288 74289 |
** successors.
*/
case OP_AggStep: {
int n;
int i;
Mem *pMem;
Mem *pRec;
Mem t;
sqlite3_context ctx;
sqlite3_value **apVal;
n = pOp->p5;
assert( n>=0 );
pRec = &aMem[pOp->p2];
apVal = p->apArg;
assert( apVal || n==0 );
for(i=0; i<n; i++, pRec++){
assert( memIsValid(pRec) );
apVal[i] = pRec;
memAboutToChange(p, pRec);
}
ctx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pMem = pMem = &aMem[pOp->p3];
pMem->n++;
t.flags = MEM_Null;
t.z = 0;
t.zMalloc = 0;
t.xDel = 0;
t.db = db;
ctx.pOut = &t;
ctx.isError = 0;
ctx.pColl = 0;
ctx.skipFlag = 0;
if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
ctx.pColl = pOp[-1].p4.pColl;
}
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
rc = ctx.isError;
}
if( ctx.skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
i = pOp[-1].p1;
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
}
sqlite3VdbeMemRelease(&t);
break;
}
/* Opcode: AggFinal P1 P2 * P4 *
** Synopsis: accum=r[P1] N=P2
**
** Execute the finalizer function for an aggregate. P1 is
|
| ︙ | ︙ | |||
74136 74137 74138 74139 74140 74141 74142 |
sqlite3VdbeMemSetNull(pDest);
break;
}
pVtab = pCur->pVtabCursor->pVtab;
pModule = pVtab->pModule;
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
| | < < < < < < | < < < < < < | < | 74725 74726 74727 74728 74729 74730 74731 74732 74733 74734 74735 74736 74737 74738 74739 74740 74741 74742 74743 74744 74745 74746 |
sqlite3VdbeMemSetNull(pDest);
break;
}
pVtab = pCur->pVtabCursor->pVtab;
pModule = pVtab->pModule;
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
MemSetTypeFlag(pDest, MEM_Null);
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
sqlite3VtabImportErrmsg(p, pVtab);
if( sContext.isError ){
rc = sContext.isError;
}
sqlite3VdbeChangeEncoding(pDest, encoding);
REGISTER_TRACE(pOp->p3, pDest);
UPDATE_MAX_BLOBSIZE(pDest);
if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
break;
|
| ︙ | ︙ | |||
74846 74847 74848 74849 74850 74851 74852 |
blob_open_out:
if( rc==SQLITE_OK && db->mallocFailed==0 ){
*ppBlob = (sqlite3_blob *)pBlob;
}else{
if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
sqlite3DbFree(db, pBlob);
}
| | | 75422 75423 75424 75425 75426 75427 75428 75429 75430 75431 75432 75433 75434 75435 75436 |
blob_open_out:
if( rc==SQLITE_OK && db->mallocFailed==0 ){
*ppBlob = (sqlite3_blob *)pBlob;
}else{
if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
sqlite3DbFree(db, pBlob);
}
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
|
| ︙ | ︙ | |||
74899 74900 74901 74902 74903 74904 74905 |
db = p->db;
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
/* Request is out of range. Return a transient error. */
rc = SQLITE_ERROR;
| | | 75475 75476 75477 75478 75479 75480 75481 75482 75483 75484 75485 75486 75487 75488 75489 |
db = p->db;
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
/* Request is out of range. Return a transient error. */
rc = SQLITE_ERROR;
sqlite3Error(db, SQLITE_ERROR);
}else if( v==0 ){
/* If there is no statement handle, then the blob-handle has
** already been invalidated. Return SQLITE_ABORT in this case.
*/
rc = SQLITE_ABORT;
}else{
/* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
|
| ︙ | ︙ | |||
74979 74980 74981 74982 74983 74984 74985 |
** already been invalidated. Return SQLITE_ABORT in this case.
*/
rc = SQLITE_ABORT;
}else{
char *zErr;
rc = blobSeekToRow(p, iRow, &zErr);
if( rc!=SQLITE_OK ){
| | | | | > | > > > | | | | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > | > > > > > > > > > > > > > > > | > > > > > > > > > > | > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | | | | | | | | | | | | | | | | | | | | | | | | > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > | > > > > > > > > > > > > > > | | > | | > | > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | < < | | | | > | | < > > | | > > > > | | | > > > > > > > > > < | > | > > > > > > > > > | > > | > > > | | | | > > | | | | < | > > > > > > > | | > | | | > | | | > > > | | | | | | | | | | | | > < > > > | > | > | < < < < < < < < < | < | < > | < < < | < < < > > | | > | | < < | > | > > > | < < < < | | < | < > > > > | > | < | | < | | | | | > | | > > | > > > > > > > | | | > > > > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < > > | < | < < < > > | | < | < < < | < < | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > | > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | > > > | > | > > > | > | < | | | | | > > > > > > > > > > > | > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | > > > | | < | | | | | > > > > | > | | | | | | | < | > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > | | | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | > | > > | | > > | > > > > > > > > > | | | | > > > | | | | | | < < | | | | | | | | | | | | | | | | > | | > > | > | > > > > | > > | > > > | < > > | | | > | | < < < | > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > > > > > > > > > > | > > > > > > > > > > > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > | > > > < | | | > < < < < < < < | < | | > > > | > > > | > > | | > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > | > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | | > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | < | | > | < < | | < < < < < < < < < < < < | < < < < < < < | < | < < < > | < < < < < | < < < | | < < < | | | < < < < < < < < < > > | < < | < < | < < < < < < < < < | | < < < < | > | | | < < | < < | < < | < < | | < < < < < < | < < < < | < < < < < < < < < < < | | < < < < < < | | < < | | | | | | > > | > > > > | > | | | | | 75555 75556 75557 75558 75559 75560 75561 75562 75563 75564 75565 75566 75567 75568 75569 75570 75571 75572 75573 75574 75575 75576 75577 75578 75579 75580 75581 75582 75583 75584 75585 75586 75587 75588 75589 75590 75591 75592 75593 75594 75595 75596 75597 75598 75599 75600 75601 75602 75603 75604 75605 75606 75607 75608 75609 75610 75611 75612 75613 75614 75615 75616 75617 75618 75619 75620 75621 75622 75623 75624 75625 75626 75627 75628 75629 75630 75631 75632 75633 75634 75635 75636 75637 75638 75639 75640 75641 75642 75643 75644 75645 75646 75647 75648 75649 75650 75651 75652 75653 75654 75655 75656 75657 75658 75659 75660 75661 75662 75663 75664 75665 75666 75667 75668 75669 75670 75671 75672 75673 75674 75675 75676 75677 75678 75679 75680 75681 75682 75683 75684 75685 75686 75687 75688 75689 75690 75691 75692 75693 75694 75695 75696 75697 75698 75699 75700 75701 75702 75703 75704 75705 75706 75707 75708 75709 75710 75711 75712 75713 75714 75715 75716 75717 75718 75719 75720 75721 75722 75723 75724 75725 75726 75727 75728 75729 75730 75731 75732 75733 75734 75735 75736 75737 75738 75739 75740 75741 75742 75743 75744 75745 75746 75747 75748 75749 75750 75751 75752 75753 75754 75755 75756 75757 75758 75759 75760 75761 75762 75763 75764 75765 75766 75767 75768 75769 75770 75771 75772 75773 75774 75775 75776 75777 75778 75779 75780 75781 75782 75783 75784 75785 75786 75787 75788 75789 75790 75791 75792 75793 75794 75795 75796 75797 75798 75799 75800 75801 75802 75803 75804 75805 75806 75807 75808 75809 75810 75811 75812 75813 75814 75815 75816 75817 75818 75819 75820 75821 75822 75823 75824 75825 75826 75827 75828 75829 75830 75831 75832 75833 75834 75835 75836 75837 75838 75839 75840 75841 75842 75843 75844 75845 75846 75847 75848 75849 75850 75851 75852 75853 75854 75855 75856 75857 75858 75859 75860 75861 75862 75863 75864 75865 75866 75867 75868 75869 75870 75871 75872 75873 75874 75875 75876 75877 75878 75879 75880 75881 75882 75883 75884 75885 75886 75887 75888 75889 75890 75891 75892 75893 75894 75895 75896 75897 75898 75899 75900 75901 75902 75903 75904 75905 75906 75907 75908 75909 75910 75911 75912 75913 75914 75915 75916 75917 75918 75919 75920 75921 75922 75923 75924 75925 75926 75927 75928 75929 75930 75931 75932 75933 75934 75935 75936 75937 75938 75939 75940 75941 75942 75943 75944 75945 75946 75947 75948 75949 75950 75951 75952 75953 75954 75955 75956 75957 75958 75959 75960 75961 75962 75963 75964 75965 75966 75967 75968 75969 75970 75971 75972 75973 75974 75975 75976 75977 75978 75979 75980 75981 75982 75983 75984 75985 75986 75987 75988 75989 75990 75991 75992 75993 75994 75995 75996 75997 75998 75999 76000 76001 76002 76003 76004 76005 76006 76007 76008 76009 76010 76011 76012 76013 76014 76015 76016 76017 76018 76019 76020 76021 76022 76023 76024 76025 76026 76027 76028 76029 76030 76031 76032 76033 76034 76035 76036 76037 76038 76039 76040 76041 76042 76043 76044 76045 76046 76047 76048 76049 76050 76051 76052 76053 76054 76055 76056 76057 76058 76059 76060 76061 76062 76063 76064 76065 76066 76067 76068 76069 76070 76071 76072 76073 76074 76075 76076 76077 76078 76079 76080 76081 76082 76083 76084 76085 76086 76087 76088 76089 76090 76091 76092 76093 76094 76095 76096 76097 76098 76099 76100 76101 76102 76103 76104 76105 76106 76107 76108 76109 76110 76111 76112 76113 76114 76115 76116 76117 76118 76119 76120 76121 76122 76123 76124 76125 76126 76127 76128 76129 76130 76131 76132 76133 76134 76135 76136 76137 76138 76139 76140 76141 76142 76143 76144 76145 76146 76147 76148 76149 76150 76151 76152 76153 76154 76155 76156 76157 76158 76159 76160 76161 76162 76163 76164 76165 76166 76167 76168 76169 76170 76171 76172 76173 76174 76175 76176 76177 76178 76179 76180 76181 76182 76183 76184 76185 76186 76187 76188 76189 76190 76191 76192 76193 76194 76195 76196 76197 76198 76199 76200 76201 76202 76203 76204 76205 76206 76207 76208 76209 76210 76211 76212 76213 76214 76215 76216 76217 76218 76219 76220 76221 76222 76223 76224 76225 76226 76227 76228 76229 76230 76231 76232 76233 76234 76235 76236 76237 76238 76239 76240 76241 76242 76243 76244 76245 76246 76247 76248 76249 76250 76251 76252 76253 76254 76255 76256 76257 76258 76259 76260 76261 76262 76263 76264 76265 76266 76267 76268 76269 76270 76271 76272 76273 76274 76275 76276 76277 76278 76279 76280 76281 76282 76283 76284 76285 76286 76287 76288 76289 76290 76291 76292 76293 76294 76295 76296 76297 76298 76299 76300 76301 76302 76303 76304 76305 76306 76307 76308 76309 76310 76311 76312 76313 76314 76315 76316 76317 76318 76319 76320 76321 76322 76323 76324 76325 76326 76327 76328 76329 76330 76331 76332 76333 76334 76335 76336 76337 76338 76339 76340 76341 76342 76343 76344 76345 76346 76347 76348 76349 76350 76351 76352 76353 76354 76355 76356 76357 76358 76359 76360 76361 76362 76363 76364 76365 76366 76367 76368 76369 76370 76371 76372 76373 76374 76375 76376 76377 76378 76379 76380 76381 76382 76383 76384 76385 76386 76387 76388 76389 76390 76391 76392 76393 76394 76395 76396 76397 76398 76399 76400 76401 76402 76403 76404 76405 76406 76407 76408 76409 76410 76411 76412 76413 76414 76415 76416 76417 76418 76419 76420 76421 76422 76423 76424 76425 76426 76427 76428 76429 76430 76431 76432 76433 76434 76435 76436 76437 76438 76439 76440 76441 76442 76443 76444 76445 76446 76447 76448 76449 76450 76451 76452 76453 76454 76455 76456 76457 76458 76459 76460 76461 76462 76463 76464 76465 76466 76467 76468 76469 76470 76471 76472 76473 76474 76475 76476 76477 76478 76479 76480 76481 76482 76483 76484 76485 76486 76487 76488 76489 76490 76491 76492 76493 76494 76495 76496 76497 76498 76499 76500 76501 76502 76503 76504 76505 76506 76507 76508 76509 76510 76511 76512 76513 76514 76515 76516 76517 76518 76519 76520 76521 76522 76523 76524 76525 76526 76527 76528 76529 76530 76531 76532 76533 76534 76535 76536 76537 76538 76539 76540 76541 76542 76543 76544 76545 76546 76547 76548 76549 76550 76551 76552 76553 76554 76555 76556 76557 76558 76559 76560 76561 76562 76563 76564 76565 76566 76567 76568 76569 76570 76571 76572 76573 76574 76575 76576 76577 76578 76579 76580 76581 76582 76583 76584 76585 76586 76587 76588 76589 76590 76591 76592 76593 76594 76595 76596 76597 76598 76599 76600 76601 76602 76603 76604 76605 76606 76607 76608 76609 76610 76611 76612 76613 76614 76615 76616 76617 76618 76619 76620 76621 76622 76623 76624 76625 76626 76627 76628 76629 76630 76631 76632 76633 76634 76635 76636 76637 76638 76639 76640 76641 76642 76643 76644 76645 76646 76647 76648 76649 76650 76651 76652 76653 76654 76655 76656 76657 76658 76659 76660 76661 76662 76663 76664 76665 76666 76667 76668 76669 76670 76671 76672 76673 76674 76675 76676 76677 76678 76679 76680 76681 76682 76683 76684 76685 76686 76687 76688 76689 76690 76691 76692 76693 76694 76695 76696 76697 76698 76699 76700 76701 76702 76703 76704 76705 76706 76707 76708 76709 76710 76711 76712 76713 76714 76715 76716 76717 76718 76719 76720 76721 76722 76723 76724 76725 76726 76727 76728 76729 76730 76731 76732 76733 76734 76735 76736 76737 76738 76739 76740 76741 76742 76743 76744 76745 76746 76747 76748 76749 76750 76751 76752 76753 76754 76755 76756 76757 76758 76759 76760 76761 76762 76763 76764 76765 76766 76767 76768 76769 76770 76771 76772 76773 76774 76775 76776 76777 76778 76779 76780 76781 76782 76783 76784 76785 76786 76787 76788 76789 76790 76791 76792 76793 76794 76795 76796 76797 76798 76799 76800 76801 76802 76803 76804 76805 76806 76807 76808 76809 76810 76811 76812 76813 76814 76815 76816 76817 76818 76819 76820 76821 76822 76823 76824 76825 76826 76827 76828 76829 76830 76831 76832 76833 76834 76835 76836 76837 76838 76839 76840 76841 76842 76843 76844 76845 76846 76847 76848 76849 76850 76851 76852 76853 76854 76855 76856 76857 76858 76859 76860 76861 76862 76863 76864 76865 76866 76867 76868 76869 76870 76871 76872 76873 76874 76875 76876 76877 76878 76879 76880 76881 76882 76883 76884 76885 76886 76887 76888 76889 76890 76891 76892 76893 76894 76895 76896 76897 76898 76899 76900 76901 76902 76903 76904 76905 76906 76907 76908 76909 76910 76911 76912 76913 76914 76915 76916 76917 76918 76919 76920 76921 76922 76923 76924 76925 76926 76927 76928 76929 76930 76931 76932 76933 76934 76935 76936 76937 76938 76939 76940 76941 76942 76943 76944 76945 76946 76947 76948 76949 76950 76951 76952 76953 76954 76955 76956 76957 76958 76959 76960 76961 76962 76963 76964 76965 76966 76967 76968 76969 76970 76971 76972 76973 76974 76975 76976 76977 76978 76979 76980 76981 76982 76983 76984 76985 76986 76987 76988 76989 76990 76991 76992 76993 76994 76995 76996 76997 76998 76999 77000 77001 77002 77003 77004 77005 77006 77007 77008 77009 77010 77011 77012 77013 77014 77015 77016 77017 77018 77019 77020 77021 77022 77023 77024 77025 77026 77027 77028 77029 77030 77031 77032 77033 77034 77035 77036 77037 77038 77039 77040 77041 77042 77043 77044 77045 77046 77047 77048 77049 77050 77051 77052 77053 77054 77055 77056 77057 77058 77059 77060 77061 77062 77063 77064 77065 77066 77067 77068 77069 77070 77071 77072 77073 77074 77075 77076 77077 77078 77079 77080 77081 77082 77083 77084 77085 77086 77087 77088 77089 77090 77091 77092 77093 77094 77095 77096 77097 77098 77099 77100 77101 77102 77103 77104 77105 77106 77107 77108 77109 77110 77111 77112 77113 77114 77115 77116 77117 77118 77119 77120 77121 77122 77123 77124 77125 77126 77127 77128 77129 77130 77131 77132 77133 77134 77135 77136 77137 77138 77139 77140 77141 77142 77143 77144 77145 77146 77147 77148 77149 77150 77151 77152 77153 77154 77155 77156 77157 77158 77159 77160 77161 77162 77163 77164 77165 77166 77167 77168 77169 77170 77171 77172 77173 77174 77175 77176 77177 77178 77179 77180 77181 77182 77183 77184 77185 77186 77187 77188 77189 77190 77191 77192 77193 77194 77195 77196 77197 77198 77199 77200 77201 77202 77203 77204 77205 77206 77207 77208 77209 77210 77211 77212 77213 77214 77215 77216 77217 77218 77219 77220 77221 77222 77223 77224 77225 77226 77227 77228 77229 77230 77231 77232 77233 77234 77235 77236 77237 77238 77239 77240 77241 77242 77243 77244 77245 77246 77247 77248 77249 77250 77251 77252 77253 77254 77255 77256 77257 77258 77259 77260 77261 77262 77263 77264 77265 77266 77267 77268 77269 77270 77271 77272 77273 77274 77275 77276 77277 77278 77279 77280 77281 77282 77283 77284 77285 77286 77287 77288 77289 77290 77291 77292 77293 77294 77295 77296 77297 77298 77299 77300 77301 77302 77303 77304 77305 77306 77307 77308 77309 77310 77311 77312 77313 77314 77315 77316 77317 77318 77319 77320 77321 77322 77323 77324 77325 77326 77327 77328 77329 77330 77331 77332 77333 77334 77335 77336 77337 77338 77339 77340 77341 77342 77343 77344 77345 77346 77347 77348 77349 77350 77351 77352 77353 77354 77355 77356 77357 77358 77359 77360 77361 77362 77363 77364 77365 77366 77367 77368 77369 77370 77371 77372 77373 77374 77375 77376 77377 77378 77379 77380 77381 77382 77383 77384 77385 77386 77387 77388 77389 77390 77391 77392 77393 77394 77395 77396 77397 77398 77399 77400 77401 77402 77403 77404 77405 77406 77407 77408 77409 77410 77411 77412 77413 77414 77415 77416 77417 77418 77419 77420 77421 77422 77423 77424 77425 77426 77427 77428 77429 77430 77431 77432 77433 77434 77435 77436 77437 77438 77439 77440 77441 77442 77443 77444 77445 77446 77447 77448 77449 77450 77451 77452 77453 77454 77455 77456 77457 77458 77459 77460 77461 77462 77463 77464 77465 77466 77467 77468 77469 77470 77471 77472 77473 77474 77475 77476 77477 77478 77479 77480 77481 77482 77483 77484 77485 77486 77487 77488 77489 77490 77491 77492 77493 77494 77495 77496 77497 77498 77499 77500 77501 77502 77503 77504 77505 77506 77507 77508 77509 77510 77511 77512 77513 77514 77515 77516 77517 77518 77519 77520 77521 77522 77523 77524 77525 77526 77527 77528 77529 77530 77531 77532 77533 77534 77535 77536 77537 77538 77539 77540 77541 77542 77543 77544 77545 77546 77547 77548 77549 77550 77551 77552 77553 77554 77555 77556 77557 77558 77559 77560 77561 77562 77563 77564 77565 77566 77567 77568 77569 77570 77571 77572 77573 77574 77575 77576 77577 77578 77579 77580 77581 77582 77583 77584 77585 77586 77587 77588 77589 77590 77591 77592 77593 77594 77595 77596 77597 77598 77599 77600 77601 77602 77603 77604 77605 77606 77607 77608 77609 77610 77611 77612 77613 77614 77615 77616 77617 77618 77619 77620 77621 77622 77623 77624 77625 77626 77627 77628 77629 77630 77631 77632 77633 77634 77635 77636 77637 77638 77639 77640 77641 77642 77643 77644 77645 77646 77647 77648 77649 77650 77651 77652 77653 77654 77655 77656 77657 77658 77659 77660 77661 77662 77663 77664 77665 77666 77667 77668 77669 77670 77671 77672 77673 77674 77675 77676 77677 77678 77679 77680 77681 77682 77683 77684 77685 77686 77687 77688 77689 77690 77691 77692 77693 77694 77695 77696 77697 77698 77699 77700 77701 77702 77703 77704 77705 77706 77707 77708 77709 77710 77711 77712 77713 77714 77715 77716 77717 77718 77719 77720 77721 77722 77723 77724 77725 77726 77727 77728 77729 77730 77731 77732 77733 77734 77735 77736 77737 77738 77739 77740 77741 77742 77743 77744 77745 77746 77747 77748 77749 77750 77751 77752 77753 77754 77755 77756 77757 77758 77759 77760 77761 77762 77763 77764 77765 77766 77767 77768 77769 77770 77771 77772 77773 77774 77775 77776 77777 77778 77779 77780 77781 77782 77783 77784 77785 77786 77787 77788 77789 77790 77791 77792 77793 77794 77795 77796 77797 77798 77799 77800 77801 77802 77803 77804 77805 77806 77807 77808 77809 77810 77811 77812 77813 77814 77815 77816 77817 77818 77819 77820 77821 77822 77823 77824 77825 77826 77827 77828 77829 77830 77831 77832 77833 77834 77835 77836 77837 77838 77839 77840 77841 77842 77843 77844 77845 77846 77847 77848 77849 77850 77851 77852 77853 77854 77855 77856 77857 77858 77859 77860 77861 77862 77863 77864 77865 77866 77867 77868 77869 77870 77871 77872 77873 77874 77875 77876 77877 77878 77879 77880 77881 77882 77883 77884 77885 77886 77887 77888 77889 77890 77891 77892 77893 77894 77895 77896 77897 77898 77899 77900 77901 77902 77903 77904 77905 77906 77907 77908 77909 77910 77911 77912 77913 77914 77915 77916 77917 77918 77919 77920 77921 77922 77923 77924 77925 77926 77927 77928 77929 77930 77931 77932 77933 77934 77935 77936 77937 77938 77939 77940 77941 77942 77943 77944 77945 77946 77947 77948 77949 77950 77951 77952 77953 77954 77955 77956 77957 77958 77959 77960 77961 77962 77963 77964 77965 77966 77967 77968 77969 77970 77971 77972 77973 77974 77975 77976 77977 77978 77979 77980 77981 77982 77983 77984 77985 77986 77987 77988 77989 77990 77991 77992 77993 77994 77995 77996 77997 77998 77999 78000 78001 78002 78003 78004 78005 78006 78007 78008 78009 78010 78011 78012 78013 78014 78015 78016 78017 78018 78019 78020 78021 78022 78023 78024 78025 78026 78027 78028 78029 78030 |
** already been invalidated. Return SQLITE_ABORT in this case.
*/
rc = SQLITE_ABORT;
}else{
char *zErr;
rc = blobSeekToRow(p, iRow, &zErr);
if( rc!=SQLITE_OK ){
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
}
assert( rc!=SQLITE_SCHEMA );
}
rc = sqlite3ApiExit(db, rc);
assert( rc==SQLITE_OK || p->pStmt==0 );
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
/************** End of vdbeblob.c ********************************************/
/************** Begin file vdbesort.c ****************************************/
/*
** 2011-07-09
**
** 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 contains code for the VdbeSorter object, used in concert with
** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements
** or by SELECT statements with ORDER BY clauses that cannot be satisfied
** using indexes and without LIMIT clauses.
**
** The VdbeSorter object implements a multi-threaded external merge sort
** algorithm that is efficient even if the number of elements being sorted
** exceeds the available memory.
**
** Here is the (internal, non-API) interface between this module and the
** rest of the SQLite system:
**
** sqlite3VdbeSorterInit() Create a new VdbeSorter object.
**
** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter
** object. The row is a binary blob in the
** OP_MakeRecord format that contains both
** the ORDER BY key columns and result columns
** in the case of a SELECT w/ ORDER BY, or
** the complete record for an index entry
** in the case of a CREATE INDEX.
**
** sqlite3VdbeSorterRewind() Sort all content previously added.
** Position the read cursor on the
** first sorted element.
**
** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted
** element.
**
** sqlite3VdbeSorterRowkey() Return the complete binary blob for the
** row currently under the read cursor.
**
** sqlite3VdbeSorterCompare() Compare the binary blob for the row
** currently under the read cursor against
** another binary blob X and report if
** X is strictly less than the read cursor.
** Used to enforce uniqueness in a
** CREATE UNIQUE INDEX statement.
**
** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim
** all resources.
**
** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This
** is like Close() followed by Init() only
** much faster.
**
** The interfaces above must be called in a particular order. Write() can
** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and
** Compare() can only occur in between Rewind() and Close()/Reset(). i.e.
**
** Init()
** for each record: Write()
** Rewind()
** Rowkey()/Compare()
** Next()
** Close()
**
** Algorithm:
**
** Records passed to the sorter via calls to Write() are initially held
** unsorted in main memory. Assuming the amount of memory used never exceeds
** a threshold, when Rewind() is called the set of records is sorted using
** an in-memory merge sort. In this case, no temporary files are required
** and subsequent calls to Rowkey(), Next() and Compare() read records
** directly from main memory.
**
** If the amount of space used to store records in main memory exceeds the
** threshold, then the set of records currently in memory are sorted and
** written to a temporary file in "Packed Memory Array" (PMA) format.
** A PMA created at this point is known as a "level-0 PMA". Higher levels
** of PMAs may be created by merging existing PMAs together - for example
** merging two or more level-0 PMAs together creates a level-1 PMA.
**
** The threshold for the amount of main memory to use before flushing
** records to a PMA is roughly the same as the limit configured for the
** page-cache of the main database. Specifically, the threshold is set to
** the value returned by "PRAGMA main.page_size" multipled by
** that returned by "PRAGMA main.cache_size", in bytes.
**
** If the sorter is running in single-threaded mode, then all PMAs generated
** are appended to a single temporary file. Or, if the sorter is running in
** multi-threaded mode then up to (N+1) temporary files may be opened, where
** N is the configured number of worker threads. In this case, instead of
** sorting the records and writing the PMA to a temporary file itself, the
** calling thread usually launches a worker thread to do so. Except, if
** there are already N worker threads running, the main thread does the work
** itself.
**
** The sorter is running in multi-threaded mode if (a) the library was built
** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
** than zero, and (b) worker threads have been enabled at runtime by calling
** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...).
**
** When Rewind() is called, any data remaining in memory is flushed to a
** final PMA. So at this point the data is stored in some number of sorted
** PMAs within temporary files on disk.
**
** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
** sorter is running in single-threaded mode, then these PMAs are merged
** incrementally as keys are retreived from the sorter by the VDBE. The
** MergeEngine object, described in further detail below, performs this
** merge.
**
** Or, if running in multi-threaded mode, then a background thread is
** launched to merge the existing PMAs. Once the background thread has
** merged T bytes of data into a single sorted PMA, the main thread
** begins reading keys from that PMA while the background thread proceeds
** with merging the next T bytes of data. And so on.
**
** Parameter T is set to half the value of the memory threshold used
** by Write() above to determine when to create a new PMA.
**
** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when
** Rewind() is called, then a hierarchy of incremental-merges is used.
** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on
** disk are merged together. Then T bytes of data from the second set, and
** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT
** PMAs at a time. This done is to improve locality.
**
** If running in multi-threaded mode and there are more than
** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more
** than one background thread may be created. Specifically, there may be
** one background thread for each temporary file on disk, and one background
** thread to merge the output of each of the others to a single PMA for
** the main thread to read from.
*/
/*
** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various
** messages to stderr that may be helpful in understanding the performance
** characteristics of the sorter in multi-threaded mode.
*/
#if 0
# define SQLITE_DEBUG_SORTER_THREADS 1
#endif
/*
** Private objects used by the sorter
*/
typedef struct MergeEngine MergeEngine; /* Merge PMAs together */
typedef struct PmaReader PmaReader; /* Incrementally read one PMA */
typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */
typedef struct SorterRecord SorterRecord; /* A record being sorted */
typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */
typedef struct SorterFile SorterFile; /* Temporary file object wrapper */
typedef struct SorterList SorterList; /* In-memory list of records */
typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */
/*
** A container for a temp file handle and the current amount of data
** stored in the file.
*/
struct SorterFile {
sqlite3_file *pFd; /* File handle */
i64 iEof; /* Bytes of data stored in pFd */
};
/*
** An in-memory list of objects to be sorted.
**
** If aMemory==0 then each object is allocated separately and the objects
** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects
** are stored in the aMemory[] bulk memory, one right after the other, and
** are connected using SorterRecord.u.iNext.
*/
struct SorterList {
SorterRecord *pList; /* Linked list of records */
u8 *aMemory; /* If non-NULL, bulk memory to hold pList */
int szPMA; /* Size of pList as PMA in bytes */
};
/*
** The MergeEngine object is used to combine two or more smaller PMAs into
** one big PMA using a merge operation. Separate PMAs all need to be
** combined into one big PMA in order to be able to step through the sorted
** records in order.
**
** The aReadr[] array contains a PmaReader object for each of the PMAs being
** merged. An aReadr[] object either points to a valid key or else is at EOF.
** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.)
** For the purposes of the paragraphs below, we assume that the array is
** actually N elements in size, where N is the smallest power of 2 greater
** to or equal to the number of PMAs being merged. The extra aReadr[] elements
** are treated as if they are empty (always at EOF).
**
** The aTree[] array is also N elements in size. The value of N is stored in
** the MergeEngine.nTree variable.
**
** The final (N/2) elements of aTree[] contain the results of comparing
** pairs of PMA keys together. Element i contains the result of
** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the
** aTree element is set to the index of it.
**
** For the purposes of this comparison, EOF is considered greater than any
** other key value. If the keys are equal (only possible with two EOF
** values), it doesn't matter which index is stored.
**
** The (N/4) elements of aTree[] that precede the final (N/2) described
** above contains the index of the smallest of each block of 4 PmaReaders
** And so on. So that aTree[1] contains the index of the PmaReader that
** currently points to the smallest key value. aTree[0] is unused.
**
** Example:
**
** aReadr[0] -> Banana
** aReadr[1] -> Feijoa
** aReadr[2] -> Elderberry
** aReadr[3] -> Currant
** aReadr[4] -> Grapefruit
** aReadr[5] -> Apple
** aReadr[6] -> Durian
** aReadr[7] -> EOF
**
** aTree[] = { X, 5 0, 5 0, 3, 5, 6 }
**
** The current element is "Apple" (the value of the key indicated by
** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will
** be advanced to the next key in its segment. Say the next key is
** "Eggplant":
**
** aReadr[5] -> Eggplant
**
** The contents of aTree[] are updated first by comparing the new PmaReader
** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader
** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree.
** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader
** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Banana<Durian),
** so the value written into element 1 of the array is 0. As follows:
**
** aTree[] = { X, 0 0, 6 0, 3, 5, 6 }
**
** In other words, each time we advance to the next sorter element, log2(N)
** key comparison operations are required, where N is the number of segments
** being merged (rounded up to the next power of 2).
*/
struct MergeEngine {
int nTree; /* Used size of aTree/aReadr (power of 2) */
SortSubtask *pTask; /* Used by this thread only */
int *aTree; /* Current state of incremental merge */
PmaReader *aReadr; /* Array of PmaReaders to merge data from */
};
/*
** This object represents a single thread of control in a sort operation.
** Exactly VdbeSorter.nTask instances of this object are allocated
** as part of each VdbeSorter object. Instances are never allocated any
** other way. VdbeSorter.nTask is set to the number of worker threads allowed
** (see SQLITE_CONFIG_WORKER_THREADS) plus one (the main thread). Thus for
** single-threaded operation, there is exactly one instance of this object
** and for multi-threaded operation there are two or more instances.
**
** Essentially, this structure contains all those fields of the VdbeSorter
** structure for which each thread requires a separate instance. For example,
** each thread requries its own UnpackedRecord object to unpack records in
** as part of comparison operations.
**
** Before a background thread is launched, variable bDone is set to 0. Then,
** right before it exits, the thread itself sets bDone to 1. This is used for
** two purposes:
**
** 1. When flushing the contents of memory to a level-0 PMA on disk, to
** attempt to select a SortSubtask for which there is not already an
** active background thread (since doing so causes the main thread
** to block until it finishes).
**
** 2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call
** to sqlite3ThreadJoin() is likely to block. Cases that are likely to
** block provoke debugging output.
**
** In both cases, the effects of the main thread seeing (bDone==0) even
** after the thread has finished are not dire. So we don't worry about
** memory barriers and such here.
*/
struct SortSubtask {
SQLiteThread *pThread; /* Background thread, if any */
int bDone; /* Set if thread is finished but not joined */
VdbeSorter *pSorter; /* Sorter that owns this sub-task */
UnpackedRecord *pUnpacked; /* Space to unpack a record */
SorterList list; /* List for thread to write to a PMA */
int nPMA; /* Number of PMAs currently in file */
SorterFile file; /* Temp file for level-0 PMAs */
SorterFile file2; /* Space for other PMAs */
};
/*
** Main sorter structure. A single instance of this is allocated for each
** sorter cursor created by the VDBE.
**
** mxKeysize:
** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(),
** this variable is updated so as to be set to the size on disk of the
** largest record in the sorter.
*/
struct VdbeSorter {
int mnPmaSize; /* Minimum PMA size, in bytes */
int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */
int mxKeysize; /* Largest serialized key seen so far */
int pgsz; /* Main database page size */
PmaReader *pReader; /* Readr data from here after Rewind() */
MergeEngine *pMerger; /* Or here, if bUseThreads==0 */
sqlite3 *db; /* Database connection */
KeyInfo *pKeyInfo; /* How to compare records */
UnpackedRecord *pUnpacked; /* Used by VdbeSorterCompare() */
SorterList list; /* List of in-memory records */
int iMemory; /* Offset of free space in list.aMemory */
int nMemory; /* Size of list.aMemory allocation in bytes */
u8 bUsePMA; /* True if one or more PMAs created */
u8 bUseThreads; /* True to use background threads */
u8 iPrev; /* Previous thread used to flush PMA */
u8 nTask; /* Size of aTask[] array */
SortSubtask aTask[1]; /* One or more subtasks */
};
/*
** An instance of the following object is used to read records out of a
** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
** aKey might point into aMap or into aBuffer. If neither of those locations
** contain a contiguous representation of the key, then aAlloc is allocated
** and the key is copied into aAlloc and aKey is made to poitn to aAlloc.
**
** pFd==0 at EOF.
*/
struct PmaReader {
i64 iReadOff; /* Current read offset */
i64 iEof; /* 1 byte past EOF for this PmaReader */
int nAlloc; /* Bytes of space at aAlloc */
int nKey; /* Number of bytes in key */
sqlite3_file *pFd; /* File handle we are reading from */
u8 *aAlloc; /* Space for aKey if aBuffer and pMap wont work */
u8 *aKey; /* Pointer to current key */
u8 *aBuffer; /* Current read buffer */
int nBuffer; /* Size of read buffer in bytes */
u8 *aMap; /* Pointer to mapping of entire file */
IncrMerger *pIncr; /* Incremental merger */
};
/*
** Normally, a PmaReader object iterates through an existing PMA stored
** within a temp file. However, if the PmaReader.pIncr variable points to
** an object of the following type, it may be used to iterate/merge through
** multiple PMAs simultaneously.
**
** There are two types of IncrMerger object - single (bUseThread==0) and
** multi-threaded (bUseThread==1).
**
** A multi-threaded IncrMerger object uses two temporary files - aFile[0]
** and aFile[1]. Neither file is allowed to grow to more than mxSz bytes in
** size. When the IncrMerger is initialized, it reads enough data from
** pMerger to populate aFile[0]. It then sets variables within the
** corresponding PmaReader object to read from that file and kicks off
** a background thread to populate aFile[1] with the next mxSz bytes of
** sorted record data from pMerger.
**
** When the PmaReader reaches the end of aFile[0], it blocks until the
** background thread has finished populating aFile[1]. It then exchanges
** the contents of the aFile[0] and aFile[1] variables within this structure,
** sets the PmaReader fields to read from the new aFile[0] and kicks off
** another background thread to populate the new aFile[1]. And so on, until
** the contents of pMerger are exhausted.
**
** A single-threaded IncrMerger does not open any temporary files of its
** own. Instead, it has exclusive access to mxSz bytes of space beginning
** at offset iStartOff of file pTask->file2. And instead of using a
** background thread to prepare data for the PmaReader, with a single
** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with
** keys from pMerger by the calling thread whenever the PmaReader runs out
** of data.
*/
struct IncrMerger {
SortSubtask *pTask; /* Task that owns this merger */
MergeEngine *pMerger; /* Merge engine thread reads data from */
i64 iStartOff; /* Offset to start writing file at */
int mxSz; /* Maximum bytes of data to store */
int bEof; /* Set to true when merge is finished */
int bUseThread; /* True to use a bg thread for this object */
SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */
};
/*
** An instance of this object is used for writing a PMA.
**
** The PMA is written one record at a time. Each record is of an arbitrary
** size. But I/O is more efficient if it occurs in page-sized blocks where
** each block is aligned on a page boundary. This object caches writes to
** the PMA so that aligned, page-size blocks are written.
*/
struct PmaWriter {
int eFWErr; /* Non-zero if in an error state */
u8 *aBuffer; /* Pointer to write buffer */
int nBuffer; /* Size of write buffer in bytes */
int iBufStart; /* First byte of buffer to write */
int iBufEnd; /* Last byte of buffer to write */
i64 iWriteOff; /* Offset of start of buffer in file */
sqlite3_file *pFd; /* File handle to write to */
};
/*
** This object is the header on a single record while that record is being
** held in memory and prior to being written out as part of a PMA.
**
** How the linked list is connected depends on how memory is being managed
** by this module. If using a separate allocation for each in-memory record
** (VdbeSorter.list.aMemory==0), then the list is always connected using the
** SorterRecord.u.pNext pointers.
**
** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0),
** then while records are being accumulated the list is linked using the
** SorterRecord.u.iNext offset. This is because the aMemory[] array may
** be sqlite3Realloc()ed while records are being accumulated. Once the VM
** has finished passing records to the sorter, or when the in-memory buffer
** is full, the list is sorted. As part of the sorting process, it is
** converted to use the SorterRecord.u.pNext pointers. See function
** vdbeSorterSort() for details.
*/
struct SorterRecord {
int nVal; /* Size of the record in bytes */
union {
SorterRecord *pNext; /* Pointer to next record in list */
int iNext; /* Offset within aMemory of next record */
} u;
/* The data for the record immediately follows this header */
};
/* Return a pointer to the buffer containing the record data for SorterRecord
** object p. Should be used as if:
**
** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
*/
#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
/* The minimum PMA size is set to this value multiplied by the database
** page size in bytes. */
#define SORTER_MIN_WORKING 10
/* Maximum number of PMAs that a single MergeEngine can merge */
#define SORTER_MAX_MERGE_COUNT 16
static int vdbeIncrSwap(IncrMerger*);
static void vdbeIncrFree(IncrMerger *);
/*
** Free all memory belonging to the PmaReader object passed as the
** argument. All structure fields are set to zero before returning.
*/
static void vdbePmaReaderClear(PmaReader *pReadr){
sqlite3_free(pReadr->aAlloc);
sqlite3_free(pReadr->aBuffer);
if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap);
vdbeIncrFree(pReadr->pIncr);
memset(pReadr, 0, sizeof(PmaReader));
}
/*
** Read the next nByte bytes of data from the PMA p.
** If successful, set *ppOut to point to a buffer containing the data
** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
** error code.
**
** The buffer returned in *ppOut is only valid until the
** next call to this function.
*/
static int vdbePmaReadBlob(
PmaReader *p, /* PmaReader from which to take the blob */
int nByte, /* Bytes of data to read */
u8 **ppOut /* OUT: Pointer to buffer containing data */
){
int iBuf; /* Offset within buffer to read from */
int nAvail; /* Bytes of data available in buffer */
if( p->aMap ){
*ppOut = &p->aMap[p->iReadOff];
p->iReadOff += nByte;
return SQLITE_OK;
}
assert( p->aBuffer );
/* If there is no more data to be read from the buffer, read the next
** p->nBuffer bytes of data from the file into it. Or, if there are less
** than p->nBuffer bytes remaining in the PMA, read all remaining data. */
iBuf = p->iReadOff % p->nBuffer;
if( iBuf==0 ){
int nRead; /* Bytes to read from disk */
int rc; /* sqlite3OsRead() return code */
/* Determine how many bytes of data to read. */
if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){
nRead = p->nBuffer;
}else{
nRead = (int)(p->iEof - p->iReadOff);
}
assert( nRead>0 );
/* Readr data from the file. Return early if an error occurs. */
rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff);
assert( rc!=SQLITE_IOERR_SHORT_READ );
if( rc!=SQLITE_OK ) return rc;
}
nAvail = p->nBuffer - iBuf;
if( nByte<=nAvail ){
/* The requested data is available in the in-memory buffer. In this
** case there is no need to make a copy of the data, just return a
** pointer into the buffer to the caller. */
*ppOut = &p->aBuffer[iBuf];
p->iReadOff += nByte;
}else{
/* The requested data is not all available in the in-memory buffer.
** In this case, allocate space at p->aAlloc[] to copy the requested
** range into. Then return a copy of pointer p->aAlloc to the caller. */
int nRem; /* Bytes remaining to copy */
/* Extend the p->aAlloc[] allocation if required. */
if( p->nAlloc<nByte ){
u8 *aNew;
int nNew = MAX(128, p->nAlloc*2);
while( nByte>nNew ) nNew = nNew*2;
aNew = sqlite3Realloc(p->aAlloc, nNew);
if( !aNew ) return SQLITE_NOMEM;
p->nAlloc = nNew;
p->aAlloc = aNew;
}
/* Copy as much data as is available in the buffer into the start of
** p->aAlloc[]. */
memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail);
p->iReadOff += nAvail;
nRem = nByte - nAvail;
/* The following loop copies up to p->nBuffer bytes per iteration into
** the p->aAlloc[] buffer. */
while( nRem>0 ){
int rc; /* vdbePmaReadBlob() return code */
int nCopy; /* Number of bytes to copy */
u8 *aNext; /* Pointer to buffer to copy data from */
nCopy = nRem;
if( nRem>p->nBuffer ) nCopy = p->nBuffer;
rc = vdbePmaReadBlob(p, nCopy, &aNext);
if( rc!=SQLITE_OK ) return rc;
assert( aNext!=p->aAlloc );
memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
nRem -= nCopy;
}
*ppOut = p->aAlloc;
}
return SQLITE_OK;
}
/*
** Read a varint from the stream of data accessed by p. Set *pnOut to
** the value read.
*/
static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){
int iBuf;
if( p->aMap ){
p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut);
}else{
iBuf = p->iReadOff % p->nBuffer;
if( iBuf && (p->nBuffer-iBuf)>=9 ){
p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
}else{
u8 aVarint[16], *a;
int i = 0, rc;
do{
rc = vdbePmaReadBlob(p, 1, &a);
if( rc ) return rc;
aVarint[(i++)&0xf] = a[0];
}while( (a[0]&0x80)!=0 );
sqlite3GetVarint(aVarint, pnOut);
}
}
return SQLITE_OK;
}
/*
** Attempt to memory map file pFile. If successful, set *pp to point to the
** new mapping and return SQLITE_OK. If the mapping is not attempted
** (because the file is too large or the VFS layer is configured not to use
** mmap), return SQLITE_OK and set *pp to NULL.
**
** Or, if an error occurs, return an SQLite error code. The final value of
** *pp is undefined in this case.
*/
static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){
int rc = SQLITE_OK;
if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){
rc = sqlite3OsFetch(pFile->pFd, 0, (int)pFile->iEof, (void**)pp);
testcase( rc!=SQLITE_OK );
}
return rc;
}
/*
** Attach PmaReader pReadr to file pFile (if it is not already attached to
** that file) and seek it to offset iOff within the file. Return SQLITE_OK
** if successful, or an SQLite error code if an error occurs.
*/
static int vdbePmaReaderSeek(
SortSubtask *pTask, /* Task context */
PmaReader *pReadr, /* Reader whose cursor is to be moved */
SorterFile *pFile, /* Sorter file to read from */
i64 iOff /* Offset in pFile */
){
int rc = SQLITE_OK;
assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 );
if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ;
if( pReadr->aMap ){
sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap);
pReadr->aMap = 0;
}
pReadr->iReadOff = iOff;
pReadr->iEof = pFile->iEof;
pReadr->pFd = pFile->pFd;
rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap);
if( rc==SQLITE_OK && pReadr->aMap==0 ){
int pgsz = pTask->pSorter->pgsz;
int iBuf = pReadr->iReadOff % pgsz;
if( pReadr->aBuffer==0 ){
pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
pReadr->nBuffer = pgsz;
}
if( rc==SQLITE_OK && iBuf ){
int nRead = pgsz - iBuf;
if( (pReadr->iReadOff + nRead) > pReadr->iEof ){
nRead = (int)(pReadr->iEof - pReadr->iReadOff);
}
rc = sqlite3OsRead(
pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff
);
testcase( rc!=SQLITE_OK );
}
}
return rc;
}
/*
** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if
** no error occurs, or an SQLite error code if one does.
*/
static int vdbePmaReaderNext(PmaReader *pReadr){
int rc = SQLITE_OK; /* Return Code */
u64 nRec = 0; /* Size of record in bytes */
if( pReadr->iReadOff>=pReadr->iEof ){
IncrMerger *pIncr = pReadr->pIncr;
int bEof = 1;
if( pIncr ){
rc = vdbeIncrSwap(pIncr);
if( rc==SQLITE_OK && pIncr->bEof==0 ){
rc = vdbePmaReaderSeek(
pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff
);
bEof = 0;
}
}
if( bEof ){
/* This is an EOF condition */
vdbePmaReaderClear(pReadr);
testcase( rc!=SQLITE_OK );
return rc;
}
}
if( rc==SQLITE_OK ){
rc = vdbePmaReadVarint(pReadr, &nRec);
}
if( rc==SQLITE_OK ){
pReadr->nKey = (int)nRec;
rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey);
testcase( rc!=SQLITE_OK );
}
return rc;
}
/*
** Initialize PmaReader pReadr to scan through the PMA stored in file pFile
** starting at offset iStart and ending at offset iEof-1. This function
** leaves the PmaReader pointing to the first key in the PMA (or EOF if the
** PMA is empty).
**
** If the pnByte parameter is NULL, then it is assumed that the file
** contains a single PMA, and that that PMA omits the initial length varint.
*/
static int vdbePmaReaderInit(
SortSubtask *pTask, /* Task context */
SorterFile *pFile, /* Sorter file to read from */
i64 iStart, /* Start offset in pFile */
PmaReader *pReadr, /* PmaReader to populate */
i64 *pnByte /* IN/OUT: Increment this value by PMA size */
){
int rc;
assert( pFile->iEof>iStart );
assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 );
assert( pReadr->aBuffer==0 );
assert( pReadr->aMap==0 );
rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart);
if( rc==SQLITE_OK ){
u64 nByte; /* Size of PMA in bytes */
rc = vdbePmaReadVarint(pReadr, &nByte);
pReadr->iEof = pReadr->iReadOff + nByte;
*pnByte += nByte;
}
if( rc==SQLITE_OK ){
rc = vdbePmaReaderNext(pReadr);
}
return rc;
}
/*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
** used by the comparison. Return the result of the comparison.
**
** Before returning, object (pTask->pUnpacked) is populated with the
** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it
** is assumed that the (pTask->pUnpacked) structure already contains the
** unpacked key to use as key2.
**
** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
** to SQLITE_NOMEM.
*/
static int vdbeSorterCompare(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( pKey2 ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
}
return sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0);
}
/*
** Initialize the temporary index cursor just opened as a sorter cursor.
**
** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
** to determine the number of fields that should be compared from the
** records being sorted. However, if the value passed as argument nField
** is non-zero and the sorter is able to guarantee a stable sort, nField
** is used instead. This is used when sorting records for a CREATE INDEX
** statement. In this case, keys are always delivered to the sorter in
** order of the primary key, which happens to be make up the final part
** of the records being sorted. So if the sort is stable, there is never
** any reason to compare PK fields and they can be ignored for a small
** performance boost.
**
** The sorter can guarantee a stable sort when running in single-threaded
** mode, but not in multi-threaded mode.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterInit(
sqlite3 *db, /* Database connection (for malloc()) */
int nField, /* Number of key fields in each record */
VdbeCursor *pCsr /* Cursor that holds the new sorter */
){
int pgsz; /* Page size of main database */
int i; /* Used to iterate through aTask[] */
int mxCache; /* Cache size */
VdbeSorter *pSorter; /* The new sorter */
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
int sz; /* Size of pSorter in bytes */
int rc = SQLITE_OK;
#if SQLITE_MAX_WORKER_THREADS==0
# define nWorker 0
#else
int nWorker;
#endif
/* Initialize the upper limit on the number of worker threads */
#if SQLITE_MAX_WORKER_THREADS>0
if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){
nWorker = 0;
}else{
nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS];
}
#endif
/* Do not allow the total number of threads (main thread + all workers)
** to exceed the maximum merge count */
#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT
if( nWorker>=SORTER_MAX_MERGE_COUNT ){
nWorker = SORTER_MAX_MERGE_COUNT-1;
}
#endif
assert( pCsr->pKeyInfo && pCsr->pBt==0 );
szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
pCsr->pSorter = pSorter;
if( pSorter==0 ){
rc = SQLITE_NOMEM;
}else{
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
if( nField && nWorker==0 ) pKeyInfo->nField = nField;
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
pSorter->nTask = nWorker + 1;
pSorter->bUseThreads = (pSorter->nTask>1);
pSorter->db = db;
for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
pTask->pSorter = pSorter;
}
if( !sqlite3TempInMemory(db) ){
pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
mxCache = db->aDb[0].pSchema->cache_size;
if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
pSorter->mxPmaSize = mxCache * pgsz;
/* If the application has not configure scratch memory using
** SQLITE_CONFIG_SCRATCH then we assume it is OK to do large memory
** allocations. If scratch memory has been configured, then assume
** large memory allocations should be avoided to prevent heap
** fragmentation.
*/
if( sqlite3GlobalConfig.pScratch==0 ){
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
}
}
}
return rc;
}
#undef nWorker /* Defined at the top of this function */
/*
** Free the list of sorted records starting at pRecord.
*/
static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
SorterRecord *p;
SorterRecord *pNext;
for(p=pRecord; p; p=pNext){
pNext = p->u.pNext;
sqlite3DbFree(db, p);
}
}
/*
** Free all resources owned by the object indicated by argument pTask. All
** fields of *pTask are zeroed before returning.
*/
static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
sqlite3DbFree(db, pTask->pUnpacked);
pTask->pUnpacked = 0;
#if SQLITE_MAX_WORKER_THREADS>0
/* pTask->list.aMemory can only be non-zero if it was handed memory
** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
if( pTask->list.aMemory ){
sqlite3_free(pTask->list.aMemory);
pTask->list.aMemory = 0;
}else
#endif
{
assert( pTask->list.aMemory==0 );
vdbeSorterRecordFree(0, pTask->list.pList);
}
pTask->list.pList = 0;
if( pTask->file.pFd ){
sqlite3OsCloseFree(pTask->file.pFd);
pTask->file.pFd = 0;
pTask->file.iEof = 0;
}
if( pTask->file2.pFd ){
sqlite3OsCloseFree(pTask->file2.pFd);
pTask->file2.pFd = 0;
pTask->file2.iEof = 0;
}
}
#ifdef SQLITE_DEBUG_SORTER_THREADS
static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
i64 t;
int iTask = (pTask - pTask->pSorter->aTask);
sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent);
}
static void vdbeSorterRewindDebug(const char *zEvent){
i64 t;
sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t);
fprintf(stderr, "%lld:X %s\n", t, zEvent);
}
static void vdbeSorterPopulateDebug(
SortSubtask *pTask,
const char *zEvent
){
i64 t;
int iTask = (pTask - pTask->pSorter->aTask);
sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent);
}
static void vdbeSorterBlockDebug(
SortSubtask *pTask,
int bBlocked,
const char *zEvent
){
if( bBlocked ){
i64 t;
sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
fprintf(stderr, "%lld:main %s\n", t, zEvent);
}
}
#else
# define vdbeSorterWorkDebug(x,y)
# define vdbeSorterRewindDebug(y)
# define vdbeSorterPopulateDebug(x,y)
# define vdbeSorterBlockDebug(x,y,z)
#endif
#if SQLITE_MAX_WORKER_THREADS>0
/*
** Join thread pTask->thread.
*/
static int vdbeSorterJoinThread(SortSubtask *pTask){
int rc = SQLITE_OK;
if( pTask->pThread ){
#ifdef SQLITE_DEBUG_SORTER_THREADS
int bDone = pTask->bDone;
#endif
void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR);
vdbeSorterBlockDebug(pTask, !bDone, "enter");
(void)sqlite3ThreadJoin(pTask->pThread, &pRet);
vdbeSorterBlockDebug(pTask, !bDone, "exit");
rc = SQLITE_PTR_TO_INT(pRet);
assert( pTask->bDone==1 );
pTask->bDone = 0;
pTask->pThread = 0;
}
return rc;
}
/*
** Launch a background thread to run xTask(pIn).
*/
static int vdbeSorterCreateThread(
SortSubtask *pTask, /* Thread will use this task object */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
assert( pTask->pThread==0 && pTask->bDone==0 );
return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn);
}
/*
** Join all outstanding threads launched by SorterWrite() to create
** level-0 PMAs.
*/
static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){
int rc = rcin;
int i;
/* This function is always called by the main user thread.
**
** If this function is being called after SorterRewind() has been called,
** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread
** is currently attempt to join one of the other threads. To avoid a race
** condition where this thread also attempts to join the same object, join
** thread pSorter->aTask[pSorter->nTask-1].pThread first. */
for(i=pSorter->nTask-1; i>=0; i--){
SortSubtask *pTask = &pSorter->aTask[i];
int rc2 = vdbeSorterJoinThread(pTask);
if( rc==SQLITE_OK ) rc = rc2;
}
return rc;
}
#else
# define vdbeSorterJoinAll(x,rcin) (rcin)
# define vdbeSorterJoinThread(pTask) SQLITE_OK
#endif
/*
** Allocate a new MergeEngine object capable of handling up to
** nReader PmaReader inputs.
**
** nReader is automatically rounded up to the next power of two.
** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up.
*/
static MergeEngine *vdbeMergeEngineNew(int nReader){
int N = 2; /* Smallest power of two >= nReader */
int nByte; /* Total bytes of space to allocate */
MergeEngine *pNew; /* Pointer to allocated object to return */
assert( nReader<=SORTER_MAX_MERGE_COUNT );
while( N<nReader ) N += N;
nByte = sizeof(MergeEngine) + N * (sizeof(int) + sizeof(PmaReader));
pNew = sqlite3FaultSim(100) ? 0 : (MergeEngine*)sqlite3MallocZero(nByte);
if( pNew ){
pNew->nTree = N;
pNew->pTask = 0;
pNew->aReadr = (PmaReader*)&pNew[1];
pNew->aTree = (int*)&pNew->aReadr[N];
}
return pNew;
}
/*
** Free the MergeEngine object passed as the only argument.
*/
static void vdbeMergeEngineFree(MergeEngine *pMerger){
int i;
if( pMerger ){
for(i=0; i<pMerger->nTree; i++){
vdbePmaReaderClear(&pMerger->aReadr[i]);
}
}
sqlite3_free(pMerger);
}
/*
** Free all resources associated with the IncrMerger object indicated by
** the first argument.
*/
static void vdbeIncrFree(IncrMerger *pIncr){
if( pIncr ){
#if SQLITE_MAX_WORKER_THREADS>0
if( pIncr->bUseThread ){
vdbeSorterJoinThread(pIncr->pTask);
if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd);
if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd);
}
#endif
vdbeMergeEngineFree(pIncr->pMerger);
sqlite3_free(pIncr);
}
}
/*
** Reset a sorting cursor back to its original empty state.
*/
SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
int i;
(void)vdbeSorterJoinAll(pSorter, SQLITE_OK);
assert( pSorter->bUseThreads || pSorter->pReader==0 );
#if SQLITE_MAX_WORKER_THREADS>0
if( pSorter->pReader ){
vdbePmaReaderClear(pSorter->pReader);
sqlite3DbFree(db, pSorter->pReader);
pSorter->pReader = 0;
}
#endif
vdbeMergeEngineFree(pSorter->pMerger);
pSorter->pMerger = 0;
for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
vdbeSortSubtaskCleanup(db, pTask);
}
if( pSorter->list.aMemory==0 ){
vdbeSorterRecordFree(0, pSorter->list.pList);
}
pSorter->list.pList = 0;
pSorter->list.szPMA = 0;
pSorter->bUsePMA = 0;
pSorter->iMemory = 0;
pSorter->mxKeysize = 0;
sqlite3DbFree(db, pSorter->pUnpacked);
pSorter->pUnpacked = 0;
}
/*
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
VdbeSorter *pSorter = pCsr->pSorter;
if( pSorter ){
sqlite3VdbeSorterReset(db, pSorter);
sqlite3_free(pSorter->list.aMemory);
sqlite3DbFree(db, pSorter);
pCsr->pSorter = 0;
}
}
#if SQLITE_MAX_MMAP_SIZE>0
/*
** The first argument is a file-handle open on a temporary file. The file
** is guaranteed to be nByte bytes or smaller in size. This function
** attempts to extend the file to nByte bytes in size and to ensure that
** the VFS has memory mapped it.
**
** Whether or not the file does end up memory mapped of course depends on
** the specific VFS implementation.
*/
static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
if( nByte<=(i64)(db->nMaxSorterMmap) ){
int rc = sqlite3OsTruncate(pFd, nByte);
if( rc==SQLITE_OK ){
void *p = 0;
sqlite3OsFetch(pFd, 0, (int)nByte, &p);
sqlite3OsUnfetch(pFd, 0, p);
}
}
}
#else
# define vdbeSorterExtendFile(x,y,z)
#endif
/*
** Allocate space for a file-handle and open a temporary file. If successful,
** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK.
** Otherwise, set *ppFd to 0 and return an SQLite error code.
*/
static int vdbeSorterOpenTempFile(
sqlite3 *db, /* Database handle doing sort */
i64 nExtend, /* Attempt to extend file to this size */
sqlite3_file **ppFd
){
int rc;
rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd,
SQLITE_OPEN_TEMP_JOURNAL |
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc
);
if( rc==SQLITE_OK ){
i64 max = SQLITE_MAX_MMAP_SIZE;
sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max);
if( nExtend>0 ){
vdbeSorterExtendFile(db, *ppFd, nExtend);
}
}
return rc;
}
/*
** If it has not already been allocated, allocate the UnpackedRecord
** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or
** if no allocation was required), or SQLITE_NOMEM otherwise.
*/
static int vdbeSortAllocUnpacked(SortSubtask *pTask){
if( pTask->pUnpacked==0 ){
char *pFree;
pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(
pTask->pSorter->pKeyInfo, 0, 0, &pFree
);
assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
if( pFree==0 ) return SQLITE_NOMEM;
pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
pTask->pUnpacked->errCode = 0;
}
return SQLITE_OK;
}
/*
** Merge the two sorted lists p1 and p2 into a single list.
** Set *ppOut to the head of the new list.
*/
static void vdbeSorterMerge(
SortSubtask *pTask, /* Calling thread context */
SorterRecord *p1, /* First list to merge */
SorterRecord *p2, /* Second list to merge */
SorterRecord **ppOut /* OUT: Head of merged list */
){
SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal;
void *pVal2 = p2 ? SRVAL(p2) : 0;
while( p1 && p2 ){
int res;
res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal);
if( res<=0 ){
*pp = p1;
pp = &p1->u.pNext;
p1 = p1->u.pNext;
pVal2 = 0;
}else{
*pp = p2;
pp = &p2->u.pNext;
p2 = p2->u.pNext;
if( p2==0 ) break;
pVal2 = SRVAL(p2);
}
}
*pp = p1 ? p1 : p2;
*ppOut = pFinal;
}
/*
** Sort the linked list of records headed at pTask->pList. Return
** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
** an error occurs.
*/
static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
int i;
SorterRecord **aSlot;
SorterRecord *p;
int rc;
rc = vdbeSortAllocUnpacked(pTask);
if( rc!=SQLITE_OK ) return rc;
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){
return SQLITE_NOMEM;
}
p = pList->pList;
while( p ){
SorterRecord *pNext;
if( pList->aMemory ){
if( (u8*)p==pList->aMemory ){
pNext = 0;
}else{
assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) );
pNext = (SorterRecord*)&pList->aMemory[p->u.iNext];
}
}else{
pNext = p->u.pNext;
}
p->u.pNext = 0;
for(i=0; aSlot[i]; i++){
vdbeSorterMerge(pTask, p, aSlot[i], &p);
aSlot[i] = 0;
}
aSlot[i] = p;
p = pNext;
}
p = 0;
for(i=0; i<64; i++){
vdbeSorterMerge(pTask, p, aSlot[i], &p);
}
pList->pList = p;
sqlite3_free(aSlot);
assert( pTask->pUnpacked->errCode==SQLITE_OK
|| pTask->pUnpacked->errCode==SQLITE_NOMEM
);
return pTask->pUnpacked->errCode;
}
/*
** Initialize a PMA-writer object.
*/
static void vdbePmaWriterInit(
sqlite3_file *pFd, /* File handle to write to */
PmaWriter *p, /* Object to populate */
int nBuf, /* Buffer size */
i64 iStart /* Offset of pFd to begin writing at */
){
memset(p, 0, sizeof(PmaWriter));
p->aBuffer = (u8*)sqlite3Malloc(nBuf);
if( !p->aBuffer ){
p->eFWErr = SQLITE_NOMEM;
}else{
p->iBufEnd = p->iBufStart = (iStart % nBuf);
p->iWriteOff = iStart - p->iBufStart;
p->nBuffer = nBuf;
p->pFd = pFd;
}
}
/*
** Write nData bytes of data to the PMA. Return SQLITE_OK
** if successful, or an SQLite error code if an error occurs.
*/
static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){
int nRem = nData;
while( nRem>0 && p->eFWErr==0 ){
int nCopy = nRem;
if( nCopy>(p->nBuffer - p->iBufEnd) ){
nCopy = p->nBuffer - p->iBufEnd;
}
memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
p->iBufEnd += nCopy;
if( p->iBufEnd==p->nBuffer ){
p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
p->iBufStart = p->iBufEnd = 0;
p->iWriteOff += p->nBuffer;
}
assert( p->iBufEnd<p->nBuffer );
nRem -= nCopy;
}
}
/*
** Flush any buffered data to disk and clean up the PMA-writer object.
** The results of using the PMA-writer after this call are undefined.
** Return SQLITE_OK if flushing the buffered data succeeds or is not
** required. Otherwise, return an SQLite error code.
**
** Before returning, set *piEof to the offset immediately following the
** last byte written to the file.
*/
static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){
int rc;
if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
}
*piEof = (p->iWriteOff + p->iBufEnd);
sqlite3_free(p->aBuffer);
rc = p->eFWErr;
memset(p, 0, sizeof(PmaWriter));
return rc;
}
/*
** Write value iVal encoded as a varint to the PMA. Return
** SQLITE_OK if successful, or an SQLite error code if an error occurs.
*/
static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){
int nByte;
u8 aByte[10];
nByte = sqlite3PutVarint(aByte, iVal);
vdbePmaWriteBlob(p, aByte, nByte);
}
/*
** Write the current contents of in-memory linked-list pList to a level-0
** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if
** successful, or an SQLite error code otherwise.
**
** The format of a PMA is:
**
** * A varint. This varint contains the total number of bytes of content
** in the PMA (not including the varint itself).
**
** * One or more records packed end-to-end in order of ascending keys.
** Each record consists of a varint followed by a blob of data (the
** key). The varint is the number of bytes in the blob of data.
*/
static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){
sqlite3 *db = pTask->pSorter->db;
int rc = SQLITE_OK; /* Return code */
PmaWriter writer; /* Object used to write to the file */
#ifdef SQLITE_DEBUG
/* Set iSz to the expected size of file pTask->file after writing the PMA.
** This is used by an assert() statement at the end of this function. */
i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof;
#endif
vdbeSorterWorkDebug(pTask, "enter");
memset(&writer, 0, sizeof(PmaWriter));
assert( pList->szPMA>0 );
/* If the first temporary PMA file has not been opened, open it now. */
if( pTask->file.pFd==0 ){
rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd);
assert( rc!=SQLITE_OK || pTask->file.pFd );
assert( pTask->file.iEof==0 );
assert( pTask->nPMA==0 );
}
/* Try to get the file to memory map */
if( rc==SQLITE_OK ){
vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9);
}
/* Sort the list */
if( rc==SQLITE_OK ){
rc = vdbeSorterSort(pTask, pList);
}
if( rc==SQLITE_OK ){
SorterRecord *p;
SorterRecord *pNext = 0;
vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz,
pTask->file.iEof);
pTask->nPMA++;
vdbePmaWriteVarint(&writer, pList->szPMA);
for(p=pList->pList; p; p=pNext){
pNext = p->u.pNext;
vdbePmaWriteVarint(&writer, p->nVal);
vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal);
if( pList->aMemory==0 ) sqlite3_free(p);
}
pList->pList = p;
rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof);
}
vdbeSorterWorkDebug(pTask, "exit");
assert( rc!=SQLITE_OK || pList->pList==0 );
assert( rc!=SQLITE_OK || pTask->file.iEof==iSz );
return rc;
}
/*
** Advance the MergeEngine to its next entry.
** Set *pbEof to true there is no next entry because
** the MergeEngine has reached the end of all its inputs.
**
** Return SQLITE_OK if successful or an error code if an error occurs.
*/
static int vdbeMergeEngineStep(
MergeEngine *pMerger, /* The merge engine to advance to the next row */
int *pbEof /* Set TRUE at EOF. Set false for more content */
){
int rc;
int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */
SortSubtask *pTask = pMerger->pTask;
/* Advance the current PmaReader */
rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]);
/* Update contents of aTree[] */
if( rc==SQLITE_OK ){
int i; /* Index of aTree[] to recalculate */
PmaReader *pReadr1; /* First PmaReader to compare */
PmaReader *pReadr2; /* Second PmaReader to compare */
u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */
/* Find the first two PmaReaders to compare. The one that was just
** advanced (iPrev) and the one next to it in the array. */
pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
pKey2 = pReadr2->aKey;
for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
/* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
int iRes;
if( pReadr1->pFd==0 ){
iRes = +1;
}else if( pReadr2->pFd==0 ){
iRes = -1;
}else{
iRes = vdbeSorterCompare(pTask,
pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey
);
}
/* If pReadr1 contained the smaller value, set aTree[i] to its index.
** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
** case there is no cache of pReadr2 in pTask->pUnpacked, so set
** pKey2 to point to the record belonging to pReadr2.
**
** Alternatively, if pReadr2 contains the smaller of the two values,
** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare()
** was actually called above, then pTask->pUnpacked now contains
** a value equivalent to pReadr2. So set pKey2 to NULL to prevent
** vdbeSorterCompare() from decoding pReadr2 again.
**
** If the two values were equal, then the value from the oldest
** PMA should be considered smaller. The VdbeSorter.aReadr[] array
** is sorted from oldest to newest, so pReadr1 contains older values
** than pReadr2 iff (pReadr1<pReadr2). */
if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
pKey2 = pReadr2->aKey;
}else{
if( pReadr1->pFd ) pKey2 = 0;
pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
}
}
*pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0);
}
return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc);
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** The main routine for background threads that write level-0 PMAs.
*/
static void *vdbeSorterFlushThread(void *pCtx){
SortSubtask *pTask = (SortSubtask*)pCtx;
int rc; /* Return code */
assert( pTask->bDone==0 );
rc = vdbeSorterListToPMA(pTask, &pTask->list);
pTask->bDone = 1;
return SQLITE_INT_TO_PTR(rc);
}
#endif /* SQLITE_MAX_WORKER_THREADS>0 */
/*
** Flush the current contents of VdbeSorter.list to a new PMA, possibly
** using a background thread.
*/
static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
#if SQLITE_MAX_WORKER_THREADS==0
pSorter->bUsePMA = 1;
return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list);
#else
int rc = SQLITE_OK;
int i;
SortSubtask *pTask = 0; /* Thread context used to create new PMA */
int nWorker = (pSorter->nTask-1);
/* Set the flag to indicate that at least one PMA has been written.
** Or will be, anyhow. */
pSorter->bUsePMA = 1;
/* Select a sub-task to sort and flush the current list of in-memory
** records to disk. If the sorter is running in multi-threaded mode,
** round-robin between the first (pSorter->nTask-1) tasks. Except, if
** the background thread from a sub-tasks previous turn is still running,
** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy,
** fall back to using the final sub-task. The first (pSorter->nTask-1)
** sub-tasks are prefered as they use background threads - the final
** sub-task uses the main thread. */
for(i=0; i<nWorker; i++){
int iTest = (pSorter->iPrev + i + 1) % nWorker;
pTask = &pSorter->aTask[iTest];
if( pTask->bDone ){
rc = vdbeSorterJoinThread(pTask);
}
if( rc!=SQLITE_OK || pTask->pThread==0 ) break;
}
if( rc==SQLITE_OK ){
if( i==nWorker ){
/* Use the foreground thread for this operation */
rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list);
}else{
/* Launch a background thread for this operation */
u8 *aMem = pTask->list.aMemory;
void *pCtx = (void*)pTask;
assert( pTask->pThread==0 && pTask->bDone==0 );
assert( pTask->list.pList==0 );
assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 );
pSorter->iPrev = (u8)(pTask - pSorter->aTask);
pTask->list = pSorter->list;
pSorter->list.pList = 0;
pSorter->list.szPMA = 0;
if( aMem ){
pSorter->list.aMemory = aMem;
pSorter->nMemory = sqlite3MallocSize(aMem);
}else if( pSorter->list.aMemory ){
pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
}
rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
}
}
return rc;
#endif /* SQLITE_MAX_WORKER_THREADS!=0 */
}
/*
** Add a record to the sorter.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal /* Memory cell containing record */
){
VdbeSorter *pSorter = pCsr->pSorter;
int rc = SQLITE_OK; /* Return Code */
SorterRecord *pNew; /* New list element */
int bFlush; /* True to flush contents of memory to PMA */
int nReq; /* Bytes of memory required */
int nPMA; /* Bytes of PMA space required */
assert( pSorter );
/* Figure out whether or not the current contents of memory should be
** flushed to a PMA before continuing. If so, do so.
**
** If using the single large allocation mode (pSorter->aMemory!=0), then
** flush the contents of memory to a new PMA if (a) at least one value is
** already in memory and (b) the new value will not fit in memory.
**
** Or, if using separate allocations for each record, flush the contents
** of memory to a PMA if either of the following are true:
**
** * The total memory allocated for the in-memory list is greater
** than (page-size * cache-size), or
**
** * The total memory allocated for the in-memory list is greater
** than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
*/
nReq = pVal->n + sizeof(SorterRecord);
nPMA = pVal->n + sqlite3VarintLen(pVal->n);
if( pSorter->mxPmaSize ){
if( pSorter->list.aMemory ){
bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize;
}else{
bFlush = (
(pSorter->list.szPMA > pSorter->mxPmaSize)
|| (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull())
);
}
if( bFlush ){
rc = vdbeSorterFlushPMA(pSorter);
pSorter->list.szPMA = 0;
pSorter->iMemory = 0;
assert( rc!=SQLITE_OK || pSorter->list.pList==0 );
}
}
pSorter->list.szPMA += nPMA;
if( nPMA>pSorter->mxKeysize ){
pSorter->mxKeysize = nPMA;
}
if( pSorter->list.aMemory ){
int nMin = pSorter->iMemory + nReq;
if( nMin>pSorter->nMemory ){
u8 *aNew;
int nNew = pSorter->nMemory * 2;
while( nNew < nMin ) nNew = nNew*2;
if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
if( nNew < nMin ) nNew = nMin;
aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
if( !aNew ) return SQLITE_NOMEM;
pSorter->list.pList = (SorterRecord*)(
aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory)
);
pSorter->list.aMemory = aNew;
pSorter->nMemory = nNew;
}
pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
pSorter->iMemory += ROUND8(nReq);
pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
}else{
pNew = (SorterRecord *)sqlite3Malloc(nReq);
if( pNew==0 ){
return SQLITE_NOMEM;
}
pNew->u.pNext = pSorter->list.pList;
}
memcpy(SRVAL(pNew), pVal->z, pVal->n);
pNew->nVal = pVal->n;
pSorter->list.pList = pNew;
return rc;
}
/*
** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format
** of the data stored in aFile[1] is the same as that used by regular PMAs,
** except that the number-of-bytes varint is omitted from the start.
*/
static int vdbeIncrPopulate(IncrMerger *pIncr){
int rc = SQLITE_OK;
int rc2;
i64 iStart = pIncr->iStartOff;
SorterFile *pOut = &pIncr->aFile[1];
SortSubtask *pTask = pIncr->pTask;
MergeEngine *pMerger = pIncr->pMerger;
PmaWriter writer;
assert( pIncr->bEof==0 );
vdbeSorterPopulateDebug(pTask, "enter");
vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart);
while( rc==SQLITE_OK ){
int dummy;
PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ];
int nKey = pReader->nKey;
i64 iEof = writer.iWriteOff + writer.iBufEnd;
/* Check if the output file is full or if the input has been exhausted.
** In either case exit the loop. */
if( pReader->pFd==0 ) break;
if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break;
/* Write the next key to the output. */
vdbePmaWriteVarint(&writer, nKey);
vdbePmaWriteBlob(&writer, pReader->aKey, nKey);
assert( pIncr->pMerger->pTask==pTask );
rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy);
}
rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof);
if( rc==SQLITE_OK ) rc = rc2;
vdbeSorterPopulateDebug(pTask, "exit");
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** The main routine for background threads that populate aFile[1] of
** multi-threaded IncrMerger objects.
*/
static void *vdbeIncrPopulateThread(void *pCtx){
IncrMerger *pIncr = (IncrMerger*)pCtx;
void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) );
pIncr->pTask->bDone = 1;
return pRet;
}
/*
** Launch a background thread to populate aFile[1] of pIncr.
*/
static int vdbeIncrBgPopulate(IncrMerger *pIncr){
void *p = (void*)pIncr;
assert( pIncr->bUseThread );
return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p);
}
#endif
/*
** This function is called when the PmaReader corresponding to pIncr has
** finished reading the contents of aFile[0]. Its purpose is to "refill"
** aFile[0] such that the PmaReader should start rereading it from the
** beginning.
**
** For single-threaded objects, this is accomplished by literally reading
** keys from pIncr->pMerger and repopulating aFile[0].
**
** For multi-threaded objects, all that is required is to wait until the
** background thread is finished (if it is not already) and then swap
** aFile[0] and aFile[1] in place. If the contents of pMerger have not
** been exhausted, this function also launches a new background thread
** to populate the new aFile[1].
**
** SQLITE_OK is returned on success, or an SQLite error code otherwise.
*/
static int vdbeIncrSwap(IncrMerger *pIncr){
int rc = SQLITE_OK;
#if SQLITE_MAX_WORKER_THREADS>0
if( pIncr->bUseThread ){
rc = vdbeSorterJoinThread(pIncr->pTask);
if( rc==SQLITE_OK ){
SorterFile f0 = pIncr->aFile[0];
pIncr->aFile[0] = pIncr->aFile[1];
pIncr->aFile[1] = f0;
}
if( rc==SQLITE_OK ){
if( pIncr->aFile[0].iEof==pIncr->iStartOff ){
pIncr->bEof = 1;
}else{
rc = vdbeIncrBgPopulate(pIncr);
}
}
}else
#endif
{
rc = vdbeIncrPopulate(pIncr);
pIncr->aFile[0] = pIncr->aFile[1];
if( pIncr->aFile[0].iEof==pIncr->iStartOff ){
pIncr->bEof = 1;
}
}
return rc;
}
/*
** Allocate and return a new IncrMerger object to read data from pMerger.
**
** If an OOM condition is encountered, return NULL. In this case free the
** pMerger argument before returning.
*/
static int vdbeIncrMergerNew(
SortSubtask *pTask, /* The thread that will be using the new IncrMerger */
MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */
IncrMerger **ppOut /* Write the new IncrMerger here */
){
int rc = SQLITE_OK;
IncrMerger *pIncr = *ppOut = (IncrMerger*)
(sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr)));
if( pIncr ){
pIncr->pMerger = pMerger;
pIncr->pTask = pTask;
pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2);
pTask->file2.iEof += pIncr->mxSz;
}else{
vdbeMergeEngineFree(pMerger);
rc = SQLITE_NOMEM;
}
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** Set the "use-threads" flag on object pIncr.
*/
static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){
pIncr->bUseThread = 1;
pIncr->pTask->file2.iEof -= pIncr->mxSz;
}
#endif /* SQLITE_MAX_WORKER_THREADS>0 */
/*
** Recompute pMerger->aTree[iOut] by comparing the next keys on the
** two PmaReaders that feed that entry. Neither of the PmaReaders
** are advanced. This routine merely does the comparison.
*/
static void vdbeMergeEngineCompare(
MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */
int iOut /* Store the result in pMerger->aTree[iOut] */
){
int i1;
int i2;
int iRes;
PmaReader *p1;
PmaReader *p2;
assert( iOut<pMerger->nTree && iOut>0 );
if( iOut>=(pMerger->nTree/2) ){
i1 = (iOut - pMerger->nTree/2) * 2;
i2 = i1 + 1;
}else{
i1 = pMerger->aTree[iOut*2];
i2 = pMerger->aTree[iOut*2+1];
}
p1 = &pMerger->aReadr[i1];
p2 = &pMerger->aReadr[i2];
if( p1->pFd==0 ){
iRes = i2;
}else if( p2->pFd==0 ){
iRes = i1;
}else{
int res;
assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
res = vdbeSorterCompare(
pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey
);
if( res<=0 ){
iRes = i1;
}else{
iRes = i2;
}
}
pMerger->aTree[iOut] = iRes;
}
/*
** Allowed values for the eMode parameter to vdbeMergeEngineInit()
** and vdbePmaReaderIncrMergeInit().
**
** Only INCRINIT_NORMAL is valid in single-threaded builds (when
** SQLITE_MAX_WORKER_THREADS==0). The other values are only used
** when there exists one or more separate worker threads.
*/
#define INCRINIT_NORMAL 0
#define INCRINIT_TASK 1
#define INCRINIT_ROOT 2
/* Forward reference.
** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each
** other (when building a merge tree).
*/
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode);
/*
** Initialize the MergeEngine object passed as the second argument. Once this
** function returns, the first key of merged data may be read from the
** MergeEngine object in the usual fashion.
**
** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge
** objects attached to the PmaReader objects that the merger reads from have
** already been populated, but that they have not yet populated aFile[0] and
** set the PmaReader objects up to read from it. In this case all that is
** required is to call vdbePmaReaderNext() on each PmaReader to point it at
** its first key.
**
** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use
** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data
** to pMerger.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
static int vdbeMergeEngineInit(
SortSubtask *pTask, /* Thread that will run pMerger */
MergeEngine *pMerger, /* MergeEngine to initialize */
int eMode /* One of the INCRINIT_XXX constants */
){
int rc = SQLITE_OK; /* Return code */
int i; /* For looping over PmaReader objects */
int nTree = pMerger->nTree;
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
/* Verify that the MergeEngine is assigned to a single thread */
assert( pMerger->pTask==0 );
pMerger->pTask = pTask;
for(i=0; i<nTree; i++){
if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
/* PmaReaders should be normally initialized in order, as if they are
** reading from the same temp file this makes for more linear file IO.
** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
** in use it will block the vdbePmaReaderNext() call while it uses
** the main thread to fill its buffer. So calling PmaReaderNext()
** on this PmaReader before any of the multi-threaded PmaReaders takes
** better advantage of multi-processor hardware. */
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
}else{
rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
}
if( rc!=SQLITE_OK ) return rc;
}
for(i=pMerger->nTree-1; i>0; i--){
vdbeMergeEngineCompare(pMerger, i);
}
return pTask->pUnpacked->errCode;
}
/*
** Initialize the IncrMerge field of a PmaReader.
**
** If the PmaReader passed as the first argument is not an incremental-reader
** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves
** to open and/or initialize the temp file related fields of the IncrMerge
** object at (pReadr->pIncr).
**
** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
** in the sub-tree headed by pReadr are also initialized. Data is then loaded
** into the buffers belonging to pReadr and it is set to
** point to the first key in its range.
**
** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
** to be a multi-threaded PmaReader and this function is being called in a
** background thread. In this case all PmaReaders in the sub-tree are
** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
** pReadr is populated. However, pReadr itself is not set up to point
** to its first key. A call to vdbePmaReaderNext() is still required to do
** that.
**
** The reason this function does not call vdbePmaReaderNext() immediately
** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has
** to block on thread (pTask->thread) before accessing aFile[1]. But, since
** this entire function is being run by thread (pTask->thread), that will
** lead to the current background thread attempting to join itself.
**
** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed
** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
** In this case vdbePmaReaderNext() is called on all child PmaReaders and
** the current PmaReader set to point to the first key in its range.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
int rc = SQLITE_OK;
IncrMerger *pIncr = pReadr->pIncr;
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
if( pIncr ){
SortSubtask *pTask = pIncr->pTask;
sqlite3 *db = pTask->pSorter->db;
rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
/* Set up the required files for pIncr. A multi-theaded IncrMerge object
** requires two temp files to itself, whereas a single-threaded object
** only requires a region of pTask->file2. */
if( rc==SQLITE_OK ){
int mxSz = pIncr->mxSz;
#if SQLITE_MAX_WORKER_THREADS>0
if( pIncr->bUseThread ){
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
if( rc==SQLITE_OK ){
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
}
}else
#endif
/*if( !pIncr->bUseThread )*/{
if( pTask->file2.pFd==0 ){
assert( pTask->file2.iEof>0 );
rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
pTask->file2.iEof = 0;
}
if( rc==SQLITE_OK ){
pIncr->aFile[1].pFd = pTask->file2.pFd;
pIncr->iStartOff = pTask->file2.iEof;
pTask->file2.iEof += mxSz;
}
}
}
#if SQLITE_MAX_WORKER_THREADS>0
if( rc==SQLITE_OK && pIncr->bUseThread ){
/* Use the current thread to populate aFile[1], even though this
** PmaReader is multi-threaded. The reason being that this function
** is already running in background thread pIncr->pTask->thread. */
assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
rc = vdbeIncrPopulate(pIncr);
}
#endif
if( rc==SQLITE_OK
&& (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK)
){
rc = vdbePmaReaderNext(pReadr);
}
}
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** The main routine for vdbePmaReaderIncrMergeInit() operations run in
** background threads.
*/
static void *vdbePmaReaderBgInit(void *pCtx){
PmaReader *pReader = (PmaReader*)pCtx;
void *pRet = SQLITE_INT_TO_PTR(
vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
);
pReader->pIncr->pTask->bDone = 1;
return pRet;
}
/*
** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK)
** on the the PmaReader object passed as the first argument.
**
** This call will initialize the various fields of the pReadr->pIncr
** structure and, if it is a multi-threaded IncrMerger, launch a
** background thread to populate aFile[1].
*/
static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
void *pCtx = (void*)pReadr;
return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx);
}
#endif
/*
** Allocate a new MergeEngine object to merge the contents of nPMA level-0
** PMAs from pTask->file. If no error occurs, set *ppOut to point to
** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
** to NULL and return an SQLite error code.
**
** When this function is called, *piOffset is set to the offset of the
** first PMA to read from pTask->file. Assuming no error occurs, it is
** set to the offset immediately following the last byte of the last
** PMA before returning. If an error does occur, then the final value of
** *piOffset is undefined.
*/
static int vdbeMergeEngineLevel0(
SortSubtask *pTask, /* Sorter task to read from */
int nPMA, /* Number of PMAs to read */
i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */
MergeEngine **ppOut /* OUT: New merge-engine */
){
MergeEngine *pNew; /* Merge engine to return */
i64 iOff = *piOffset;
int i;
int rc = SQLITE_OK;
*ppOut = pNew = vdbeMergeEngineNew(nPMA);
if( pNew==0 ) rc = SQLITE_NOMEM;
for(i=0; i<nPMA && rc==SQLITE_OK; i++){
i64 nDummy;
PmaReader *pReadr = &pNew->aReadr[i];
rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
iOff = pReadr->iEof;
}
if( rc!=SQLITE_OK ){
vdbeMergeEngineFree(pNew);
*ppOut = 0;
}
*piOffset = iOff;
return rc;
}
/*
** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of
** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes.
**
** i.e.
**
** nPMA<=16 -> TreeDepth() == 0
** nPMA<=256 -> TreeDepth() == 1
** nPMA<=65536 -> TreeDepth() == 2
*/
static int vdbeSorterTreeDepth(int nPMA){
int nDepth = 0;
i64 nDiv = SORTER_MAX_MERGE_COUNT;
while( nDiv < (i64)nPMA ){
nDiv = nDiv * SORTER_MAX_MERGE_COUNT;
nDepth++;
}
return nDepth;
}
/*
** pRoot is the root of an incremental merge-tree with depth nDepth (according
** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the
** tree, counting from zero. This function adds pLeaf to the tree.
**
** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error
** code is returned and pLeaf is freed.
*/
static int vdbeSorterAddToTree(
SortSubtask *pTask, /* Task context */
int nDepth, /* Depth of tree according to TreeDepth() */
int iSeq, /* Sequence number of leaf within tree */
MergeEngine *pRoot, /* Root of tree */
MergeEngine *pLeaf /* Leaf to add to tree */
){
int rc = SQLITE_OK;
int nDiv = 1;
int i;
MergeEngine *p = pRoot;
IncrMerger *pIncr;
rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr);
for(i=1; i<nDepth; i++){
nDiv = nDiv * SORTER_MAX_MERGE_COUNT;
}
for(i=1; i<nDepth && rc==SQLITE_OK; i++){
int iIter = (iSeq / nDiv) % SORTER_MAX_MERGE_COUNT;
PmaReader *pReadr = &p->aReadr[iIter];
if( pReadr->pIncr==0 ){
MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
}
}
if( rc==SQLITE_OK ){
p = pReadr->pIncr->pMerger;
nDiv = nDiv / SORTER_MAX_MERGE_COUNT;
}
}
if( rc==SQLITE_OK ){
p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr;
}else{
vdbeIncrFree(pIncr);
}
return rc;
}
/*
** This function is called as part of a SorterRewind() operation on a sorter
** that has already written two or more level-0 PMAs to one or more temp
** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that
** can be used to incrementally merge all PMAs on disk.
**
** If successful, SQLITE_OK is returned and *ppOut set to point to the
** MergeEngine object at the root of the tree before returning. Or, if an
** error occurs, an SQLite error code is returned and the final value
** of *ppOut is undefined.
*/
static int vdbeSorterMergeTreeBuild(
VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */
MergeEngine **ppOut /* Write the MergeEngine here */
){
MergeEngine *pMain = 0;
int rc = SQLITE_OK;
int iTask;
#if SQLITE_MAX_WORKER_THREADS>0
/* If the sorter uses more than one task, then create the top-level
** MergeEngine here. This MergeEngine will read data from exactly
** one PmaReader per sub-task. */
assert( pSorter->bUseThreads || pSorter->nTask==1 );
if( pSorter->nTask>1 ){
pMain = vdbeMergeEngineNew(pSorter->nTask);
if( pMain==0 ) rc = SQLITE_NOMEM;
}
#endif
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
SortSubtask *pTask = &pSorter->aTask[iTask];
assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 );
if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){
MergeEngine *pRoot = 0; /* Root node of tree for this task */
int nDepth = vdbeSorterTreeDepth(pTask->nPMA);
i64 iReadOff = 0;
if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){
rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot);
}else{
int i;
int iSeq = 0;
pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
if( pRoot==0 ) rc = SQLITE_NOMEM;
for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
MergeEngine *pMerger = 0; /* New level-0 PMA merger */
int nReader; /* Number of level-0 PMAs to merge */
nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT);
rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger);
if( rc==SQLITE_OK ){
rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger);
}
}
}
if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS>0
if( pMain!=0 ){
rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr);
}else
#endif
{
assert( pMain==0 );
pMain = pRoot;
}
}else{
vdbeMergeEngineFree(pRoot);
}
}
}
if( rc!=SQLITE_OK ){
vdbeMergeEngineFree(pMain);
pMain = 0;
}
*ppOut = pMain;
return rc;
}
/*
** This function is called as part of an sqlite3VdbeSorterRewind() operation
** on a sorter that has written two or more PMAs to temporary files. It sets
** up either VdbeSorter.pMerger (for single threaded sorters) or pReader
** (for multi-threaded sorters) so that it can be used to iterate through
** all records stored in the sorter.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
int rc; /* Return code */
SortSubtask *pTask0 = &pSorter->aTask[0];
MergeEngine *pMain = 0;
#if SQLITE_MAX_WORKER_THREADS
sqlite3 *db = pTask0->pSorter->db;
#endif
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS
assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
if( pSorter->bUseThreads ){
int iTask;
PmaReader *pReadr;
SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
rc = vdbeSortAllocUnpacked(pLast);
if( rc==SQLITE_OK ){
pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
pSorter->pReader = pReadr;
if( pReadr==0 ) rc = SQLITE_NOMEM;
}
if( rc==SQLITE_OK ){
rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
if( rc==SQLITE_OK ){
vdbeIncrMergerSetThreads(pReadr->pIncr);
for(iTask=0; iTask<(pSorter->nTask-1); iTask++){
IncrMerger *pIncr;
if( (pIncr = pMain->aReadr[iTask].pIncr) ){
vdbeIncrMergerSetThreads(pIncr);
assert( pIncr->pTask!=pLast );
}
}
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
PmaReader *p = &pMain->aReadr[iTask];
assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] );
if( p->pIncr ){
if( iTask==pSorter->nTask-1 ){
rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK);
}else{
rc = vdbePmaReaderBgIncrInit(p);
}
}
}
}
pMain = 0;
}
if( rc==SQLITE_OK ){
rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT);
}
}else
#endif
{
rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL);
pSorter->pMerger = pMain;
pMain = 0;
}
}
if( rc!=SQLITE_OK ){
vdbeMergeEngineFree(pMain);
}
return rc;
}
/*
** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite,
** this function is called to prepare for iterating through the records
** in sorted order.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
VdbeSorter *pSorter = pCsr->pSorter;
int rc = SQLITE_OK; /* Return code */
assert( pSorter );
/* If no data has been written to disk, then do not do so now. Instead,
** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
** from the in-memory list. */
if( pSorter->bUsePMA==0 ){
if( pSorter->list.pList ){
*pbEof = 0;
rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list);
}else{
*pbEof = 1;
}
return rc;
}
/* Write the current in-memory list to a PMA. When the VdbeSorterWrite()
** function flushes the contents of memory to disk, it immediately always
** creates a new list consisting of a single key immediately afterwards.
** So the list is never empty at this point. */
assert( pSorter->list.pList );
rc = vdbeSorterFlushPMA(pSorter);
/* Join all threads */
rc = vdbeSorterJoinAll(pSorter, rc);
vdbeSorterRewindDebug("rewind");
/* Assuming no errors have occurred, set up a merger structure to
** incrementally read and merge all remaining PMAs. */
assert( pSorter->pReader==0 );
if( rc==SQLITE_OK ){
rc = vdbeSorterSetupMerge(pSorter);
*pbEof = 0;
}
vdbeSorterRewindDebug("rewinddone");
return rc;
}
/*
** Advance to the next element in the sorter.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
VdbeSorter *pSorter = pCsr->pSorter;
int rc; /* Return code */
assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) );
if( pSorter->bUsePMA ){
assert( pSorter->pReader==0 || pSorter->pMerger==0 );
assert( pSorter->bUseThreads==0 || pSorter->pReader );
assert( pSorter->bUseThreads==1 || pSorter->pMerger );
#if SQLITE_MAX_WORKER_THREADS>0
if( pSorter->bUseThreads ){
rc = vdbePmaReaderNext(pSorter->pReader);
*pbEof = (pSorter->pReader->pFd==0);
}else
#endif
/*if( !pSorter->bUseThreads )*/ {
assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) );
rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof);
}
}else{
SorterRecord *pFree = pSorter->list.pList;
pSorter->list.pList = pFree->u.pNext;
pFree->u.pNext = 0;
if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree);
*pbEof = !pSorter->list.pList;
rc = SQLITE_OK;
}
return rc;
}
/*
** Return a pointer to a buffer owned by the sorter that contains the
** current key.
*/
static void *vdbeSorterRowkey(
const VdbeSorter *pSorter, /* Sorter object */
int *pnKey /* OUT: Size of current key in bytes */
){
void *pKey;
if( pSorter->bUsePMA ){
PmaReader *pReader;
#if SQLITE_MAX_WORKER_THREADS>0
if( pSorter->bUseThreads ){
pReader = pSorter->pReader;
}else
#endif
/*if( !pSorter->bUseThreads )*/{
pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]];
}
*pnKey = pReader->nKey;
pKey = pReader->aKey;
}else{
*pnKey = pSorter->list.pList->nVal;
pKey = SRVAL(pSorter->list.pList);
}
return pKey;
}
/*
** Copy the current sorter key into the memory cell pOut.
*/
|
| ︙ | ︙ | |||
76069 76070 76071 76072 76073 76074 76075 76076 76077 76078 76079 76080 76081 76082 76083 76084 | return SQLITE_OK; } /* ** Compare the key in memory cell pVal with the key that the sorter cursor ** passed as the first argument currently points to. For the purposes of ** the comparison, ignore the rowid field at the end of each record. ** ** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). ** Otherwise, set *pRes to a negative, zero or positive value if the ** key in pVal is smaller than, equal to or larger than the current sorter ** key. */ SQLITE_PRIVATE int sqlite3VdbeSorterCompare( const VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal, /* Value to compare to current sorter key */ | > > > > > > | > > > > > > > > > > > > > > > > > > > | > | 78043 78044 78045 78046 78047 78048 78049 78050 78051 78052 78053 78054 78055 78056 78057 78058 78059 78060 78061 78062 78063 78064 78065 78066 78067 78068 78069 78070 78071 78072 78073 78074 78075 78076 78077 78078 78079 78080 78081 78082 78083 78084 78085 78086 78087 78088 78089 78090 78091 78092 78093 78094 78095 78096 78097 78098 78099 |
return SQLITE_OK;
}
/*
** Compare the key in memory cell pVal with the key that the sorter cursor
** passed as the first argument currently points to. For the purposes of
** the comparison, ignore the rowid field at the end of each record.
**
** If the sorter cursor key contains any NULL values, consider it to be
** less than pVal. Even if pVal also contains NULL values.
**
** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM).
** Otherwise, set *pRes to a negative, zero or positive value if the
** key in pVal is smaller than, equal to or larger than the current sorter
** key.
**
** This routine forms the core of the OP_SorterCompare opcode, which in
** turn is used to verify uniqueness when constructing a UNIQUE INDEX.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal, /* Value to compare to current sorter key */
int nKeyCol, /* Compare this many columns */
int *pRes /* OUT: Result of comparison */
){
VdbeSorter *pSorter = pCsr->pSorter;
UnpackedRecord *r2 = pSorter->pUnpacked;
KeyInfo *pKeyInfo = pCsr->pKeyInfo;
int i;
void *pKey; int nKey; /* Sorter key to compare pVal with */
if( r2==0 ){
char *p;
r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
assert( pSorter->pUnpacked==(UnpackedRecord*)p );
if( r2==0 ) return SQLITE_NOMEM;
r2->nField = nKeyCol;
}
assert( r2->nField==nKeyCol );
pKey = vdbeSorterRowkey(pSorter, &nKey);
sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2);
for(i=0; i<nKeyCol; i++){
if( r2->aMem[i].flags & MEM_Null ){
*pRes = -1;
return SQLITE_OK;
}
}
*pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2, 0);
return SQLITE_OK;
}
/************** End of vdbesort.c ********************************************/
/************** Begin file journal.c *****************************************/
/*
** 2007 August 22
|
| ︙ | ︙ | |||
80134 80135 80136 80137 80138 80139 80140 80141 80142 80143 80144 80145 80146 80147 |
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
| > | 82134 82135 82136 82137 82138 82139 82140 82141 82142 82143 82144 82145 82146 82147 82148 |
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
dest.iSdst = dest.iSDParm;
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
|
| ︙ | ︙ | |||
80817 80818 80819 80820 80821 80822 80823 |
case TK_AS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
| < < < < < < < < < < < < < < | > | 82818 82819 82820 82821 82822 82823 82824 82825 82826 82827 82828 82829 82830 82831 82832 82833 82834 82835 82836 82837 82838 |
case TK_AS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
if( inReg!=target ){
sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
inReg = target;
}
sqlite3VdbeAddOp2(v, OP_Cast, target,
sqlite3AffinityType(pExpr->u.zToken, 0));
testcase( usedAsColumnCache(pParse, inReg, inReg) );
sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
break;
}
#endif /* SQLITE_OMIT_CAST */
case TK_LT:
case TK_LE:
|
| ︙ | ︙ | |||
86373 86374 86375 86376 86377 86378 86379 |
** auxiliary databases added using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
Table *p = 0;
int i;
| < < | | 88361 88362 88363 88364 88365 88366 88367 88368 88369 88370 88371 88372 88373 88374 88375 88376 88377 88378 88379 88380 88381 88382 |
** auxiliary databases added using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
Table *p = 0;
int i;
assert( zName!=0 );
/* All mutexes are required for schema access. Make sure we hold them. */
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
if( p ) break;
}
return p;
}
/*
** Locate the in-memory structure that describes a particular database
|
| ︙ | ︙ | |||
86465 86466 86467 86468 86469 86470 86471 |
** for duplicate index names is done.) The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
Index *p = 0;
int i;
| < | | 88451 88452 88453 88454 88455 88456 88457 88458 88459 88460 88461 88462 88463 88464 88465 88466 88467 88468 88469 88470 88471 88472 88473 |
** for duplicate index names is done.) The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
Index *p = 0;
int i;
/* All mutexes are required for schema access. Make sure we hold them. */
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
}
return p;
}
/*
** Reclaim the memory used by an index
|
| ︙ | ︙ | |||
86502 86503 86504 86505 86506 86507 86508 |
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
** the index hash table and free all memory structures associated
** with the index.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
Index *pIndex;
| < < | | 88487 88488 88489 88490 88491 88492 88493 88494 88495 88496 88497 88498 88499 88500 88501 88502 88503 88504 88505 |
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
** the index hash table and free all memory structures associated
** with the index.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
Index *pIndex;
Hash *pHash;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pHash = &db->aDb[iDb].pSchema->idxHash;
pIndex = sqlite3HashInsert(pHash, zIdxName, 0);
if( ALWAYS(pIndex) ){
if( pIndex->pTable->pIndex==pIndex ){
pIndex->pTable->pIndex = pIndex->pNext;
}else{
Index *p;
/* Justification of ALWAYS(); The index must be on the list of
** indices. */
|
| ︙ | ︙ | |||
86668 86669 86670 86671 86672 86673 86674 |
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
TESTONLY ( Index *pOld = ) sqlite3HashInsert(
| | | 88651 88652 88653 88654 88655 88656 88657 88658 88659 88660 88661 88662 88663 88664 88665 |
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
TESTONLY ( Index *pOld = ) sqlite3HashInsert(
&pIndex->pSchema->idxHash, zName, 0
);
assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
assert( pOld==pIndex || pOld==0 );
}
freeIndex(db, pIndex);
}
|
| ︙ | ︙ | |||
86711 86712 86713 86714 86715 86716 86717 | assert( db!=0 ); assert( iDb>=0 && iDb<db->nDb ); assert( zTabName ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ pDb = &db->aDb[iDb]; | | < | 88694 88695 88696 88697 88698 88699 88700 88701 88702 88703 88704 88705 88706 88707 88708 | assert( db!=0 ); assert( iDb>=0 && iDb<db->nDb ); assert( zTabName ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ pDb = &db->aDb[iDb]; p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); sqlite3DeleteTable(db, p); db->flags |= SQLITE_InternChanges; } /* ** Given a token, return a string that consists of the text of that ** token. Space to hold the returned string |
| ︙ | ︙ | |||
88034 88035 88036 88037 88038 88039 88040 |
/* Add the table to the in-memory representation of the database.
*/
if( db->init.busy ){
Table *pOld;
Schema *pSchema = p->pSchema;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
| | < | 90016 90017 90018 90019 90020 90021 90022 90023 90024 90025 90026 90027 90028 90029 90030 |
/* Add the table to the in-memory representation of the database.
*/
if( db->init.busy ){
Table *pOld;
Schema *pSchema = p->pSchema;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
if( pOld ){
assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
db->mallocFailed = 1;
return;
}
pParse->pNewTable = 0;
db->flags |= SQLITE_InternChanges;
|
| ︙ | ︙ | |||
88685 88686 88687 88688 88689 88690 88691 | } pFKey->isDeferred = 0; pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, | | | 90666 90667 90668 90669 90670 90671 90672 90673 90674 90675 90676 90677 90678 90679 90680 |
}
pFKey->isDeferred = 0;
pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */
pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */
assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash,
pFKey->zTo, (void *)pFKey
);
if( pNextTo==pFKey ){
db->mallocFailed = 1;
goto fk_end;
}
if( pNextTo ){
assert( pNextTo->pPrevTo==0 );
|
| ︙ | ︙ | |||
88773 88774 88775 88776 88777 88778 88779 |
}else{
tnum = pIndex->tnum;
}
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
| | | 90754 90755 90756 90757 90758 90759 90760 90761 90762 90763 90764 90765 90766 90767 90768 |
}else{
tnum = pIndex->tnum;
}
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
sqlite3KeyInfoRef(pKey), P4_KEYINFO);
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
regRecord = sqlite3GetTempReg(pParse);
|
| ︙ | ︙ | |||
89122 89123 89124 89125 89126 89127 89128 |
}
if( j>=pTab->nCol ){
sqlite3ErrorMsg(pParse, "table %s has no column named %s",
pTab->zName, zColName);
pParse->checkSchema = 1;
goto exit_create_index;
}
| | | 91103 91104 91105 91106 91107 91108 91109 91110 91111 91112 91113 91114 91115 91116 91117 |
}
if( j>=pTab->nCol ){
sqlite3ErrorMsg(pParse, "table %s has no column named %s",
pTab->zName, zColName);
pParse->checkSchema = 1;
goto exit_create_index;
}
assert( j<=0x7fff );
pIndex->aiColumn[i] = (i16)j;
if( pListItem->pExpr ){
int nColl;
assert( pListItem->pExpr->op==TK_COLLATE );
zColl = pListItem->pExpr->u.zToken;
nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl );
|
| ︙ | ︙ | |||
89233 89234 89235 89236 89237 89238 89239 |
/* Link the new Index structure to its table and to the other
** in-memory database structures.
*/
if( db->init.busy ){
Index *p;
assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
| | < | 91214 91215 91216 91217 91218 91219 91220 91221 91222 91223 91224 91225 91226 91227 91228 |
/* Link the new Index structure to its table and to the other
** in-memory database structures.
*/
if( db->init.busy ){
Index *p;
assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
pIndex->zName, pIndex);
if( p ){
assert( p==pIndex ); /* Malloc must have failed */
db->mallocFailed = 1;
goto exit_create_index;
}
db->flags |= SQLITE_InternChanges;
if( pTblName!=0 ){
|
| ︙ | ︙ | |||
90503 90504 90505 90506 90507 90508 90509 |
*/
static CollSeq *findCollSeqEntry(
sqlite3 *db, /* Database connection */
const char *zName, /* Name of the collating sequence */
int create /* Create a new entry if true */
){
CollSeq *pColl;
| < | > | | | 92483 92484 92485 92486 92487 92488 92489 92490 92491 92492 92493 92494 92495 92496 92497 92498 92499 92500 92501 92502 92503 92504 92505 92506 92507 92508 92509 92510 92511 92512 |
*/
static CollSeq *findCollSeqEntry(
sqlite3 *db, /* Database connection */
const char *zName, /* Name of the collating sequence */
int create /* Create a new entry if true */
){
CollSeq *pColl;
pColl = sqlite3HashFind(&db->aCollSeq, zName);
if( 0==pColl && create ){
int nName = sqlite3Strlen30(zName);
pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1);
if( pColl ){
CollSeq *pDel = 0;
pColl[0].zName = (char*)&pColl[3];
pColl[0].enc = SQLITE_UTF8;
pColl[1].zName = (char*)&pColl[3];
pColl[1].enc = SQLITE_UTF16LE;
pColl[2].zName = (char*)&pColl[3];
pColl[2].enc = SQLITE_UTF16BE;
memcpy(pColl[0].zName, zName, nName);
pColl[0].zName[nName] = 0;
pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl);
/* If a malloc() failure occurred in sqlite3HashInsert(), it will
** return the pColl pointer to be deleted (because it wasn't added
** to the hash table).
*/
assert( pDel==0 || pDel==pColl );
if( pDel!=0 ){
|
| ︙ | ︙ | |||
91294 91295 91296 91297 91298 91299 91300 91301 91302 |
/* Unless this is a view, open cursors for the table we are
** deleting from and all its indices. If this is a view, then the
** only effect this statement has is to fire the INSTEAD OF
** triggers.
*/
if( !isView ){
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
&iDataCur, &iIdxCur);
| > | | | > | 93274 93275 93276 93277 93278 93279 93280 93281 93282 93283 93284 93285 93286 93287 93288 93289 93290 93291 93292 93293 93294 93295 93296 93297 93298 93299 93300 93301 |
/* Unless this is a view, open cursors for the table we are
** deleting from and all its indices. If this is a view, then the
** only effect this statement has is to fire the INSTEAD OF
** triggers.
*/
if( !isView ){
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
&iDataCur, &iIdxCur);
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
}
/* Set up a loop over the rowids/primary-keys that were found in the
** where-clause loop above.
*/
if( okOnePass ){
/* Just one row. Hence the top-of-loop is a no-op */
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
assert( !IsVirtual(pTab) );
if( aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
VdbeCoverage(v);
}
}else if( pPk ){
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
|
| ︙ | ︙ | |||
94075 94076 94077 94078 94079 94080 94081 |
** Calling this function with table "t1" as an argument returns a pointer
** to the FKey structure representing the foreign key constraint on table
** "t2". Calling this function with "t2" as the argument would return a
** NULL pointer (as there are no FK constraints for which t2 is the parent
** table).
*/
SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){
| < | | 96057 96058 96059 96060 96061 96062 96063 96064 96065 96066 96067 96068 96069 96070 96071 |
** Calling this function with table "t1" as an argument returns a pointer
** to the FKey structure representing the foreign key constraint on table
** "t2". Calling this function with "t2" as the argument would return a
** NULL pointer (as there are no FK constraints for which t2 is the parent
** table).
*/
SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){
return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName);
}
/*
** The second argument is a Trigger structure allocated by the
** fkActionTrigger() routine. This function deletes the Trigger structure
** and all of its sub-components.
**
|
| ︙ | ︙ | |||
94754 94755 94756 94757 94758 94759 94760 |
/* Remove the FK from the fkeyHash hash table. */
if( !db || db->pnBytesFreed==0 ){
if( pFKey->pPrevTo ){
pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
}else{
void *p = (void *)pFKey->pNextTo;
const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
| | | 96735 96736 96737 96738 96739 96740 96741 96742 96743 96744 96745 96746 96747 96748 96749 |
/* Remove the FK from the fkeyHash hash table. */
if( !db || db->pnBytesFreed==0 ){
if( pFKey->pPrevTo ){
pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
}else{
void *p = (void *)pFKey->pNextTo;
const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p);
}
if( pFKey->pNextTo ){
pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
}
}
/* EV: R-30323-21917 Each foreign key constraint in SQLite is
|
| ︙ | ︙ | |||
96393 96394 96395 96396 96397 96398 96399 96400 96401 96402 96403 96404 96405 96406 96407 96408 96409 96410 96411 96412 96413 96414 96415 96416 96417 |
** or the first index for WITHOUT ROWID tables) if it is non-negative.
** If iBase is negative, then allocate the next available cursor.
**
** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
** pTab->pIndex list.
*/
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
int op, /* OP_OpenRead or OP_OpenWrite */
int iBase, /* Use this for the table cursor, if there is one */
u8 *aToOpen, /* If not NULL: boolean for each table and index */
int *piDataCur, /* Write the database source cursor number here */
int *piIdxCur /* Write the first index cursor number here */
){
int i;
int iDb;
int iDataCur;
Index *pIdx;
Vdbe *v;
assert( op==OP_OpenRead || op==OP_OpenWrite );
if( IsVirtual(pTab) ){
| > > > | | | | 98374 98375 98376 98377 98378 98379 98380 98381 98382 98383 98384 98385 98386 98387 98388 98389 98390 98391 98392 98393 98394 98395 98396 98397 98398 98399 98400 98401 98402 98403 98404 98405 98406 98407 98408 98409 98410 98411 |
** or the first index for WITHOUT ROWID tables) if it is non-negative.
** If iBase is negative, then allocate the next available cursor.
**
** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
** pTab->pIndex list.
**
** If pTab is a virtual table, then this routine is a no-op and the
** *piDataCur and *piIdxCur values are left uninitialized.
*/
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
int op, /* OP_OpenRead or OP_OpenWrite */
int iBase, /* Use this for the table cursor, if there is one */
u8 *aToOpen, /* If not NULL: boolean for each table and index */
int *piDataCur, /* Write the database source cursor number here */
int *piIdxCur /* Write the first index cursor number here */
){
int i;
int iDb;
int iDataCur;
Index *pIdx;
Vdbe *v;
assert( op==OP_OpenRead || op==OP_OpenWrite );
if( IsVirtual(pTab) ){
/* This routine is a no-op for virtual tables. Leave the output
** variables *piDataCur and *piIdxCur uninitialized so that valgrind
** can detect if they are used by mistake in the caller. */
return 0;
}
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
if( iBase<0 ) iBase = pParse->nTab;
iDataCur = iBase++;
|
| ︙ | ︙ | |||
96845 96846 96847 96848 96849 96850 96851 | char **azCols = 0; /* Names of result columns */ int callbackIsInit; /* True if callback data is initialized */ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; if( zSql==0 ) zSql = ""; sqlite3_mutex_enter(db->mutex); | | | 98829 98830 98831 98832 98833 98834 98835 98836 98837 98838 98839 98840 98841 98842 98843 |
char **azCols = 0; /* Names of result columns */
int callbackIsInit; /* True if callback data is initialized */
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
if( zSql==0 ) zSql = "";
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK);
while( rc==SQLITE_OK && zSql[0] ){
int nCol;
char **azVals = 0;
pStmt = 0;
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
|
| ︙ | ︙ | |||
96903 96904 96905 96906 96907 96908 96909 |
if( xCallback(pArg, nCol, azVals, azCols) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
** sqlite3_exec() returns non-zero, then sqlite3_exec() will
** return SQLITE_ABORT. */
rc = SQLITE_ABORT;
sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
| | | 98887 98888 98889 98890 98891 98892 98893 98894 98895 98896 98897 98898 98899 98900 98901 |
if( xCallback(pArg, nCol, azVals, azCols) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
** sqlite3_exec() returns non-zero, then sqlite3_exec() will
** return SQLITE_ABORT. */
rc = SQLITE_ABORT;
sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
sqlite3Error(db, SQLITE_ABORT);
goto exec_out;
}
}
if( rc!=SQLITE_ROW ){
rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
|
| ︙ | ︙ | |||
96933 96934 96935 96936 96937 96938 96939 |
if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
*pzErrMsg = sqlite3Malloc(nErrMsg);
if( *pzErrMsg ){
memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
}else{
rc = SQLITE_NOMEM;
| | | 98917 98918 98919 98920 98921 98922 98923 98924 98925 98926 98927 98928 98929 98930 98931 |
if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
*pzErrMsg = sqlite3Malloc(nErrMsg);
if( *pzErrMsg ){
memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
}else{
rc = SQLITE_NOMEM;
sqlite3Error(db, SQLITE_NOMEM);
}
}else if( pzErrMsg ){
*pzErrMsg = 0;
}
assert( (rc&db->errMask)==rc );
sqlite3_mutex_leave(db->mutex);
|
| ︙ | ︙ | |||
98186 98187 98188 98189 98190 98191 98192 |
}else{
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
wsdAutoext.aExt[i];
}
sqlite3_mutex_leave(mutex);
zErrmsg = 0;
if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
| | | 100170 100171 100172 100173 100174 100175 100176 100177 100178 100179 100180 100181 100182 100183 100184 |
}else{
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
wsdAutoext.aExt[i];
}
sqlite3_mutex_leave(mutex);
zErrmsg = 0;
if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
sqlite3ErrorWithMsg(db, rc,
"automatic extension loading failed: %s", zErrmsg);
go = 0;
}
sqlite3_free(zErrmsg);
}
}
|
| ︙ | ︙ | |||
98258 98259 98260 98261 98262 98263 98264 | #define PragTyp_SHRINK_MEMORY 26 #define PragTyp_SOFT_HEAP_LIMIT 27 #define PragTyp_STATS 28 #define PragTyp_SYNCHRONOUS 29 #define PragTyp_TABLE_INFO 30 #define PragTyp_TEMP_STORE 31 #define PragTyp_TEMP_STORE_DIRECTORY 32 | > | | | | | | | | | 100242 100243 100244 100245 100246 100247 100248 100249 100250 100251 100252 100253 100254 100255 100256 100257 100258 100259 100260 100261 100262 100263 100264 |
#define PragTyp_SHRINK_MEMORY 26
#define PragTyp_SOFT_HEAP_LIMIT 27
#define PragTyp_STATS 28
#define PragTyp_SYNCHRONOUS 29
#define PragTyp_TABLE_INFO 30
#define PragTyp_TEMP_STORE 31
#define PragTyp_TEMP_STORE_DIRECTORY 32
#define PragTyp_THREADS 33
#define PragTyp_WAL_AUTOCHECKPOINT 34
#define PragTyp_WAL_CHECKPOINT 35
#define PragTyp_ACTIVATE_EXTENSIONS 36
#define PragTyp_HEXKEY 37
#define PragTyp_KEY 38
#define PragTyp_REKEY 39
#define PragTyp_LOCK_STATUS 40
#define PragTyp_PARSER_TRACE 41
#define PragFlag_NeedSchema 0x01
static const struct sPragmaNames {
const char *const zName; /* Name of pragma */
u8 ePragTyp; /* PragTyp_XXX value */
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
u32 iArg; /* Extra argument */
} aPragmaNames[] = {
|
| ︙ | ︙ | |||
98615 98616 98617 98618 98619 98620 98621 98622 98623 98624 98625 98626 98627 98628 |
/* ePragFlag: */ 0,
/* iArg: */ 0 },
{ /* zName: */ "temp_store_directory",
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{ /* zName: */ "user_version",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
| > > > > | 100600 100601 100602 100603 100604 100605 100606 100607 100608 100609 100610 100611 100612 100613 100614 100615 100616 100617 |
/* ePragFlag: */ 0,
/* iArg: */ 0 },
{ /* zName: */ "temp_store_directory",
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
{ /* zName: */ "threads",
/* ePragTyp: */ PragTyp_THREADS,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{ /* zName: */ "user_version",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
| ︙ | ︙ | |||
98662 98663 98664 98665 98666 98667 98668 |
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
| | | 100651 100652 100653 100654 100655 100656 100657 100658 100659 100660 100661 100662 100663 100664 100665 |
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 57 on by default, 70 total. */
/* End of the automatically generated pragma table.
***************************************************************************/
/*
** Interpret the given string as a safety level. Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
** unrecognized string argument. The FULL option is disallowed
|
| ︙ | ︙ | |||
100469 100470 100471 100472 100473 100474 100475 100476 100477 100478 100479 100480 100481 100482 |
sqlite3_int64 N;
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
sqlite3_soft_heap_limit64(N);
}
returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
break;
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
| > > > > > > > > > > > > > > > > > > > > | 102458 102459 102460 102461 102462 102463 102464 102465 102466 102467 102468 102469 102470 102471 102472 102473 102474 102475 102476 102477 102478 102479 102480 102481 102482 102483 102484 102485 102486 102487 102488 102489 102490 102491 |
sqlite3_int64 N;
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
sqlite3_soft_heap_limit64(N);
}
returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
break;
}
/*
** PRAGMA threads
** PRAGMA threads = N
**
** Configure the maximum number of worker threads. Return the new
** maximum, which might be less than requested.
*/
case PragTyp_THREADS: {
sqlite3_int64 N;
if( zRight
&& sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
&& N>=0
){
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
}
returnSingleInt(pParse, "threads",
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
|
| ︙ | ︙ | |||
101151 101152 101153 101154 101155 101156 101157 |
for(i=0; i<db->nDb; i++) {
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
const char *zDb = db->aDb[i].zName;
| | | | 103160 103161 103162 103163 103164 103165 103166 103167 103168 103169 103170 103171 103172 103173 103174 103175 103176 103177 103178 103179 103180 103181 103182 103183 103184 103185 103186 103187 103188 103189 103190 103191 |
for(i=0; i<db->nDb; i++) {
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
const char *zDb = db->aDb[i].zName;
sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
testcase( db->flags & SQLITE_ReadUncommitted );
goto end_prepare;
}
}
}
sqlite3VtabUnlockList(db);
pParse->db = db;
pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
testcase( nBytes==mxLen );
testcase( nBytes==mxLen+1 );
if( nBytes>mxLen ){
sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
goto end_prepare;
}
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
sqlite3DbFree(db, zSqlCopy);
|
| ︙ | ︙ | |||
101235 101236 101237 101238 101239 101240 101241 |
sqlite3VdbeFinalize(pParse->pVdbe);
assert(!(*ppStmt));
}else{
*ppStmt = (sqlite3_stmt*)pParse->pVdbe;
}
if( zErrMsg ){
| | | | 103244 103245 103246 103247 103248 103249 103250 103251 103252 103253 103254 103255 103256 103257 103258 103259 103260 103261 |
sqlite3VdbeFinalize(pParse->pVdbe);
assert(!(*ppStmt));
}else{
*ppStmt = (sqlite3_stmt*)pParse->pVdbe;
}
if( zErrMsg ){
sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
sqlite3DbFree(db, zErrMsg);
}else{
sqlite3Error(db, rc);
}
/* Delete any TriggerPrg structures allocated while parsing this statement. */
while( pParse->pTriggerPrg ){
TriggerPrg *pT = pParse->pTriggerPrg;
pParse->pTriggerPrg = pT->pNext;
sqlite3DbFree(db, pT);
|
| ︙ | ︙ | |||
101900 101901 101902 101903 101904 101905 101906 | Parse *pParse, /* Parsing context */ ExprList *pList, /* Form the KeyInfo object from this ExprList */ int iStart, /* Begin with this column of pList */ int nExtra /* Add this many extra columns to the end */ ); /* | | | | > > | > | > > | < | | > > > > > > | < > | > | > > | > > | | > | > > > > | | 103909 103910 103911 103912 103913 103914 103915 103916 103917 103918 103919 103920 103921 103922 103923 103924 103925 103926 103927 103928 103929 103930 103931 103932 103933 103934 103935 103936 103937 103938 103939 103940 103941 103942 103943 103944 103945 103946 103947 103948 103949 103950 103951 103952 103953 103954 103955 103956 103957 103958 103959 103960 103961 103962 103963 103964 103965 103966 103967 103968 103969 103970 103971 103972 103973 103974 103975 103976 103977 103978 103979 103980 |
Parse *pParse, /* Parsing context */
ExprList *pList, /* Form the KeyInfo object from this ExprList */
int iStart, /* Begin with this column of pList */
int nExtra /* Add this many extra columns to the end */
);
/*
** Generate code that will push the record in registers regData
** through regData+nData-1 onto the sorter.
*/
static void pushOntoSorter(
Parse *pParse, /* Parser context */
SortCtx *pSort, /* Information about the ORDER BY clause */
Select *pSelect, /* The whole SELECT statement */
int regData, /* First register holding data to be sorted */
int nData, /* Number of elements in the data array */
int nPrefixReg /* No. of reg prior to regData available for use */
){
Vdbe *v = pParse->pVdbe; /* Stmt under construction */
int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */
int nBase = nExpr + bSeq + nData; /* Fields in sorter record */
int regBase; /* Regs for sorter record */
int regRecord = ++pParse->nMem; /* Assembled sorter record */
int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
int op; /* Opcode to add sorter record to sorter */
assert( bSeq==0 || bSeq==1 );
if( nPrefixReg ){
assert( nPrefixReg==nExpr+bSeq );
regBase = regData - nExpr - bSeq;
}else{
regBase = pParse->nMem + 1;
pParse->nMem += nBase;
}
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
if( bSeq ){
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
}
if( nPrefixReg==0 ){
sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+bSeq, nData);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
if( nOBSat>0 ){
int regPrevKey; /* The first nOBSat columns of the previous row */
int addrFirst; /* Address of the OP_IfNot opcode */
int addrJmp; /* Address of the OP_Jump opcode */
VdbeOp *pOp; /* Opcode that opens the sorter */
int nKey; /* Number of sorting key columns, including OP_Sequence */
KeyInfo *pKI; /* Original KeyInfo on the sorter table */
regPrevKey = pParse->nMem+1;
pParse->nMem += pSort->nOBSat;
nKey = nExpr - pSort->nOBSat + bSeq;
if( bSeq ){
addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr);
}else{
addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor);
}
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
if( pParse->db->mallocFailed ) return;
pOp->p2 = nKey + nData;
pKI = pOp->p4.pKeyInfo;
memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1);
addrJmp = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
|
| ︙ | ︙ | |||
102071 102072 102073 102074 102075 102076 102077 102078 102079 102080 102081 102082 102083 102084 102085 102086 102087 102088 102089 102090 102091 102092 102093 102094 102095 102096 102097 102098 102099 |
Vdbe *v = pParse->pVdbe;
int i;
int hasDistinct; /* True if the DISTINCT keyword is present */
int regResult; /* Start of memory holding result set */
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
assert( v );
assert( pEList!=0 );
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pSort && pSort->pOrderBy==0 ) pSort = 0;
if( pSort==0 && !hasDistinct ){
assert( iContinue!=0 );
codeOffset(v, p->iOffset, iContinue);
}
/* Pull the requested columns.
*/
nResultCol = pEList->nExpr;
if( pDest->iSdst==0 ){
pDest->iSdst = pParse->nMem+1;
pParse->nMem += nResultCol;
}else if( pDest->iSdst+nResultCol > pParse->nMem ){
/* This is an error condition that can result, for example, when a SELECT
** on the right-hand side of an INSERT contains more result columns than
** there are columns in the table on the left. The error will be caught
** and reported later. But we need to make sure enough memory is allocated
| > > > > > > | 104100 104101 104102 104103 104104 104105 104106 104107 104108 104109 104110 104111 104112 104113 104114 104115 104116 104117 104118 104119 104120 104121 104122 104123 104124 104125 104126 104127 104128 104129 104130 104131 104132 104133 104134 |
Vdbe *v = pParse->pVdbe;
int i;
int hasDistinct; /* True if the DISTINCT keyword is present */
int regResult; /* Start of memory holding result set */
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
int nPrefixReg = 0; /* Number of extra registers before regResult */
assert( v );
assert( pEList!=0 );
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pSort && pSort->pOrderBy==0 ) pSort = 0;
if( pSort==0 && !hasDistinct ){
assert( iContinue!=0 );
codeOffset(v, p->iOffset, iContinue);
}
/* Pull the requested columns.
*/
nResultCol = pEList->nExpr;
if( pDest->iSdst==0 ){
if( pSort ){
nPrefixReg = pSort->pOrderBy->nExpr;
if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++;
pParse->nMem += nPrefixReg;
}
pDest->iSdst = pParse->nMem+1;
pParse->nMem += nResultCol;
}else if( pDest->iSdst+nResultCol > pParse->nMem ){
/* This is an error condition that can result, for example, when a SELECT
** on the right-hand side of an INSERT contains more result columns than
** there are columns in the table on the left. The error will be caught
** and reported later. But we need to make sure enough memory is allocated
|
| ︙ | ︙ | |||
102202 102203 102204 102205 102206 102207 102208 |
/* Store the result as data using a unique key.
*/
case SRT_Fifo:
case SRT_DistFifo:
case SRT_Table:
case SRT_EphemTab: {
| | | | | | | 104237 104238 104239 104240 104241 104242 104243 104244 104245 104246 104247 104248 104249 104250 104251 104252 104253 104254 104255 104256 104257 104258 104259 104260 104261 104262 104263 104264 104265 104266 104267 104268 104269 104270 104271 104272 104273 104274 104275 104276 104277 104278 104279 104280 104281 104282 104283 104284 104285 104286 104287 104288 104289 104290 104291 104292 104293 104294 104295 |
/* Store the result as data using a unique key.
*/
case SRT_Fifo:
case SRT_DistFifo:
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
#ifndef SQLITE_OMIT_CTE
if( eDest==SRT_DistFifo ){
/* If the destination is DistFifo, then cursor (iParm+1) is open
** on an ephemeral index. If the current row is already present
** in the index, do not write it to the output. If not, add the
** current row to the index and proceed with writing it to the
** output table as well. */
int addr = sqlite3VdbeCurrentAddr(v) + 4;
sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
assert( pSort==0 );
}
#endif
if( pSort ){
pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg);
}else{
int r2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3ReleaseTempReg(pParse, r2);
}
sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
** then there should be a single item on the stack. Write this
** item into the set table with bogus data.
*/
case SRT_Set: {
assert( nResultCol==1 );
pDest->affSdst =
sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
if( pSort ){
/* At first glance you would think we could optimize out the
** ORDER BY in this case since the order of entries in the set
** does not matter. But there might be a LIMIT clause, in which
** case the order does matter */
pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
}
|
| ︙ | ︙ | |||
102272 102273 102274 102275 102276 102277 102278 |
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
assert( nResultCol==1 );
if( pSort ){
| | | < < | < | 104307 104308 104309 104310 104311 104312 104313 104314 104315 104316 104317 104318 104319 104320 104321 104322 104323 104324 104325 104326 104327 104328 104329 104330 104331 104332 104333 104334 104335 |
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
assert( nResultCol==1 );
if( pSort ){
pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
}else{
assert( regResult==iParm );
/* The LIMIT clause will jump out of the loop for us */
}
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
case SRT_Coroutine: /* Send data to a co-routine */
case SRT_Output: { /* Return the results */
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pSort ){
pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
}
break;
|
| ︙ | ︙ | |||
102569 102570 102571 102572 102573 102574 102575 |
){
Vdbe *v = pParse->pVdbe; /* The prepared statement */
int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
int addr;
int addrOnce = 0;
int iTab;
| < > > > > > > > > < < < < > > > > | > > > | < | > < > > > > > | > > | 104601 104602 104603 104604 104605 104606 104607 104608 104609 104610 104611 104612 104613 104614 104615 104616 104617 104618 104619 104620 104621 104622 104623 104624 104625 104626 104627 104628 104629 104630 104631 104632 104633 104634 104635 104636 104637 104638 104639 104640 104641 104642 104643 104644 104645 104646 104647 104648 104649 104650 104651 104652 104653 104654 104655 104656 104657 104658 104659 104660 104661 104662 104663 104664 104665 104666 104667 104668 104669 104670 |
){
Vdbe *v = pParse->pVdbe; /* The prepared statement */
int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
int addr;
int addrOnce = 0;
int iTab;
ExprList *pOrderBy = pSort->pOrderBy;
int eDest = pDest->eDest;
int iParm = pDest->iSDParm;
int regRow;
int regRowid;
int nKey;
int iSortTab; /* Sorter cursor to read from */
int nSortData; /* Trailing values to read from sorter */
u8 p5; /* p5 parameter for 1st OP_Column */
int i;
int bSeq; /* True if sorter record includes seq. no. */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
struct ExprList_item *aOutEx = p->pEList->a;
#endif
if( pSort->labelBkOut ){
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
}
iTab = pSort->iECursor;
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
regRowid = 0;
regRow = pDest->iSdst;
nSortData = nColumn;
}else{
regRowid = sqlite3GetTempReg(pParse);
regRow = sqlite3GetTempReg(pParse);
nSortData = 1;
}
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
int regSortOut = ++pParse->nMem;
iSortTab = pParse->nTab++;
if( pSort->labelBkOut ){
addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
p5 = OPFLAG_CLEARCACHE;
bSeq = 0;
}else{
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
iSortTab = iTab;
p5 = 0;
bSeq = 1;
}
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
if( i==0 ) sqlite3VdbeChangeP5(v, p5);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
switch( eDest ){
case SRT_Table:
case SRT_EphemTab: {
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
|
| ︙ | ︙ | |||
102637 102638 102639 102640 102641 102642 102643 |
assert( nColumn==1 );
sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
/* The LIMIT clause will terminate the loop for us */
break;
}
#endif
default: {
| < < < < < < < < > | | | | 104685 104686 104687 104688 104689 104690 104691 104692 104693 104694 104695 104696 104697 104698 104699 104700 104701 104702 104703 104704 104705 104706 104707 104708 104709 104710 104711 104712 104713 104714 |
assert( nColumn==1 );
sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
/* The LIMIT clause will terminate the loop for us */
break;
}
#endif
default: {
assert( eDest==SRT_Output || eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
testcase( eDest==SRT_Coroutine );
if( eDest==SRT_Output ){
sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
}else{
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}
break;
}
}
if( regRowid ){
sqlite3ReleaseTempReg(pParse, regRow);
sqlite3ReleaseTempReg(pParse, regRowid);
}
/* The bottom of the loop
*/
sqlite3VdbeResolveLabel(v, addrContinue);
if( pSort->sortFlags & SORTFLAG_UseSorter ){
sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v);
}else{
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v);
|
| ︙ | ︙ | |||
106200 106201 106202 106203 106204 106205 106206 |
*/
if( sSort.pOrderBy ){
KeyInfo *pKeyInfo;
pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0);
sSort.iECursor = pParse->nTab++;
sSort.addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
| | | > | 108241 108242 108243 108244 108245 108246 108247 108248 108249 108250 108251 108252 108253 108254 108255 108256 108257 |
*/
if( sSort.pOrderBy ){
KeyInfo *pKeyInfo;
pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0);
sSort.iECursor = pParse->nTab++;
sSort.addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0,
(char*)pKeyInfo, P4_KEYINFO
);
}else{
sSort.addrSortIndex = -1;
}
/* If the output is destined for a temporary table, open that table.
*/
if( pDest->eDest==SRT_EphemTab ){
|
| ︙ | ︙ | |||
106332 106333 106334 106335 106336 106337 106338 |
** SELECT statement.
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
sAggInfo.mnReg = pParse->nMem+1;
| | | 108374 108375 108376 108377 108378 108379 108380 108381 108382 108383 108384 108385 108386 108387 108388 |
** SELECT statement.
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
if( pHaving ){
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
|
| ︙ | ︙ | |||
106425 106426 106427 106428 106429 106430 106431 |
explainTempTable(pParse,
(sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
"DISTINCT" : "GROUP BY");
groupBySort = 1;
nGroupBy = pGroupBy->nExpr;
| | | < | | 108467 108468 108469 108470 108471 108472 108473 108474 108475 108476 108477 108478 108479 108480 108481 108482 108483 108484 108485 108486 108487 108488 108489 108490 108491 108492 |
explainTempTable(pParse,
(sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
"DISTINCT" : "GROUP BY");
groupBySort = 1;
nGroupBy = pGroupBy->nExpr;
nCol = nGroupBy;
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
if( sAggInfo.aCol[i].iSorterColumn>=j ){
nCol++;
j++;
}
}
regBase = sqlite3GetTempRange(pParse, nCol);
sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn>=j ){
int r1 = j + regBase;
int r2;
r2 = sqlite3ExprCodeGetColumn(pParse,
|
| ︙ | ︙ | |||
107234 107235 107236 107237 107238 107239 107240 |
/* Check that the trigger name is not reserved and that no trigger of the
** specified name exists */
zName = sqlite3NameFromToken(db, pName);
if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto trigger_cleanup;
}
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
| | < | 109275 109276 109277 109278 109279 109280 109281 109282 109283 109284 109285 109286 109287 109288 109289 |
/* Check that the trigger name is not reserved and that no trigger of the
** specified name exists */
zName = sqlite3NameFromToken(db, pName);
if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto trigger_cleanup;
}
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
}else{
assert( !db->init.busy );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto trigger_cleanup;
|
| ︙ | ︙ | |||
107378 107379 107380 107381 107382 107383 107384 |
sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName));
}
if( db->init.busy ){
Trigger *pLink = pTrig;
Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
| | < | | 109418 109419 109420 109421 109422 109423 109424 109425 109426 109427 109428 109429 109430 109431 109432 109433 109434 109435 109436 109437 |
sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName));
}
if( db->init.busy ){
Trigger *pLink = pTrig;
Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pTrig = sqlite3HashInsert(pHash, zName, pTrig);
if( pTrig ){
db->mallocFailed = 1;
}else if( pLink->pSchema==pLink->pTabSchema ){
Table *pTab;
pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
assert( pTab!=0 );
pLink->pNext = pTab->pTrigger;
pTab->pTrigger = pLink;
}
}
triggerfinish_cleanup:
|
| ︙ | ︙ | |||
107543 107544 107545 107546 107547 107548 107549 |
** instead of the trigger name.
**/
SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
Trigger *pTrigger = 0;
int i;
const char *zDb;
const char *zName;
| < < | | 109582 109583 109584 109585 109586 109587 109588 109589 109590 109591 109592 109593 109594 109595 109596 109597 109598 109599 109600 109601 109602 109603 109604 109605 109606 109607 109608 109609 109610 109611 |
** instead of the trigger name.
**/
SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
Trigger *pTrigger = 0;
int i;
const char *zDb;
const char *zName;
sqlite3 *db = pParse->db;
if( db->mallocFailed ) goto drop_trigger_cleanup;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto drop_trigger_cleanup;
}
assert( pName->nSrc==1 );
zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
}
if( !pTrigger ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
}else{
sqlite3CodeVerifyNamedSchema(pParse, zDb);
|
| ︙ | ︙ | |||
107583 107584 107585 107586 107587 107588 107589 |
}
/*
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(Trigger *pTrigger){
| < | | 109620 109621 109622 109623 109624 109625 109626 109627 109628 109629 109630 109631 109632 109633 109634 |
}
/*
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(Trigger *pTrigger){
return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table);
}
/*
** Drop a trigger given a pointer to that trigger.
*/
SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
|
| ︙ | ︙ | |||
107656 107657 107658 107659 107660 107661 107662 |
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
Trigger *pTrigger;
Hash *pHash;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pHash = &(db->aDb[iDb].pSchema->trigHash);
| | | 109692 109693 109694 109695 109696 109697 109698 109699 109700 109701 109702 109703 109704 109705 109706 |
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
Trigger *pTrigger;
Hash *pHash;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pHash = &(db->aDb[iDb].pSchema->trigHash);
pTrigger = sqlite3HashInsert(pHash, zName, 0);
if( ALWAYS(pTrigger) ){
if( pTrigger->pSchema==pTrigger->pTabSchema ){
Table *pTab = tableOfTrigger(pTrigger);
Trigger **pp;
for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
*pp = (*pp)->pNext;
}
|
| ︙ | ︙ | |||
109369 109370 109371 109372 109373 109374 109375 |
void (*xDestroy)(void *) /* Module destructor function */
){
int rc = SQLITE_OK;
int nName;
sqlite3_mutex_enter(db->mutex);
nName = sqlite3Strlen30(zName);
| | | | 111405 111406 111407 111408 111409 111410 111411 111412 111413 111414 111415 111416 111417 111418 111419 111420 111421 111422 111423 111424 111425 111426 111427 111428 111429 111430 111431 111432 |
void (*xDestroy)(void *) /* Module destructor function */
){
int rc = SQLITE_OK;
int nName;
sqlite3_mutex_enter(db->mutex);
nName = sqlite3Strlen30(zName);
if( sqlite3HashFind(&db->aModule, zName) ){
rc = SQLITE_MISUSE_BKPT;
}else{
Module *pMod;
pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
if( pMod ){
Module *pDel;
char *zCopy = (char *)(&pMod[1]);
memcpy(zCopy, zName, nName+1);
pMod->zName = zCopy;
pMod->pModule = pModule;
pMod->pAux = pAux;
pMod->xDestroy = xDestroy;
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
assert( pDel==0 || pDel==pMod );
if( pDel ){
db->mallocFailed = 1;
sqlite3DbFree(db, pDel);
}
}
}
|
| ︙ | ︙ | |||
109751 109752 109753 109754 109755 109756 109757 |
** the first time the virtual table is used in an SQL statement. This
** allows a schema that contains virtual tables to be loaded before
** the required virtual table implementations are registered. */
else {
Table *pOld;
Schema *pSchema = pTab->pSchema;
const char *zName = pTab->zName;
| < | | 111787 111788 111789 111790 111791 111792 111793 111794 111795 111796 111797 111798 111799 111800 111801 111802 |
** the first time the virtual table is used in an SQL statement. This
** allows a schema that contains virtual tables to be loaded before
** the required virtual table implementations are registered. */
else {
Table *pOld;
Schema *pSchema = pTab->pSchema;
const char *zName = pTab->zName;
assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
if( pOld ){
db->mallocFailed = 1;
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
return;
}
pParse->pNewTable = 0;
}
|
| ︙ | ︙ | |||
109919 109920 109921 109922 109923 109924 109925 |
assert( pTab );
if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
return SQLITE_OK;
}
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
| | | 111954 111955 111956 111957 111958 111959 111960 111961 111962 111963 111964 111965 111966 111967 111968 |
assert( pTab );
if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
return SQLITE_OK;
}
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
if( !pMod ){
const char *zModule = pTab->azModuleArg[0];
sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
rc = SQLITE_ERROR;
}else{
char *zErr = 0;
|
| ︙ | ︙ | |||
109987 109988 109989 109990 109991 109992 109993 | const char *zMod; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); /* Locate the required virtual table module */ zMod = pTab->azModuleArg[0]; | | | 112022 112023 112024 112025 112026 112027 112028 112029 112030 112031 112032 112033 112034 112035 112036 |
const char *zMod;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
/* If the module has been registered and includes a Create method,
** invoke it now. If the module has not been registered, return an
** error. Otherwise, do nothing.
*/
if( !pMod ){
*pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
|
| ︙ | ︙ | |||
110026 110027 110028 110029 110030 110031 110032 |
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
sqlite3_mutex_enter(db->mutex);
if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
| | | 112061 112062 112063 112064 112065 112066 112067 112068 112069 112070 112071 112072 112073 112074 112075 |
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
sqlite3_mutex_enter(db->mutex);
if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
sqlite3Error(db, SQLITE_MISUSE);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT;
}
assert( (pTab->tabFlags & TF_Virtual)!=0 );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
|
| ︙ | ︙ | |||
110054 110055 110056 110057 110058 110059 110060 |
pTab->aCol = pParse->pNewTable->aCol;
pTab->nCol = pParse->pNewTable->nCol;
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
db->pVtabCtx->pTab = 0;
}else{
| | | 112089 112090 112091 112092 112093 112094 112095 112096 112097 112098 112099 112100 112101 112102 112103 |
pTab->aCol = pParse->pNewTable->aCol;
pTab->nCol = pParse->pNewTable->nCol;
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
db->pVtabCtx->pTab = 0;
}else{
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
rc = SQLITE_ERROR;
}
pParse->declareVtab = 0;
if( pParse->pVdbe ){
sqlite3VdbeFinalize(pParse->pVdbe);
|
| ︙ | ︙ | |||
110415 110416 110417 110418 110419 110420 110421 |
}
default:
rc = SQLITE_MISUSE_BKPT;
break;
}
va_end(ap);
| | | 112450 112451 112452 112453 112454 112455 112456 112457 112458 112459 112460 112461 112462 112463 112464 |
}
default:
rc = SQLITE_MISUSE_BKPT;
break;
}
va_end(ap);
if( rc!=SQLITE_OK ) sqlite3Error(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/************** End of vtab.c ************************************************/
|
| ︙ | ︙ | |||
113081 113082 113083 113084 113085 113086 113087 113088 113089 113090 113091 113092 113093 113094 |
** less than the upper bound of the range query. Where the upper bound
** is either ($P) or ($P:$U). Again, even if $U is available, both values
** of iUpper are requested of whereKeyStats() and the smaller used.
*/
tRowcnt iLower;
tRowcnt iUpper;
if( nEq==p->nKeyCol ){
aff = SQLITE_AFF_INTEGER;
}else{
aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
}
/* Determine iLower and iUpper using ($P) only. */
if( nEq==0 ){
| > > > > | 115116 115117 115118 115119 115120 115121 115122 115123 115124 115125 115126 115127 115128 115129 115130 115131 115132 115133 |
** less than the upper bound of the range query. Where the upper bound
** is either ($P) or ($P:$U). Again, even if $U is available, both values
** of iUpper are requested of whereKeyStats() and the smaller used.
*/
tRowcnt iLower;
tRowcnt iUpper;
if( pRec ){
testcase( pRec->nField!=pBuilder->nRecValid );
pRec->nField = pBuilder->nRecValid;
}
if( nEq==p->nKeyCol ){
aff = SQLITE_AFF_INTEGER;
}else{
aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
}
/* Determine iLower and iUpper using ($P) only. */
if( nEq==0 ){
|
| ︙ | ︙ | |||
113110 113111 113112 113113 113114 113115 113116 113117 113118 113119 113120 113121 113122 113123 113124 113125 113126 113127 113128 113129 113130 113131 113132 113133 113134 113135 113136 113137 113138 113139 113140 113141 113142 113143 113144 |
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
whereKeyStats(pParse, p, pRec, 0, a);
iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
if( iNew>iLower ) iLower = iNew;
nOut--;
}
}
/* If possible, improve on the iUpper estimate using ($P:$U). */
if( pUpper ){
int bOk; /* True if value is extracted from pExpr */
Expr *pExpr = pUpper->pExpr->pRight;
assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
whereKeyStats(pParse, p, pRec, 1, a);
iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
if( iNew<iUpper ) iUpper = iNew;
nOut--;
}
}
pBuilder->pRec = pRec;
if( rc==SQLITE_OK ){
if( iUpper>iLower ){
nNew = sqlite3LogEst(iUpper - iLower);
}else{
nNew = 10; assert( 10==sqlite3LogEst(2) );
}
if( nNew<nOut ){
nOut = nNew;
}
| > > < | < < > > > > > > > | 115149 115150 115151 115152 115153 115154 115155 115156 115157 115158 115159 115160 115161 115162 115163 115164 115165 115166 115167 115168 115169 115170 115171 115172 115173 115174 115175 115176 115177 115178 115179 115180 115181 115182 115183 115184 115185 115186 115187 115188 115189 115190 115191 115192 115193 115194 115195 115196 115197 115198 115199 115200 115201 115202 115203 115204 115205 115206 115207 115208 115209 115210 115211 115212 115213 115214 115215 115216 115217 115218 115219 115220 115221 115222 115223 115224 115225 115226 |
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
whereKeyStats(pParse, p, pRec, 0, a);
iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
if( iNew>iLower ) iLower = iNew;
nOut--;
pLower = 0;
}
}
/* If possible, improve on the iUpper estimate using ($P:$U). */
if( pUpper ){
int bOk; /* True if value is extracted from pExpr */
Expr *pExpr = pUpper->pExpr->pRight;
assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
whereKeyStats(pParse, p, pRec, 1, a);
iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
if( iNew<iUpper ) iUpper = iNew;
nOut--;
pUpper = 0;
}
}
pBuilder->pRec = pRec;
if( rc==SQLITE_OK ){
if( iUpper>iLower ){
nNew = sqlite3LogEst(iUpper - iLower);
}else{
nNew = 10; assert( 10==sqlite3LogEst(2) );
}
if( nNew<nOut ){
nOut = nNew;
}
WHERETRACE(0x10, ("STAT4 range scan: %u..%u est=%d\n",
(u32)iLower, (u32)iUpper, nOut));
}
}else{
int bDone = 0;
rc = whereRangeSkipScanEst(pParse, pLower, pUpper, pLoop, &bDone);
if( bDone ) return rc;
}
}
#else
UNUSED_PARAMETER(pParse);
UNUSED_PARAMETER(pBuilder);
assert( pLower || pUpper );
#endif
assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 );
nNew = whereRangeAdjust(pLower, nOut);
nNew = whereRangeAdjust(pUpper, nNew);
/* TUNING: If there is both an upper and lower limit, assume the range is
** reduced by an additional 75%. This means that, by default, an open-ended
** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
** match 1/64 of the index. */
if( pLower && pUpper ) nNew -= 20;
nOut -= (pLower!=0) + (pUpper!=0);
if( nNew<10 ) nNew = 10;
if( nNew<nOut ) nOut = nNew;
#if defined(WHERETRACE_ENABLED)
if( pLoop->nOut>nOut ){
WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n",
pLoop->nOut, nOut));
}
#endif
pLoop->nOut = (LogEst)nOut;
return rc;
}
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
|
| ︙ | ︙ | |||
113280 113281 113282 113283 113284 113285 113286 |
nRowEst += nEst;
pBuilder->nRecValid = nRecValid;
}
if( rc==SQLITE_OK ){
if( nRowEst > nRow0 ) nRowEst = nRow0;
*pnRow = nRowEst;
| | | 115325 115326 115327 115328 115329 115330 115331 115332 115333 115334 115335 115336 115337 115338 115339 |
nRowEst += nEst;
pBuilder->nRecValid = nRecValid;
}
if( rc==SQLITE_OK ){
if( nRowEst > nRow0 ) nRowEst = nRow0;
*pnRow = nRowEst;
WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst));
}
assert( pBuilder->nRecValid==nRecValid );
return rc;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
|
| ︙ | ︙ | |||
114671 114672 114673 114674 114675 114676 114677 |
struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pTab;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
| | | > > > | > | 116716 116717 116718 116719 116720 116721 116722 116723 116724 116725 116726 116727 116728 116729 116730 116731 116732 116733 116734 116735 116736 116737 116738 116739 116740 116741 116742 116743 116744 116745 116746 116747 116748 116749 116750 116751 116752 116753 116754 116755 116756 |
struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pTab;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
const char *zName;
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
int i = sqlite3Strlen30(zName) - 1;
while( zName[i]!='_' ) i--;
zName += i;
}
sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq);
}else{
sqlite3DebugPrintf("%20s","");
}
}else{
char *z;
if( p->u.vtab.idxStr ){
z = sqlite3_mprintf("(%d,\"%s\",%x)",
p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask);
}else{
z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
}
sqlite3DebugPrintf(" %-19s", z);
sqlite3_free(z);
}
if( p->wsFlags & WHERE_SKIPSCAN ){
sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
}else{
sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
}
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
/* If the 0x100 bit of wheretracing is set, then show all of the constraint
** expressions in the WhereLoop.aLTerm[] array.
*/
if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ /* WHERETRACE 0x100 */
int i;
|
| ︙ | ︙ | |||
115206 115207 115208 115209 115210 115211 115212 | ** The magic number 18 is selected on the basis that scanning 17 rows ** is almost always quicker than an index seek (even though if the index ** contains fewer than 2^17 rows we assume otherwise in other parts of ** the code). And, even if it is not, it should not be too much slower. ** On the other hand, the extra seeks could end up being significantly ** more expensive. */ assert( 42==sqlite3LogEst(18) ); | < | > > > > > > > > | 117255 117256 117257 117258 117259 117260 117261 117262 117263 117264 117265 117266 117267 117268 117269 117270 117271 117272 117273 117274 117275 117276 117277 117278 117279 117280 117281 117282 117283 117284 117285 117286 117287 117288 117289 117290 |
** The magic number 18 is selected on the basis that scanning 17 rows
** is almost always quicker than an index seek (even though if the index
** contains fewer than 2^17 rows we assume otherwise in other parts of
** the code). And, even if it is not, it should not be too much slower.
** On the other hand, the extra seeks could end up being significantly
** more expensive. */
assert( 42==sqlite3LogEst(18) );
if( saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nEq++;
pNew->u.btree.nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
if( pTerm ){
/* TUNING: When estimating skip-scan for a term that is also indexable,
** increase the cost of the skip-scan by 2x, to make it a little less
** desirable than the regular index lookup. */
nIter += 10; assert( 10==sqlite3LogEst(2) );
}
pNew->nOut -= nIter;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
pNew->nOut = saved_nOut;
pNew->u.btree.nEq = saved_nEq;
pNew->u.btree.nSkip = saved_nSkip;
}
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */
LogEst rCostIdx;
LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */
int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
| ︙ | ︙ | |||
115592 115593 115594 115595 115596 115597 115598 |
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
/* Loop over all indices
*/
for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
if( pProbe->pPartIdxWhere!=0
| | > | 117648 117649 117650 117651 117652 117653 117654 117655 117656 117657 117658 117659 117660 117661 117662 117663 |
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
/* Loop over all indices
*/
for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
if( pProbe->pPartIdxWhere!=0
&& !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
continue; /* Partial index inappropriate for this query */
}
rSize = pProbe->aiRowLogEst[0];
pNew->u.btree.nEq = 0;
pNew->u.btree.nSkip = 0;
pNew->nLTerm = 0;
pNew->iSortIdx = 0;
|
| ︙ | ︙ | |||
123010 123011 123012 123013 123014 123015 123016 |
*/
sqlite3VtabRollback(db);
/* Legacy behavior (sqlite3_close() behavior) is to return
** SQLITE_BUSY if the connection can not be closed immediately.
*/
if( !forceZombie && connectionIsBusy(db) ){
| | | 125067 125068 125069 125070 125071 125072 125073 125074 125075 125076 125077 125078 125079 125080 125081 |
*/
sqlite3VtabRollback(db);
/* Legacy behavior (sqlite3_close() behavior) is to return
** SQLITE_BUSY if the connection can not be closed immediately.
*/
if( !forceZombie && connectionIsBusy(db) ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized "
"statements or unfinished backups");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
#ifdef SQLITE_ENABLE_SQLLOG
if( sqlite3GlobalConfig.xSqllog ){
|
| ︙ | ︙ | |||
123140 123141 123142 123143 123144 123145 123146 |
pMod->xDestroy(pMod->pAux);
}
sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
| | | 125197 125198 125199 125200 125201 125202 125203 125204 125205 125206 125207 125208 125209 125210 125211 |
pMod->xDestroy(pMod->pAux);
}
sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
sqlite3ValueFree(db->pErr);
sqlite3CloseExtensions(db);
db->magic = SQLITE_MAGIC_ERROR;
/* The temp-database schema is allocated differently from the other schema
** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
|
| ︙ | ︙ | |||
123573 123574 123575 123576 123577 123578 123579 |
** and there are active VMs, then return SQLITE_BUSY. If a function
** is being overridden/deleted but there are no active VMs, allow the
** operation to continue but invalidate all precompiled statements.
*/
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
if( db->nVdbeActive ){
| | | 125630 125631 125632 125633 125634 125635 125636 125637 125638 125639 125640 125641 125642 125643 125644 |
** and there are active VMs, then return SQLITE_BUSY. If a function
** is being overridden/deleted but there are no active VMs, allow the
** operation to continue but invalidate all precompiled statements.
*/
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
if( db->nVdbeActive ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
return SQLITE_BUSY;
}else{
sqlite3ExpirePreparedStatements(db);
}
}
|
| ︙ | ︙ | |||
123911 123912 123913 123914 123915 123916 123917 |
sqlite3_mutex_enter(db->mutex);
if( zDb && zDb[0] ){
iDb = sqlite3FindDbName(db, zDb);
}
if( iDb<0 ){
rc = SQLITE_ERROR;
| | | | 125968 125969 125970 125971 125972 125973 125974 125975 125976 125977 125978 125979 125980 125981 125982 125983 125984 125985 |
sqlite3_mutex_enter(db->mutex);
if( zDb && zDb[0] ){
iDb = sqlite3FindDbName(db, zDb);
}
if( iDb<0 ){
rc = SQLITE_ERROR;
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
}else{
rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
sqlite3Error(db, rc);
}
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
#endif
}
|
| ︙ | ︙ | |||
124069 124070 124071 124072 124073 124074 124075 |
}
sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
z = (void *)outOfMem;
}else{
z = sqlite3_value_text16(db->pErr);
if( z==0 ){
| | | 126126 126127 126128 126129 126130 126131 126132 126133 126134 126135 126136 126137 126138 126139 126140 |
}
sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
z = (void *)outOfMem;
}else{
z = sqlite3_value_text16(db->pErr);
if( z==0 ){
sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode));
z = sqlite3_value_text16(db->pErr);
}
/* A malloc() may have failed within the call to sqlite3_value_text16()
** above. If this is the case, then the db->mallocFailed flag needs to
** be cleared before returning. Do this directly, instead of via
** sqlite3ApiExit(), to avoid setting the database handle error message.
*/
|
| ︙ | ︙ | |||
124156 124157 124158 124159 124160 124161 124162 |
u8 enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDel)(void*)
){
CollSeq *pColl;
int enc2;
| < | 126213 126214 126215 126216 126217 126218 126219 126220 126221 126222 126223 126224 126225 126226 |
u8 enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDel)(void*)
){
CollSeq *pColl;
int enc2;
assert( sqlite3_mutex_held(db->mutex) );
/* If SQLITE_UTF16 is specified as the encoding type, transform this
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
*/
|
| ︙ | ︙ | |||
124181 124182 124183 124184 124185 124186 124187 |
/* Check if this call is removing or replacing an existing collation
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
if( db->nVdbeActive ){
| | | | | 126237 126238 126239 126240 126241 126242 126243 126244 126245 126246 126247 126248 126249 126250 126251 126252 126253 126254 126255 126256 126257 126258 126259 126260 126261 126262 126263 126264 126265 126266 126267 126268 126269 126270 126271 126272 126273 126274 126275 126276 126277 126278 126279 126280 126281 126282 126283 126284 126285 |
/* Check if this call is removing or replacing an existing collation
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
if( db->nVdbeActive ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
sqlite3ExpirePreparedStatements(db);
invalidateCachedKeyInfo(db);
/* If collation sequence pColl was created directly by a call to
** sqlite3_create_collation, and not generated by synthCollSeq(),
** then any copies made by synthCollSeq() need to be invalidated.
** Also, collation destructor - CollSeq.xDel() - function may need
** to be called.
*/
if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName);
int j;
for(j=0; j<3; j++){
CollSeq *p = &aColl[j];
if( p->enc==pColl->enc ){
if( p->xDel ){
p->xDel(p->pUser);
}
p->xCmp = 0;
}
}
}
}
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
if( pColl==0 ) return SQLITE_NOMEM;
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
pColl->xDel = xDel;
pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
sqlite3Error(db, SQLITE_OK);
return SQLITE_OK;
}
/*
** This array defines hard upper bounds on limit values. The
** initializer must be kept in sync with the SQLITE_LIMIT_*
|
| ︙ | ︙ | |||
124237 124238 124239 124240 124241 124242 124243 124244 124245 124246 124247 124248 124249 124250 | SQLITE_MAX_COMPOUND_SELECT, SQLITE_MAX_VDBE_OP, SQLITE_MAX_FUNCTION_ARG, SQLITE_MAX_ATTACHED, SQLITE_MAX_LIKE_PATTERN_LENGTH, SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ SQLITE_MAX_TRIGGER_DEPTH, }; /* ** Make sure the hard limits are set to reasonable values */ #if SQLITE_MAX_LENGTH<100 # error SQLITE_MAX_LENGTH must be at least 100 | > | 126293 126294 126295 126296 126297 126298 126299 126300 126301 126302 126303 126304 126305 126306 126307 | SQLITE_MAX_COMPOUND_SELECT, SQLITE_MAX_VDBE_OP, SQLITE_MAX_FUNCTION_ARG, SQLITE_MAX_ATTACHED, SQLITE_MAX_LIKE_PATTERN_LENGTH, SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ SQLITE_MAX_TRIGGER_DEPTH, SQLITE_MAX_WORKER_THREADS, }; /* ** Make sure the hard limits are set to reasonable values */ #if SQLITE_MAX_LENGTH<100 # error SQLITE_MAX_LENGTH must be at least 100 |
| ︙ | ︙ | |||
124272 124273 124274 124275 124276 124277 124278 124279 124280 124281 124282 124283 124284 124285 | #endif #if SQLITE_MAX_COLUMN>32767 # error SQLITE_MAX_COLUMN must not exceed 32767 #endif #if SQLITE_MAX_TRIGGER_DEPTH<1 # error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 #endif /* ** Change the value of a limit. Report the old value. ** If an invalid limit index is supplied, report -1. ** Make no changes but still report the old value if the ** new limit is negative. | > > > | 126329 126330 126331 126332 126333 126334 126335 126336 126337 126338 126339 126340 126341 126342 126343 126344 126345 | #endif #if SQLITE_MAX_COLUMN>32767 # error SQLITE_MAX_COLUMN must not exceed 32767 #endif #if SQLITE_MAX_TRIGGER_DEPTH<1 # error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 #endif #if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 # error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 #endif /* ** Change the value of a limit. Report the old value. ** If an invalid limit index is supplied, report -1. ** Make no changes but still report the old value if the ** new limit is negative. |
| ︙ | ︙ | |||
124305 124306 124307 124308 124309 124310 124311 |
assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
SQLITE_MAX_LIKE_PATTERN_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
| > | | 126365 126366 126367 126368 126369 126370 126371 126372 126373 126374 126375 126376 126377 126378 126379 126380 |
assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
SQLITE_MAX_LIKE_PATTERN_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
return -1;
}
oldLimit = db->aLimit[limitId];
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
|
| ︙ | ︙ | |||
124652 124653 124654 124655 124656 124657 124658 124659 124660 124661 124662 124663 124664 124665 124666 124667 124668 124669 |
db->errMask = 0xff;
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->autoCommit = 1;
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
| > > | 126713 126714 126715 126716 126717 126718 126719 126720 126721 126722 126723 126724 126725 126726 126727 126728 126729 126730 126731 126732 |
db->errMask = 0xff;
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
db->autoCommit = 1;
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
|
| ︙ | ︙ | |||
124700 124701 124702 124703 124704 124705 124706 |
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
/* Parse the filename/URI argument. */
db->openFlags = flags;
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
| | | | 126763 126764 126765 126766 126767 126768 126769 126770 126771 126772 126773 126774 126775 126776 126777 126778 126779 126780 126781 126782 126783 126784 126785 126786 126787 126788 126789 |
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
/* Parse the filename/URI argument. */
db->openFlags = flags;
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
sqlite3_free(zErrMsg);
goto opendb_out;
}
/* Open the backend database driver */
rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
flags | SQLITE_OPEN_MAIN_DB);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_IOERR_NOMEM ){
rc = SQLITE_NOMEM;
}
sqlite3Error(db, rc);
goto opendb_out;
}
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
/* The default safety_level for the main database is 'full'; for the temp
|
| ︙ | ︙ | |||
124736 124737 124738 124739 124740 124741 124742 |
goto opendb_out;
}
/* Register all built-in functions, but do not attempt to read the
** database schema yet. This is delayed until the first time the database
** is accessed.
*/
| | | 126799 126800 126801 126802 126803 126804 126805 126806 126807 126808 126809 126810 126811 126812 126813 |
goto opendb_out;
}
/* Register all built-in functions, but do not attempt to read the
** database schema yet. This is delayed until the first time the database
** is accessed.
*/
sqlite3Error(db, SQLITE_OK);
sqlite3RegisterBuiltinFunctions(db);
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
rc = sqlite3_errcode(db);
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
124793 124794 124795 124796 124797 124798 124799 |
*/
#ifdef SQLITE_DEFAULT_LOCKING_MODE
db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
SQLITE_DEFAULT_LOCKING_MODE);
#endif
| | | 126856 126857 126858 126859 126860 126861 126862 126863 126864 126865 126866 126867 126868 126869 126870 |
*/
#ifdef SQLITE_DEFAULT_LOCKING_MODE
db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
SQLITE_DEFAULT_LOCKING_MODE);
#endif
if( rc ) sqlite3Error(db, rc);
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
|
| ︙ | ︙ | |||
125155 125156 125157 125158 125159 125160 125161 |
if( SQLITE_OK==rc && !pTab ){
sqlite3DbFree(db, zErrMsg);
zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
zColumnName);
rc = SQLITE_ERROR;
}
| | | 127218 127219 127220 127221 127222 127223 127224 127225 127226 127227 127228 127229 127230 127231 127232 |
if( SQLITE_OK==rc && !pTab ){
sqlite3DbFree(db, zErrMsg);
zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
zColumnName);
rc = SQLITE_ERROR;
}
sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg);
sqlite3DbFree(db, zErrMsg);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif
|
| ︙ | ︙ | |||
125519 125520 125521 125522 125523 125524 125525 125526 125527 125528 125529 125530 125531 125532 125533 125534 125535 |
#ifdef SQLITE_VDBE_COVERAGE
typedef void (*branch_callback)(void*,int,u8,u8);
sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
#endif
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);
**
** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if
** not.
*/
case SQLITE_TESTCTRL_ISINIT: {
if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
break;
}
| > > > > > > > < | 127582 127583 127584 127585 127586 127587 127588 127589 127590 127591 127592 127593 127594 127595 127596 127597 127598 127599 127600 127601 127602 127603 127604 127605 127606 127607 127608 127609 127610 127611 127612 |
#ifdef SQLITE_VDBE_COVERAGE
typedef void (*branch_callback)(void*,int,u8,u8);
sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
#endif
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */
case SQLITE_TESTCTRL_SORTER_MMAP: {
sqlite3 *db = va_arg(ap, sqlite3*);
db->nMaxSorterMmap = va_arg(ap, int);
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);
**
** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if
** not.
*/
case SQLITE_TESTCTRL_ISINIT: {
if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
break;
}
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
return rc;
}
/*
|
| ︙ | ︙ | |||
125803 125804 125805 125806 125807 125808 125809 |
removeFromBlockedList(db);
addToBlockedList(db);
}
}
leaveMutex();
assert( !db->mallocFailed );
| | | 127872 127873 127874 127875 127876 127877 127878 127879 127880 127881 127882 127883 127884 127885 127886 |
removeFromBlockedList(db);
addToBlockedList(db);
}
}
leaveMutex();
assert( !db->mallocFailed );
sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0));
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** This function is called while stepping or preparing a statement
** associated with connection db. The operation will return SQLITE_LOCKED
|
| ︙ | ︙ |
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.7" #define SQLITE_VERSION_NUMBER 3008007 #define SQLITE_SOURCE_ID "2014-09-01 18:21:27 672e7387b1bda8d007da7de4244226577d7ab2dc" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 |
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
#define SQLITE_LIMIT_SQL_LENGTH 1
#define SQLITE_LIMIT_COLUMN 2
#define SQLITE_LIMIT_EXPR_DEPTH 3
#define SQLITE_LIMIT_COMPOUND_SELECT 4
#define SQLITE_LIMIT_VDBE_OP 5
#define SQLITE_LIMIT_FUNCTION_ARG 6
#define SQLITE_LIMIT_ATTACHED 7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
| > > > > > | 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 |
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
**
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
** <dd>The maximum number of auxiliary worker threads that a single
** [prepared statement] may start.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
#define SQLITE_LIMIT_SQL_LENGTH 1
#define SQLITE_LIMIT_COLUMN 2
#define SQLITE_LIMIT_EXPR_DEPTH 3
#define SQLITE_LIMIT_COMPOUND_SELECT 4
#define SQLITE_LIMIT_VDBE_OP 5
#define SQLITE_LIMIT_FUNCTION_ARG 6
#define SQLITE_LIMIT_ATTACHED 7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
|
| ︙ | ︙ | |||
6161 6162 6163 6164 6165 6166 6167 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 | > | | 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_LAST 24 /* ** CAPI3REF: SQLite Runtime Status ** ** ^This interface is used to retrieve runtime status information ** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for |
| ︙ | ︙ |