Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update the built-in SQLite to the latest trunk version that includes various performance enhancements. The purpose here is to test the recent SQLite enhancements in a real-world application. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
ad744440dc89d439fef4b7988fbc7d00 |
User & Date: | drh 2022-03-02 02:00:30 |
Context
2022-03-07
| ||
19:01 | Update to the latest SQLite 3.39.0 alpha with its performance enhancements and bug fixes. ... (check-in: 14da62ee user: drh tags: trunk) | |
2022-03-03
| ||
23:19 | Use a CTE instead of querying the database in a loop when finding the start of a branch. This can bring significant speedup on some machines. ... (check-in: c7749bb0 user: danield tags: start-of-branch-cte) | |
2022-03-02
| ||
02:00 | Update the built-in SQLite to the latest trunk version that includes various performance enhancements. The purpose here is to test the recent SQLite enhancements in a real-world application. ... (check-in: ad744440 user: drh tags: trunk) | |
2022-03-01
| ||
21:02 | Ensure that db_open()'s db-is-an-appendvfs-binary check uses canonicalized filenames to avoid the problem reported in forum post 16880a28aad1a868. ... (check-in: ab7ad234 user: stephan tags: trunk) | |
Changes
Changes to extsrc/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.39.0. 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 |
︙ | ︙ | |||
448 449 450 451 452 453 454 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.39.0" #define SQLITE_VERSION_NUMBER 3039000 #define SQLITE_SOURCE_ID "2022-03-02 01:02:16 6497997aa80419688890ed5dbbb7d6acc26bf3732305ff4a728cba1fe4d1626b" /* ** 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 |
︙ | ︙ | |||
10069 10070 10071 10072 10073 10074 10075 | ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ ** ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value ** and remains valid for the duration of the xBestIndex method call. ** ^When xBestIndex returns, the sqlite3_value object returned by ** sqlite3_vtab_rhs_value() is automatically deallocated. ** | | | 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 | ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ ** ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value ** and remains valid for the duration of the xBestIndex method call. ** ^When xBestIndex returns, the sqlite3_value object returned by ** sqlite3_vtab_rhs_value() is automatically deallocated. ** ** The "_rhs_" in the name of this routine is an abbreviation for ** "Right-Hand Side". */ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} |
︙ | ︙ | |||
14707 14708 14709 14710 14711 14712 14713 | /* ** Handle type for pages. */ typedef struct PgHdr DbPage; /* | | | > | 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 | /* ** Handle type for pages. */ typedef struct PgHdr DbPage; /* ** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is ** reserved for working around a windows/posix incompatibility). It is ** used in the journal to signify that the remainder of the journal file ** is devoted to storing a super-journal name - there are no more pages to ** roll back. See comments for function writeSuperJournal() in pager.c ** for details. */ #define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) #define PAGER_SJ_PGNO(x) ((x)->lckPgno) /* ** Allowed values for the flags parameter to sqlite3PagerOpen(). ** ** NOTE: These values must match the corresponding BTREE_ values in btree.h. */ #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ |
︙ | ︙ | |||
15391 15392 15393 15394 15395 15396 15397 | KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif | < | 15392 15393 15394 15395 15396 15397 15398 15399 15400 15401 15402 15403 15404 15405 | KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif } p4; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS char *zComment; /* Comment to improve readability */ #endif #ifdef VDBE_PROFILE u32 cnt; /* Number of times this instruction was executed */ u64 cycles; /* Total time spent executing this instruction */ |
︙ | ︙ | |||
15442 15443 15444 15445 15446 15447 15448 | */ #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_STATIC (-1) /* Pointer to a static string */ #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */ #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ | < | | | | | | | | | | | | < | 15442 15443 15444 15445 15446 15447 15448 15449 15450 15451 15452 15453 15454 15455 15456 15457 15458 15459 15460 15461 15462 15463 15464 15465 15466 15467 15468 | */ #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_STATIC (-1) /* Pointer to a static string */ #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */ #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ #define P4_TABLE (-5) /* P4 is a pointer to a Table structure */ /* Above do not own any resources. Must free those below */ #define P4_FREE_IF_LE (-6) #define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */ #define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */ #define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */ #define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */ #define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_REAL (-12) /* P4 is a 64-bit floating point value */ #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 #define P5_ConstraintUnique 2 #define P5_ConstraintCheck 3 #define P5_ConstraintFK 4 |
︙ | ︙ | |||
15501 15502 15503 15504 15505 15506 15507 | /************** Include opcodes.h in the middle of vdbe.h ********************/ /************** Begin file opcodes.h *****************************************/ /* Automatically generated. Do not edit */ /* See the tool/mkopcodeh.tcl script for details */ #define OP_Savepoint 0 #define OP_AutoCommit 1 #define OP_Transaction 2 | < < < | | | | | | | | | | | | | > > > < < < | | | | | | | | | | | > > > | | | | | | 15499 15500 15501 15502 15503 15504 15505 15506 15507 15508 15509 15510 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 15526 15527 15528 15529 15530 15531 15532 15533 15534 15535 15536 15537 15538 15539 15540 15541 15542 15543 15544 15545 15546 15547 15548 | /************** Include opcodes.h in the middle of vdbe.h ********************/ /************** Begin file opcodes.h *****************************************/ /* Automatically generated. Do not edit */ /* See the tool/mkopcodeh.tcl script for details */ #define OP_Savepoint 0 #define OP_AutoCommit 1 #define OP_Transaction 2 #define OP_Checkpoint 3 #define OP_JournalMode 4 #define OP_Vacuum 5 #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ #define OP_Goto 8 /* jump */ #define OP_Gosub 9 /* jump */ #define OP_InitCoroutine 10 /* jump */ #define OP_Yield 11 /* jump */ #define OP_MustBeInt 12 /* jump */ #define OP_Jump 13 /* jump */ #define OP_Once 14 /* jump */ #define OP_If 15 /* jump */ #define OP_IfNot 16 /* jump */ #define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ #define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ #define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */ #define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */ #define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */ #define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */ #define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */ #define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */ #define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */ #define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */ #define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */ #define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */ #define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */ #define OP_Last 31 /* jump */ #define OP_IfSmaller 32 /* jump */ #define OP_SorterSort 33 /* jump */ #define OP_Sort 34 /* jump */ #define OP_Rewind 35 /* jump */ #define OP_SorterNext 36 /* jump */ #define OP_Prev 37 /* jump */ #define OP_Next 38 /* jump */ #define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */ #define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */ #define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */ #define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */ #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ #define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */ |
︙ | ︙ | |||
15695 15696 15697 15698 15699 15700 15701 | #define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ #define OPFLG_IN2 0x04 /* in2: P2 is an input */ #define OPFLG_IN3 0x08 /* in3: P3 is an input */ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ | | | | | | | 15693 15694 15695 15696 15697 15698 15699 15700 15701 15702 15703 15704 15705 15706 15707 15708 15709 15710 15711 | #define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ #define OPFLG_IN1 0x02 /* in1: P1 is an input */ #define OPFLG_IN2 0x04 /* in2: P2 is an input */ #define OPFLG_IN3 0x08 /* in3: P3 is an input */ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ /* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\ /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\ /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ /* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\ /* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\ /* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\ |
︙ | ︙ | |||
17776 17777 17778 17779 17780 17781 17782 17783 17784 17785 17786 17787 17788 17789 | ** before the first match or immediately after the last match. The ** eqSeen field will indicate whether or not an exact match exists in the ** b-tree. */ struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ Mem *aMem; /* Values */ 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) */ i8 r1; /* Value to return if (lhs < rhs) */ i8 r2; /* Value to return if (lhs > rhs) */ u8 eqSeen; /* True if an equality comparison has been seen */ }; | > > > > > | 17774 17775 17776 17777 17778 17779 17780 17781 17782 17783 17784 17785 17786 17787 17788 17789 17790 17791 17792 | ** before the first match or immediately after the last match. The ** eqSeen field will indicate whether or not an exact match exists in the ** b-tree. */ struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ Mem *aMem; /* Values */ union { char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ } u; int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ 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) */ i8 r1; /* Value to return if (lhs < rhs) */ i8 r2; /* Value to return if (lhs > rhs) */ u8 eqSeen; /* True if an equality comparison has been seen */ }; |
︙ | ︙ | |||
22223 22224 22225 22226 22227 22228 22229 22230 22231 22232 | union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ } u; u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ u8 eSubtype; /* Subtype for this value */ | > > < < | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > | | < < < | < | | | | < < < < < < | 22226 22227 22228 22229 22230 22231 22232 22233 22234 22235 22236 22237 22238 22239 22240 22241 22242 22243 22244 22245 22246 22247 22248 22249 22250 22251 22252 22253 22254 22255 22256 22257 22258 22259 22260 22261 22262 22263 22264 22265 22266 22267 22268 22269 22270 22271 22272 22273 22274 22275 22276 22277 22278 22279 22280 22281 22282 22283 22284 22285 22286 22287 22288 22289 22290 22291 22292 22293 22294 22295 22296 22297 22298 22299 22300 22301 22302 22303 22304 22305 22306 22307 22308 22309 22310 22311 22312 22313 22314 22315 22316 22317 22318 22319 22320 22321 22322 22323 22324 22325 22326 22327 22328 22329 22330 22331 22332 22333 | union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ } u; char *z; /* String or BLOB value */ int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ u8 eSubtype; /* Subtype for this value */ /* ShallowCopy only needs to copy the information above */ sqlite3 *db; /* The associated database connection */ int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ u16 mScopyFlags; /* flags value immediately after the shallow copy */ #endif }; /* ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ #define MEMCELLSIZE offsetof(Mem,db) /* One or more of the following flags are set to indicate the ** representations of the value stored in the Mem struct. ** ** * MEM_Null An SQL NULL value ** ** * MEM_Null|MEM_Zero An SQL NULL with the virtual table ** UPDATE no-change flag set ** ** * MEM_Null|MEM_Term| An SQL NULL, but also contains a ** MEM_Subtype pointer accessible using ** sqlite3_value_pointer(). ** ** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal ** to other NULLs even using the IS operator. ** ** * MEM_Str A string, stored in Mem.z with ** length Mem.n. Zero-terminated if ** MEM_Term is set. This flag is ** incompatible with MEM_Blob and ** MEM_Null, but can appear with MEM_Int, ** MEM_Real, and MEM_IntReal. ** ** * MEM_Blob A blob, stored in Mem.z length Mem.n. ** Incompatible with MEM_Str, MEM_Null, ** MEM_Int, MEM_Real, and MEM_IntReal. ** ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus ** MEM.u.i extra 0x00 bytes at the end. ** ** * MEM_Int Integer stored in Mem.u.i. ** ** * MEM_Real Real stored in Mem.u.r. ** ** * MEM_IntReal Real stored as an integer in Mem.u.i. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. ** For a pointer type created using sqlite3_bind_pointer() or ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main ** database (see below for exceptions). If the MEM_Term flag is also ** set, then the string is nul terminated. The MEM_Int and MEM_Real ** flags may coexist with the MEM_Str flag. */ #define MEM_Undefined 0x0000 /* Value is undefined */ #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */ #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */ #define MEM_AffMask 0x003f /* Mask of affinity bits */ /* Extra bits that modify the meanings of the core datatypes above */ #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */ /* 0x0080 // Available */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_Term 0x0200 /* String in Mem.z is zero terminated */ #define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */ #define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */ #define MEM_TypeMask 0x0dbf /* Mask of type bits */ /* Bits that determine the storage for Mem.z for a string or blob or ** aggregate accumulator. */ #define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */ #define MEM_Static 0x2000 /* Mem.z points to a static string */ #define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */ #define MEM_Agg 0x8000 /* Mem.z points to an agg function context */ /* Return TRUE if Mem X contains dynamically allocated content - anything ** that needs to be deallocated to avoid a leak. */ #define VdbeMemDynamic(X) \ (((X)->flags&(MEM_Agg|MEM_Dyn))!=0) |
︙ | ︙ | |||
22309 22310 22311 22312 22313 22314 22315 | ** True if Mem X is a NULL-nochng type. */ #define MemNullNochng(X) \ (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \ && (X)->n==0 && (X)->u.nZero==0) /* | | > > > > | | 22341 22342 22343 22344 22345 22346 22347 22348 22349 22350 22351 22352 22353 22354 22355 22356 22357 22358 22359 22360 22361 22362 22363 | ** True if Mem X is a NULL-nochng type. */ #define MemNullNochng(X) \ (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \ && (X)->n==0 && (X)->u.nZero==0) /* ** Return true if a memory cell has been initialized and is valid. ** is for use inside assert() statements only. ** ** A Memory cell is initialized if at least one of the ** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits ** is set. It is "undefined" if all those bits are zero. */ #ifdef SQLITE_DEBUG #define memIsValid(M) ((M)->flags & MEM_AffMask)!=0 #endif /* ** Each auxiliary data pointer stored by a user defined function ** implementation calling sqlite3_set_auxdata() is stored in an instance ** of this structure. All such structures associated with a single VM ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed |
︙ | ︙ | |||
22521 22522 22523 22524 22525 22526 22527 | /* ** Function prototypes */ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); | | | | 22557 22558 22559 22560 22561 22562 22563 22564 22565 22566 22567 22568 22569 22570 22571 22572 | /* ** Function prototypes */ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p); SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); |
︙ | ︙ | |||
34577 34578 34579 34580 34581 34582 34583 | # define OpHelp(X) #endif SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ static const char *const azName[] = { /* 0 */ "Savepoint" OpHelp(""), /* 1 */ "AutoCommit" OpHelp(""), /* 2 */ "Transaction" OpHelp(""), | < < < | | | | | | | | | | | | | > > > < < < | | | | | | | | | | | | | | | | > > > | 34613 34614 34615 34616 34617 34618 34619 34620 34621 34622 34623 34624 34625 34626 34627 34628 34629 34630 34631 34632 34633 34634 34635 34636 34637 34638 34639 34640 34641 34642 34643 34644 34645 34646 34647 34648 34649 34650 34651 34652 34653 34654 34655 34656 34657 34658 34659 34660 34661 34662 | # define OpHelp(X) #endif SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ static const char *const azName[] = { /* 0 */ "Savepoint" OpHelp(""), /* 1 */ "AutoCommit" OpHelp(""), /* 2 */ "Transaction" OpHelp(""), /* 3 */ "Checkpoint" OpHelp(""), /* 4 */ "JournalMode" OpHelp(""), /* 5 */ "Vacuum" OpHelp(""), /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), /* 8 */ "Goto" OpHelp(""), /* 9 */ "Gosub" OpHelp(""), /* 10 */ "InitCoroutine" OpHelp(""), /* 11 */ "Yield" OpHelp(""), /* 12 */ "MustBeInt" OpHelp(""), /* 13 */ "Jump" OpHelp(""), /* 14 */ "Once" OpHelp(""), /* 15 */ "If" OpHelp(""), /* 16 */ "IfNot" OpHelp(""), /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"), /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"), /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"), /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"), /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"), /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"), /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"), /* 28 */ "Found" OpHelp("key=r[P3@P4]"), /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"), /* 30 */ "NotExists" OpHelp("intkey=r[P3]"), /* 31 */ "Last" OpHelp(""), /* 32 */ "IfSmaller" OpHelp(""), /* 33 */ "SorterSort" OpHelp(""), /* 34 */ "Sort" OpHelp(""), /* 35 */ "Rewind" OpHelp(""), /* 36 */ "SorterNext" OpHelp(""), /* 37 */ "Prev" OpHelp(""), /* 38 */ "Next" OpHelp(""), /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"), /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"), /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"), /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), /* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
︙ | ︙ | |||
50903 50904 50905 50906 50907 50908 50909 | } /* ** Make sure the page is marked as dirty. If it isn't dirty already, ** make it so. */ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ | | > | 50939 50940 50941 50942 50943 50944 50945 50946 50947 50948 50949 50950 50951 50952 50953 50954 | } /* ** Make sure the page is marked as dirty. If it isn't dirty already, ** make it so. */ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ assert( p->nRef>0 || p->pCache->bPurgeable==0 ); testcase( p->nRef==0 ); assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); |
︙ | ︙ | |||
53872 53873 53874 53875 53876 53877 53878 53879 53880 53881 53882 53883 53884 53885 | ***************************************************************************/ u16 nExtra; /* Add this many bytes to each in-memory page */ i16 nReserve; /* Number of unused bytes at end of each page */ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ u32 sectorSize; /* Assumed sector size during rollback */ Pgno mxPgno; /* Maximum allowed size of the database */ i64 pageSize; /* Number of bytes in a page */ i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ int aStat[4]; /* Total cache hits, misses, writes, spills */ | > | 53909 53910 53911 53912 53913 53914 53915 53916 53917 53918 53919 53920 53921 53922 53923 | ***************************************************************************/ u16 nExtra; /* Add this many bytes to each in-memory page */ i16 nReserve; /* Number of unused bytes at end of each page */ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ u32 sectorSize; /* Assumed sector size during rollback */ Pgno mxPgno; /* Maximum allowed size of the database */ Pgno lckPgno; /* Page number for the locking page */ i64 pageSize; /* Number of bytes in a page */ i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ int aStat[4]; /* Total cache hits, misses, writes, spills */ |
︙ | ︙ | |||
54858 54859 54860 54861 54862 54863 54864 | /* ** Write the supplied super-journal name into the journal file for pager ** pPager at the current location. The super-journal name must be the last ** thing written to a journal file. If the pager is in full-sync mode, the ** journal file descriptor is advanced to the next sector boundary before ** anything is written. The format is: ** | | | 54896 54897 54898 54899 54900 54901 54902 54903 54904 54905 54906 54907 54908 54909 54910 | /* ** Write the supplied super-journal name into the journal file for pager ** pPager at the current location. The super-journal name must be the last ** thing written to a journal file. If the pager is in full-sync mode, the ** journal file descriptor is advanced to the next sector boundary before ** anything is written. The format is: ** ** + 4 bytes: PAGER_SJ_PGNO. ** + N bytes: super-journal filename in utf-8. ** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator). ** + 4 bytes: super-journal name checksum. ** + 8 bytes: aJournalMagic[]. ** ** The super-journal page checksum is the sum of the bytes in thesuper-journal ** name, where each byte is interpreted as a signed 8-bit integer. |
︙ | ︙ | |||
54906 54907 54908 54909 54910 54911 54912 | pPager->journalOff = journalHdrOffset(pPager); } iHdrOff = pPager->journalOff; /* Write the super-journal data to the end of the journal file. If ** an error occurs, return the error code to the caller. */ | | | 54944 54945 54946 54947 54948 54949 54950 54951 54952 54953 54954 54955 54956 54957 54958 | pPager->journalOff = journalHdrOffset(pPager); } iHdrOff = pPager->journalOff; /* Write the super-journal data to the end of the journal file. If ** an error occurs, return the error code to the caller. */ if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager)))) || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4))) || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper))) || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum))) || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nSuper+8))) ){ return rc; |
︙ | ︙ | |||
55416 55417 55418 55419 55420 55421 55422 | ** and played back, then SQLITE_OK is returned. If an IO error occurs ** while reading the record from the (sub-)journal file or while writing ** to the database file, then the IO error code is returned. If data ** is successfully read from the (sub-)journal file but appears to be ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in ** two circumstances: ** | | | 55454 55455 55456 55457 55458 55459 55460 55461 55462 55463 55464 55465 55466 55467 55468 | ** and played back, then SQLITE_OK is returned. If an IO error occurs ** while reading the record from the (sub-)journal file or while writing ** to the database file, then the IO error code is returned. If data ** is successfully read from the (sub-)journal file but appears to be ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in ** two circumstances: ** ** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or ** * If the record is being rolled back from the main journal file ** and the checksum field does not match the record content. ** ** Neither of these two scenarios are possible during a savepoint rollback. ** ** If this is a savepoint rollback, then memory may have to be dynamically ** allocated by this function. If this is the case and an allocation fails, |
︙ | ︙ | |||
55476 55477 55478 55479 55480 55481 55482 | *pOffset += pPager->pageSize + 4 + isMainJrnl*4; /* Sanity checking on the page. This is more important that I originally ** thought. If a power failure occurs while the journal is being written, ** it could cause invalid data to be written into the journal. We need to ** detect this invalid data (with high probability) and ignore it. */ | | | 55514 55515 55516 55517 55518 55519 55520 55521 55522 55523 55524 55525 55526 55527 55528 | *pOffset += pPager->pageSize + 4 + isMainJrnl*4; /* Sanity checking on the page. This is more important that I originally ** thought. If a power failure occurs while the journal is being written, ** it could cause invalid data to be written into the journal. We need to ** detect this invalid data (with high probability) and ignore it. */ if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){ assert( !isSavepnt ); return SQLITE_DONE; } if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ return SQLITE_OK; } if( isMainJrnl ){ |
︙ | ︙ | |||
56035 56036 56037 56038 56039 56040 56041 56042 56043 56044 56045 56046 56047 56048 | */ if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ rc = pager_truncate(pPager, mxPg); if( rc!=SQLITE_OK ){ goto end_playback; } pPager->dbSize = mxPg; } /* Copy original pages out of the journal and back into the ** database file and/or page cache. */ for(u=0; u<nRec; u++){ if( needPagerReset ){ | > > > | 56073 56074 56075 56076 56077 56078 56079 56080 56081 56082 56083 56084 56085 56086 56087 56088 56089 | */ if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ rc = pager_truncate(pPager, mxPg); if( rc!=SQLITE_OK ){ goto end_playback; } pPager->dbSize = mxPg; if( pPager->mxPgno<mxPg ){ pPager->mxPgno = mxPg; } } /* Copy original pages out of the journal and back into the ** database file and/or page cache. */ for(u=0; u<nRec; u++){ if( needPagerReset ){ |
︙ | ︙ | |||
56931 56932 56933 56934 56935 56936 56937 56938 56939 56940 56941 56942 56943 56944 | rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); } if( rc==SQLITE_OK ){ sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); pPager->pageSize = pageSize; }else{ sqlite3PageFree(pNew); } } *pPageSize = pPager->pageSize; if( rc==SQLITE_OK ){ | > | 56972 56973 56974 56975 56976 56977 56978 56979 56980 56981 56982 56983 56984 56985 56986 | rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); } if( rc==SQLITE_OK ){ sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); pPager->pageSize = pageSize; pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1; }else{ sqlite3PageFree(pNew); } } *pPageSize = pPager->pageSize; if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
58680 58681 58682 58683 58684 58685 58686 | sqlite3_pcache_page *pBase; assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); assert( pPager->hasHeldSharedLock==1 ); | < | | | | | 58722 58723 58724 58725 58726 58727 58728 58729 58730 58731 58732 58733 58734 58735 58736 58737 58738 58739 58740 58741 58742 58743 58744 58745 58746 58747 58748 58749 58750 58751 58752 58753 58754 58755 58756 58757 58758 58759 58760 58761 58762 58763 58764 58765 58766 | sqlite3_pcache_page *pBase; assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); assert( pPager->hasHeldSharedLock==1 ); pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ pPg = 0; rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); if( rc!=SQLITE_OK ) goto pager_acquire_err; if( pBase==0 ){ rc = SQLITE_NOMEM_BKPT; goto pager_acquire_err; } } pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); assert( pPg==(*ppPage) ); assert( pPg->pgno==pgno ); assert( pPg->pPager==pPager || pPg->pPager==0 ); noContent = (flags & PAGER_GET_NOCONTENT)!=0; if( pPg->pPager && !noContent ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno!=PAGER_SJ_PGNO(pPager) ); pPager->aStat[PAGER_STAT_HIT]++; return SQLITE_OK; }else{ /* The pager cache has created a new page. Its content needs to ** be initialized. But first some error checks: ** ** (1) Never try to fetch the locking page ** (2) Never try to fetch page 0, which does not exist */ if( pgno==PAGER_SJ_PGNO(pPager) || pgno==0 ){ rc = SQLITE_CORRUPT_BKPT; goto pager_acquire_err; } pPg->pPager = pPager; assert( !isOpen(pPager->fd) || !MEMDB ); |
︙ | ︙ | |||
59110 59111 59112 59113 59114 59115 59116 | u32 cksum; char *pData2; i64 iOff = pPager->journalOff; /* We should never write to the journal file the page that ** contains the database locks. The following assert verifies ** that we do not. */ | | | 59151 59152 59153 59154 59155 59156 59157 59158 59159 59160 59161 59162 59163 59164 59165 | u32 cksum; char *pData2; i64 iOff = pPager->journalOff; /* We should never write to the journal file the page that ** contains the database locks. The following assert verifies ** that we do not. */ assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) ); assert( pPager->journalHdr<=pPager->journalOff ); pData2 = pPg->pData; cksum = pager_cksum(pPager, (u8*)pData2); /* Even if an IO or diskfull error occurs while journalling the ** page in the block above, set the need-sync flag for the page. |
︙ | ︙ | |||
59289 59290 59291 59292 59293 59294 59295 | 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) ){ | | | 59330 59331 59332 59333 59334 59335 59336 59337 59338 59339 59340 59341 59342 59343 59344 | 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_SJ_PGNO(pPager) ){ rc = sqlite3PagerGet(pPager, pg, &pPage, 0); if( rc==SQLITE_OK ){ rc = pager_write(pPage); if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; } sqlite3PagerUnrefNotNull(pPage); |
︙ | ︙ | |||
59767 59768 59769 59770 59771 59772 59773 | /* If the file on disk is smaller than the database image, use ** pager_truncate to grow the file here. This can happen if the database ** image was extended as part of the current transaction and then the ** last page in the db image moved to the free-list. In this case the ** last page is never written out to disk, leaving the database file ** undersized. Fix this now if it is the case. */ if( pPager->dbSize>pPager->dbFileSize ){ | | | 59808 59809 59810 59811 59812 59813 59814 59815 59816 59817 59818 59819 59820 59821 59822 | /* If the file on disk is smaller than the database image, use ** pager_truncate to grow the file here. This can happen if the database ** image was extended as part of the current transaction and then the ** last page in the db image moved to the free-list. In this case the ** last page is never written out to disk, leaving the database file ** undersized. Fix this now if it is the case. */ if( pPager->dbSize>pPager->dbFileSize ){ Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager)); assert( pPager->eState==PAGER_WRITER_DBMOD ); rc = pager_truncate(pPager, nNew); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; } /* Finally, sync the database file. */ if( !noSync ){ |
︙ | ︙ | |||
65394 65395 65396 65397 65398 65399 65400 | u16 nCell; /* Number of cells on this page, local and ovfl */ u16 maskPage; /* Mask for page offset */ u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th ** non-overflow cell */ u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ | | > > | 65435 65436 65437 65438 65439 65440 65441 65442 65443 65444 65445 65446 65447 65448 65449 65450 65451 | u16 nCell; /* Number of cells on this page, local and ovfl */ u16 maskPage; /* Mask for page offset */ u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th ** non-overflow cell */ u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ u8 *aDataEnd; /* One byte past the end of the entire page - not just ** the usable space, the entire page. Used to prevent ** corruption-induced of buffer overflow. */ u8 *aCellIdx; /* The cell index area */ u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ DbPage *pDbPage; /* Pager page handle */ u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */ }; |
︙ | ︙ | |||
65699 65700 65701 65702 65703 65704 65705 | #define CURSOR_SKIPNEXT 2 #define CURSOR_REQUIRESEEK 3 #define CURSOR_FAULT 4 /* ** The database page the PENDING_BYTE occupies. This page is never used. */ | | | 65742 65743 65744 65745 65746 65747 65748 65749 65750 65751 65752 65753 65754 65755 65756 | #define CURSOR_SKIPNEXT 2 #define CURSOR_REQUIRESEEK 3 #define CURSOR_FAULT 4 /* ** The database page the PENDING_BYTE occupies. This page is never used. */ #define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1)) /* ** These macros define the location of the pointer-map entry for a ** database page. The first argument to each is the number of usable ** bytes on each page of the database (often 1024). The second is the ** page number to look up in the pointer map. ** |
︙ | ︙ | |||
67453 67454 67455 67456 67457 67458 67459 67460 67461 67462 67463 67464 67465 67466 | ** ** Compute the total number of bytes that a Cell needs in the cell ** data area of the btree-page. The return number includes the cell ** data header and the local payload, but not any overflow page or ** the space used by the cell pointer. ** ** cellSizePtrNoPayload() => table internal nodes ** cellSizePtr() => all index nodes & table leaf nodes */ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ u8 *pEnd; /* End mark for a varint */ u32 nSize; /* Size value to return */ | > | 67496 67497 67498 67499 67500 67501 67502 67503 67504 67505 67506 67507 67508 67509 67510 | ** ** Compute the total number of bytes that a Cell needs in the cell ** data area of the btree-page. The return number includes the cell ** data header and the local payload, but not any overflow page or ** the space used by the cell pointer. ** ** cellSizePtrNoPayload() => table internal nodes ** cellSizePtrTableLeaf() => table leaf nodes ** cellSizePtr() => all index nodes & table leaf nodes */ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ u8 *pEnd; /* End mark for a varint */ u32 nSize; /* Size value to return */ |
︙ | ︙ | |||
67478 67479 67480 67481 67482 67483 67484 | pEnd = &pIter[8]; nSize &= 0x7f; do{ nSize = (nSize<<7) | (*++pIter & 0x7f); }while( *(pIter)>=0x80 && pIter<pEnd ); } pIter++; | < < < < < < < | 67522 67523 67524 67525 67526 67527 67528 67529 67530 67531 67532 67533 67534 67535 | pEnd = &pIter[8]; nSize &= 0x7f; do{ nSize = (nSize<<7) | (*++pIter & 0x7f); }while( *(pIter)>=0x80 && pIter<pEnd ); } pIter++; testcase( nSize==pPage->maxLocal ); testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize<=pPage->maxLocal ){ nSize += (u32)(pIter - pCell); if( nSize<4 ) nSize = 4; }else{ int minLocal = pPage->minLocal; |
︙ | ︙ | |||
67524 67525 67526 67527 67528 67529 67530 67531 67532 67533 67534 67535 67536 67537 67538 67539 67540 67541 67542 67543 | assert( pPage->childPtrSize==4 ); pEnd = pIter + 9; while( (*pIter++)&0x80 && pIter<pEnd ); assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB ); return (u16)(pIter - pCell); } #ifdef SQLITE_DEBUG /* This variation on cellSizePtr() is used inside of assert() statements ** only. */ static u16 cellSize(MemPage *pPage, int iCell){ return pPage->xCellSize(pPage, findCell(pPage, iCell)); } #endif #ifndef SQLITE_OMIT_AUTOVACUUM /* ** The cell pCell is currently part of page pSrc but will ultimately be part | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 67561 67562 67563 67564 67565 67566 67567 67568 67569 67570 67571 67572 67573 67574 67575 67576 67577 67578 67579 67580 67581 67582 67583 67584 67585 67586 67587 67588 67589 67590 67591 67592 67593 67594 67595 67596 67597 67598 67599 67600 67601 67602 67603 67604 67605 67606 67607 67608 67609 67610 67611 67612 67613 67614 67615 67616 67617 67618 67619 67620 67621 67622 67623 67624 67625 67626 67627 67628 67629 67630 67631 67632 67633 67634 67635 67636 67637 67638 67639 67640 | assert( pPage->childPtrSize==4 ); pEnd = pIter + 9; while( (*pIter++)&0x80 && pIter<pEnd ); assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB ); return (u16)(pIter - pCell); } static u16 cellSizePtrTableLeaf(MemPage *pPage, u8 *pCell){ u8 *pIter = pCell; /* For looping over bytes of pCell */ u8 *pEnd; /* End mark for a varint */ u32 nSize; /* Size value to return */ #ifdef SQLITE_DEBUG /* The value returned by this function should always be the same as ** the (CellInfo.nSize) value found by doing a full parse of the ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of ** this function verifies that this invariant is not violated. */ CellInfo debuginfo; pPage->xParseCell(pPage, pCell, &debuginfo); #endif nSize = *pIter; if( nSize>=0x80 ){ pEnd = &pIter[8]; nSize &= 0x7f; do{ nSize = (nSize<<7) | (*++pIter & 0x7f); }while( *(pIter)>=0x80 && pIter<pEnd ); } pIter++; /* pIter now points at the 64-bit integer key value, a variable length ** integer. The following block moves pIter to point at the first byte ** past the end of the key value. */ if( (*pIter++)&0x80 && (*pIter++)&0x80 && (*pIter++)&0x80 && (*pIter++)&0x80 && (*pIter++)&0x80 && (*pIter++)&0x80 && (*pIter++)&0x80 && (*pIter++)&0x80 ){ pIter++; } testcase( nSize==pPage->maxLocal ); testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize<=pPage->maxLocal ){ nSize += (u32)(pIter - pCell); if( nSize<4 ) nSize = 4; }else{ int minLocal = pPage->minLocal; nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); testcase( nSize==pPage->maxLocal ); testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize>pPage->maxLocal ){ nSize = minLocal; } nSize += 4 + (u16)(pIter - pCell); } assert( nSize==debuginfo.nSize || CORRUPT_DB ); return (u16)nSize; } #ifdef SQLITE_DEBUG /* This variation on cellSizePtr() is used inside of assert() statements ** only. */ static u16 cellSize(MemPage *pPage, int iCell){ return pPage->xCellSize(pPage, findCell(pPage, iCell)); } #endif #ifndef SQLITE_OMIT_AUTOVACUUM /* ** The cell pCell is currently part of page pSrc but will ultimately be part ** of pPage. (pSrc and pPage are often the same.) If pCell contains a ** pointer to an overflow page, insert an entry into the pointer-map for ** the overflow page that will be valid after pCell has been moved to pPage. */ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ CellInfo info; if( *pRC ) return; assert( pCell!=0 ); |
︙ | ︙ | |||
67712 67713 67714 67715 67716 67717 67718 | ** will be ignored if adding the extra space to the fragmentation count ** causes the fragmentation count to exceed 60. */ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ const int hdr = pPg->hdrOffset; /* Offset to page header */ u8 * const aData = pPg->aData; /* Page data */ int iAddr = hdr + 1; /* Address of ptr to pc */ | > | > | | 67801 67802 67803 67804 67805 67806 67807 67808 67809 67810 67811 67812 67813 67814 67815 67816 67817 67818 67819 67820 67821 67822 67823 67824 67825 67826 67827 | ** will be ignored if adding the extra space to the fragmentation count ** causes the fragmentation count to exceed 60. */ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ const int hdr = pPg->hdrOffset; /* Offset to page header */ u8 * const aData = pPg->aData; /* Page data */ int iAddr = hdr + 1; /* Address of ptr to pc */ u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */ int pc = get2byte(pTmp); /* Address of a free slot */ int x; /* Excess size of the slot */ int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */ int size; /* Size of the free slot */ assert( pc>0 ); while( pc<=maxPC ){ /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each ** freeblock form a big-endian integer which is the size of the freeblock ** in bytes, including the 4-byte header. */ pTmp = &aData[pc+2]; size = get2byte(pTmp); if( (x = size - nByte)>=0 ){ testcase( x==4 ); testcase( x==3 ); if( x<4 ){ /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total ** number of bytes in fragments may not exceed 60. */ if( aData[hdr+7]>57 ) return 0; |
︙ | ︙ | |||
67747 67748 67749 67750 67751 67752 67753 | /* The slot remains on the free-list. Reduce its size to account ** for the portion used by the new allocation. */ put2byte(&aData[pc+2], x); } return &aData[pc + x]; } iAddr = pc; | > | | 67838 67839 67840 67841 67842 67843 67844 67845 67846 67847 67848 67849 67850 67851 67852 67853 | /* The slot remains on the free-list. Reduce its size to account ** for the portion used by the new allocation. */ put2byte(&aData[pc+2], x); } return &aData[pc + x]; } iAddr = pc; pTmp = &aData[pc]; pc = get2byte(pTmp); if( pc<=iAddr+size ){ if( pc ){ /* The next slot in the chain is not past the end of the current slot */ *pRc = SQLITE_CORRUPT_PAGE(pPg); } return 0; } |
︙ | ︙ | |||
67781 67782 67783 67784 67785 67786 67787 67788 67789 67790 67791 67792 67793 67794 67795 67796 67797 67798 67799 67800 67801 67802 67803 67804 67805 | ** 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 rc = SQLITE_OK; /* Integer return code */ int gap; /* First byte of gap between cell pointers and cell content */ 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 ); assert( nByte < (int)(pPage->pBt->usableSize-8) ); assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); gap = pPage->cellOffset + 2*pPage->nCell; assert( gap<=65536 ); /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size ** and the reserved space is zero (the usual value for reserved space) ** then the cell content offset of an empty page wants to be 65536. ** However, that integer is too large to be stored in a 2-byte unsigned ** integer, so a value of 0 is used in its place. */ | > > | | 67873 67874 67875 67876 67877 67878 67879 67880 67881 67882 67883 67884 67885 67886 67887 67888 67889 67890 67891 67892 67893 67894 67895 67896 67897 67898 67899 67900 67901 67902 67903 67904 67905 67906 67907 | ** 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 rc = SQLITE_OK; /* Integer return code */ u8 *pTmp; /* Temp ptr into data[] */ int gap; /* First byte of gap between cell pointers and cell content */ 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 ); assert( nByte < (int)(pPage->pBt->usableSize-8) ); assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); gap = pPage->cellOffset + 2*pPage->nCell; assert( gap<=65536 ); /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size ** and the reserved space is zero (the usual value for reserved space) ** then the cell content offset of an empty page wants to be 65536. ** However, that integer is too large to be stored in a 2-byte unsigned ** integer, so a value of 0 is used in its place. */ pTmp = &data[hdr+5]; top = get2byte(pTmp); assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */ if( gap>top ){ if( top==0 && pPage->pBt->usableSize==65536 ){ top = 65536; }else{ return SQLITE_CORRUPT_PAGE(pPage); } |
︙ | ︙ | |||
67881 67882 67883 67884 67885 67886 67887 67888 67889 67890 67891 67892 67893 67894 | 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 */ u16 x; /* Offset to cell content area */ 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( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ | > | 67975 67976 67977 67978 67979 67980 67981 67982 67983 67984 67985 67986 67987 67988 67989 | 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 */ u16 x; /* Offset to cell content area */ u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ u8 *pTmp; /* Temporary ptr into data[] */ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ |
︙ | ︙ | |||
67943 67944 67945 67946 67947 67948 67949 | iSize = iEnd - iPtr; iStart = iPtr; } } if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); data[hdr+7] -= nFrag; } | > | | 68038 68039 68040 68041 68042 68043 68044 68045 68046 68047 68048 68049 68050 68051 68052 68053 | iSize = iEnd - iPtr; iStart = iPtr; } } if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); data[hdr+7] -= nFrag; } pTmp = &data[hdr+5]; x = get2byte(pTmp); if( iStart<=x ){ /* 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( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage); if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage); put2byte(&data[hdr+1], iFreeBlk); |
︙ | ︙ | |||
67999 68000 68001 68002 68003 68004 68005 68006 68007 68008 68009 68010 68011 68012 | assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a ** leaf table b-tree page. */ assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); pPage->intKey = 1; if( pPage->leaf ){ pPage->intKeyLeaf = 1; pPage->xParseCell = btreeParseCellPtr; }else{ pPage->intKeyLeaf = 0; pPage->xCellSize = cellSizePtrNoPayload; pPage->xParseCell = btreeParseCellPtrNoPayload; } pPage->maxLocal = pBt->maxLeaf; | > | 68095 68096 68097 68098 68099 68100 68101 68102 68103 68104 68105 68106 68107 68108 68109 | assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a ** leaf table b-tree page. */ assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); pPage->intKey = 1; if( pPage->leaf ){ pPage->intKeyLeaf = 1; pPage->xCellSize = cellSizePtrTableLeaf; pPage->xParseCell = btreeParseCellPtr; }else{ pPage->intKeyLeaf = 0; pPage->xCellSize = cellSizePtrNoPayload; pPage->xParseCell = btreeParseCellPtrNoPayload; } pPage->maxLocal = pBt->maxLeaf; |
︙ | ︙ | |||
68179 68180 68181 68182 68183 68184 68185 | return SQLITE_CORRUPT_PAGE(pPage); } assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; pPage->aCellIdx = data + pPage->childPtrSize + 8; | | | 68276 68277 68278 68279 68280 68281 68282 68283 68284 68285 68286 68287 68288 68289 68290 | return SQLITE_CORRUPT_PAGE(pPage); } assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; pPage->aCellIdx = data + pPage->childPtrSize + 8; pPage->aDataEnd = pPage->aData + pBt->pageSize; pPage->aDataOfst = pPage->aData + pPage->childPtrSize; /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ pPage->nCell = get2byte(&data[3]); if( pPage->nCell>MX_CELL(pBt) ){ /* To many cells for a single page. The page must be corrupt */ return SQLITE_CORRUPT_PAGE(pPage); |
︙ | ︙ | |||
68214 68215 68216 68217 68218 68219 68220 | */ static void zeroPage(MemPage *pPage, int flags){ unsigned char *data = pPage->aData; BtShared *pBt = pPage->pBt; u8 hdr = pPage->hdrOffset; u16 first; | | | | 68311 68312 68313 68314 68315 68316 68317 68318 68319 68320 68321 68322 68323 68324 68325 68326 68327 68328 68329 68330 68331 68332 68333 68334 68335 68336 68337 68338 68339 68340 68341 | */ static void zeroPage(MemPage *pPage, int flags){ unsigned char *data = pPage->aData; BtShared *pBt = pPage->pBt; u8 hdr = pPage->hdrOffset; u16 first; assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); assert( sqlite3PagerGetData(pPage->pDbPage) == data ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pBt->mutex) ); if( pBt->btsFlags & BTS_FAST_SECURE ){ memset(&data[hdr], 0, pBt->usableSize - hdr); } data[hdr] = (char)flags; first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); memset(&data[hdr+1], 0, 4); data[hdr+7] = 0; put2byte(&data[hdr+5], pBt->usableSize); pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); pPage->cellOffset = first; pPage->aDataEnd = &data[pBt->pageSize]; pPage->aCellIdx = &data[first]; pPage->aDataOfst = &data[pPage->childPtrSize]; pPage->nOverflow = 0; assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nCell = 0; pPage->isInit = 1; |
︙ | ︙ | |||
68356 68357 68358 68359 68360 68361 68362 | if( (*ppPage)->isInit==0 ){ btreePageFromDbPage(pDbPage, pgno, pBt); rc = btreeInitPage(*ppPage); if( rc!=SQLITE_OK ){ goto getAndInitPage_error2; } } | | | > > | 68453 68454 68455 68456 68457 68458 68459 68460 68461 68462 68463 68464 68465 68466 68467 68468 68469 68470 68471 68472 68473 68474 68475 68476 68477 68478 68479 68480 68481 68482 68483 68484 68485 68486 68487 68488 | if( (*ppPage)->isInit==0 ){ btreePageFromDbPage(pDbPage, pgno, pBt); rc = btreeInitPage(*ppPage); if( rc!=SQLITE_OK ){ goto getAndInitPage_error2; } } assert( (*ppPage)->pgno==pgno || CORRUPT_DB ); assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); /* If obtaining a child page for a cursor, we must verify that the page is ** compatible with the root page. */ if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ rc = SQLITE_CORRUPT_PGNO(pgno); goto getAndInitPage_error2; } return SQLITE_OK; getAndInitPage_error2: releasePage(*ppPage); getAndInitPage_error1: if( pCur ){ pCur->iPage--; pCur->pPage = pCur->apPage[pCur->iPage]; } testcase( pgno==0 ); assert( pgno!=0 || rc==SQLITE_CORRUPT || rc==SQLITE_IOERR_NOMEM || rc==SQLITE_NOMEM ); return rc; } /* ** Release a MemPage. This should be called once for each prior ** call to btreeGetPage. ** |
︙ | ︙ | |||
75111 75112 75113 75114 75115 75116 75117 | || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ | | | 75210 75211 75212 75213 75214 75215 75216 75217 75218 75219 75220 75221 75222 75223 75224 | || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ if( pCur->eState>CURSOR_INVALID ){ rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeComputeFreeSpace(pPage); } if( rc ) return rc; } |
︙ | ︙ | |||
75429 75430 75431 75432 75433 75434 75435 | ** bPreserve==0 Not necessary to save the cursor position ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. */ bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ if( !pPage->leaf | | | 75528 75529 75530 75531 75532 75533 75534 75535 75536 75537 75538 75539 75540 75541 75542 | ** bPreserve==0 Not necessary to save the cursor position ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. */ bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ if( !pPage->leaf || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) || pPage->nCell==1 /* See dbfuzz001.test for a test case */ ){ /* A b-tree rebalance will be required after deleting this entry. ** Save the cursor key. */ rc = saveCursorKey(pCur); if( rc ) return rc; }else{ |
︙ | ︙ | |||
80543 80544 80545 80546 80547 80548 80549 | ** ** (2) Compute the maximum number of arguments used by any SQL function ** and store that value in *pMaxFuncArgs. ** ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately ** indicate what the prepared statement actually does. ** | | | 80642 80643 80644 80645 80646 80647 80648 80649 80650 80651 80652 80653 80654 80655 80656 | ** ** (2) Compute the maximum number of arguments used by any SQL function ** and store that value in *pMaxFuncArgs. ** ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately ** indicate what the prepared statement actually does. ** ** (4) (discontinued) ** ** (5) Reclaim the memory allocated for storing labels. ** ** This routine will only function correctly if the mkopcodeh.tcl generator ** script numbers the opcodes correctly. Changes to this routine must be ** coordinated with changes to mkopcodeh.tcl. */ |
︙ | ︙ | |||
80589 80590 80591 80592 80593 80594 80595 | #endif case OP_Vacuum: case OP_JournalMode: { p->readOnly = 0; p->bIsReader = 1; break; } | < < < < < < < < < < < < < < < < < < < | 80688 80689 80690 80691 80692 80693 80694 80695 80696 80697 80698 80699 80700 80701 | #endif case OP_Vacuum: case OP_JournalMode: { p->readOnly = 0; p->bIsReader = 1; break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case OP_VUpdate: { if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; break; } case OP_VFilter: { int n; |
︙ | ︙ | |||
80891 80892 80893 80894 80895 80896 80897 | case P4_FUNCCTX: { freeP4FuncCtx(db, (sqlite3_context*)p4); break; } case P4_REAL: case P4_INT64: case P4_DYNAMIC: | < | 80971 80972 80973 80974 80975 80976 80977 80978 80979 80980 80981 80982 80983 80984 | case P4_FUNCCTX: { freeP4FuncCtx(db, (sqlite3_context*)p4); break; } case P4_REAL: case P4_INT64: case P4_DYNAMIC: case P4_INTARRAY: { sqlite3DbFree(db, p4); break; } case P4_KEYINFO: { if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); break; |
︙ | ︙ | |||
81488 81489 81490 81491 81492 81493 81494 | sqlite3_str_append(&x, "]", 1); break; } case P4_SUBPROGRAM: { zP4 = "program"; break; } | < < < < | 81567 81568 81569 81570 81571 81572 81573 81574 81575 81576 81577 81578 81579 81580 | sqlite3_str_append(&x, "]", 1); break; } case P4_SUBPROGRAM: { zP4 = "program"; break; } case P4_TABLE: { zP4 = pOp->p4.pTab->zName; break; } default: { zP4 = pOp->p4.z; } |
︙ | ︙ | |||
81623 81624 81625 81626 81627 81628 81629 81630 81631 | sqlite3_free(zCom); sqlite3EndBenignMalloc(); } #endif /* ** Initialize an array of N Mem element. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ | > > > > > > > > > > > > | | | > | | | > | 81698 81699 81700 81701 81702 81703 81704 81705 81706 81707 81708 81709 81710 81711 81712 81713 81714 81715 81716 81717 81718 81719 81720 81721 81722 81723 81724 81725 81726 81727 81728 81729 81730 81731 81732 81733 81734 81735 | sqlite3_free(zCom); sqlite3EndBenignMalloc(); } #endif /* ** Initialize an array of N Mem element. ** ** This is a high-runner, so only those fields that really do need to ** be initialized are set. The Mem structure is organized so that ** the fields that get initialized are nearby and hopefully on the same ** cache line. ** ** Mem.flags = flags ** Mem.db = db ** Mem.szMalloc = 0 ** ** All other fields of Mem can safely remain uninitialized for now. They ** will be initialized before use. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ if( N>0 ){ do{ p->flags = flags; p->db = db; p->szMalloc = 0; #ifdef SQLITE_DEBUG p->pScopyFrom = 0; #endif p++; }while( (--N)>0 ); } } /* ** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N){ |
︙ | ︙ | |||
83290 83291 83292 83293 83294 83295 83296 | /* ** 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 supposed to be pointing. If the row was deleted out from under the ** cursor, set the cursor to point to a NULL row. */ | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < | 83379 83380 83381 83382 83383 83384 83385 83386 83387 83388 83389 83390 83391 83392 83393 83394 83395 83396 83397 83398 83399 83400 83401 83402 83403 83404 83405 83406 83407 83408 83409 83410 83411 | /* ** 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 supposed to be pointing. If the row was deleted out from under the ** cursor, set the cursor to point to a NULL row. */ SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){ int isDifferentRow, rc; assert( p->eCurType==CURTYPE_BTREE ); assert( p->uc.pCursor!=0 ); assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); p->cacheStatus = CACHE_STALE; if( isDifferentRow ) p->nullRow = 1; return rc; } /* ** Check to ensure that the cursor is valid. Restore the cursor ** if need be. Return any I/O error from the restore operation. */ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ assert( p->eCurType==CURTYPE_BTREE ); if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return sqlite3VdbeHandleMovedCursor(p); } return SQLITE_OK; } /* ** The following functions: ** |
︙ | ︙ | |||
84527 84528 84529 84530 84531 84532 84533 | case 0: case 7: return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); default: return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } | > | | 84584 84585 84586 84587 84588 84589 84590 84591 84592 84593 84594 84595 84596 84597 84598 84599 | case 0: case 7: return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); default: return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } assert( pPKey2->u.i == pPKey2->aMem[0].u.i ); v = pPKey2->u.i; if( v>lhs ){ res = pPKey2->r1; }else if( v<lhs ){ res = pPKey2->r2; }else if( pPKey2->nField>1 ){ /* The first fields of the two keys are equal. Compare the trailing ** fields. */ |
︙ | ︙ | |||
84562 84563 84564 84565 84566 84567 84568 84569 | UnpackedRecord *pPKey2 /* Right key */ ){ const u8 *aKey1 = (const u8*)pKey1; int serial_type; int res; assert( pPKey2->aMem[0].flags & MEM_Str ); vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); | > > | > > | > | > > | < | | | | 84620 84621 84622 84623 84624 84625 84626 84627 84628 84629 84630 84631 84632 84633 84634 84635 84636 84637 84638 84639 84640 84641 84642 84643 84644 84645 84646 84647 84648 84649 84650 84651 84652 84653 84654 84655 84656 84657 84658 84659 84660 84661 84662 84663 84664 84665 84666 84667 | UnpackedRecord *pPKey2 /* Right key */ ){ const u8 *aKey1 = (const u8*)pKey1; int serial_type; int res; assert( pPKey2->aMem[0].flags & MEM_Str ); assert( pPKey2->aMem[0].n == pPKey2->n ); assert( pPKey2->aMem[0].z == pPKey2->u.z ); vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); serial_type = (signed char)(aKey1[1]); vrcs_restart: if( serial_type<12 ){ if( serial_type<0 ){ sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type); if( serial_type>=12 ) goto vrcs_restart; assert( CORRUPT_DB ); } res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ }else if( !(serial_type & 0x01) ){ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ }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->n, nStr ); res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp); if( res>0 ){ res = pPKey2->r2; }else if( res<0 ){ res = pPKey2->r1; }else{ res = nStr - pPKey2->n; if( res==0 ){ if( pPKey2->nField>1 ){ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ res = pPKey2->default_rc; pPKey2->eqSeen = 1; } |
︙ | ︙ | |||
84644 84645 84646 84647 84648 84649 84650 84651 84652 84653 84654 84655 84656 84657 84658 84659 84660 84661 84662 84663 84664 84665 84666 | p->r1 = 1; p->r2 = -1; }else{ p->r1 = -1; p->r2 = 1; } if( (flags & MEM_Int) ){ return vdbeRecordCompareInt; } testcase( flags & MEM_Real ); testcase( flags & MEM_Null ); testcase( flags & MEM_Blob ); if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ assert( flags & MEM_Str ); return vdbeRecordCompareString; } } return sqlite3VdbeRecordCompare; } | > > > | 84708 84709 84710 84711 84712 84713 84714 84715 84716 84717 84718 84719 84720 84721 84722 84723 84724 84725 84726 84727 84728 84729 84730 84731 84732 84733 | p->r1 = 1; p->r2 = -1; }else{ p->r1 = -1; p->r2 = 1; } if( (flags & MEM_Int) ){ p->u.i = p->aMem[0].u.i; return vdbeRecordCompareInt; } testcase( flags & MEM_Real ); testcase( flags & MEM_Null ); testcase( flags & MEM_Blob ); if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ assert( flags & MEM_Str ); p->u.z = p->aMem[0].z; p->n = p->aMem[0].n; return vdbeRecordCompareString; } } return sqlite3VdbeRecordCompare; } |
︙ | ︙ | |||
86127 86128 86129 86130 86131 86132 86133 86134 86135 86136 | ** __attribute__((aligned(8))) macro. */ static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) __attribute__((aligned(8))) #endif = { /* .u = */ {0}, /* .flags = */ (u16)MEM_Null, /* .enc = */ (u8)0, /* .eSubtype = */ (u8)0, | > > | < < | | 86194 86195 86196 86197 86198 86199 86200 86201 86202 86203 86204 86205 86206 86207 86208 86209 86210 86211 86212 86213 86214 86215 86216 | ** __attribute__((aligned(8))) macro. */ static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) __attribute__((aligned(8))) #endif = { /* .u = */ {0}, /* .z = */ (char*)0, /* .n = */ (int)0, /* .flags = */ (u16)MEM_Null, /* .enc = */ (u8)0, /* .eSubtype = */ (u8)0, /* .db = */ (sqlite3*)0, /* .szMalloc = */ (int)0, /* .uTemp = */ (u32)0, /* .zMalloc = */ (char*)0, /* .xDel = */ (void(*)(void*))0, #ifdef SQLITE_DEBUG /* .pScopyFrom = */ (Mem*)0, /* .mScopyFlags= */ 0, #endif }; return &nullMem; |
︙ | ︙ | |||
90018 90019 90020 90021 90022 90023 90024 | ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { u32 p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ | | > < < < < < < | < < < > > > > > > > > > > > > > > > > > < < < < | 90085 90086 90087 90088 90089 90090 90091 90092 90093 90094 90095 90096 90097 90098 90099 90100 90101 90102 90103 90104 90105 90106 90107 90108 90109 90110 90111 90112 90113 90114 90115 90116 90117 90118 90119 90120 90121 90122 90123 90124 90125 90126 90127 90128 90129 90130 90131 90132 90133 90134 90135 90136 90137 90138 90139 90140 90141 90142 90143 90144 90145 90146 90147 90148 90149 90150 90151 90152 90153 90154 90155 90156 90157 90158 90159 90160 90161 90162 90163 90164 90165 90166 90167 90168 90169 90170 | ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { u32 p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ Mem *pDest; /* Where to write the extracted value */ Mem sMem; /* For storing the record being decoded */ const u8 *zData; /* Part of the record being decoded */ const u8 *zHdr; /* Next unparsed byte of the header */ const u8 *zEndHdr; /* Pointer to first byte after the header */ u64 offset64; /* 64-bit offset */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pC = p->apCsr[pOp->p1]; p2 = (u32)pOp->p2; op_column_restart: assert( pC!=0 ); assert( p2<(u32)pC->nField ); aOffset = pC->aOffset; assert( aOffset==pC->aType+pC->nField ); assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ /* For the special case of as pseudo-cursor, the seekResult field ** identifies the register that holds the record */ assert( pC->seekResult>0 ); pReg = &aMem[pC->seekResult]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = pReg->n; pC->aRow = (u8*)pReg->z; }else{ pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); sqlite3VdbeMemSetNull(pDest); goto op_column_out; } }else{ pCrsr = pC->uc.pCursor; if( pC->deferredMoveto ){ u32 iMap; assert( !pC->isEphemeral ); if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){ pC = pC->pAltCursor; p2 = iMap - 1; goto op_column_restart; } rc = sqlite3VdbeFinishMoveto(pC); if( rc ) goto abort_due_to_error; }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){ rc = sqlite3VdbeHandleMovedCursor(pC); if( rc ) goto abort_due_to_error; goto op_column_restart; } assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); assert( pC->szRow<=pC->payloadSize ); assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ } pC->cacheStatus = p->cacheCtr; pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]); pC->nHdrParsed = 0; if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/ /* pC->aRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be ** dynamically allocated. */ pC->aRow = 0; |
︙ | ︙ | |||
90125 90126 90127 90128 90129 90130 90131 90132 90133 90134 90135 90136 90137 90138 | ** database file. */ zData = pC->aRow; assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ testcase( aOffset[0]==0 ); goto op_column_read_header; } } /* Make sure at least the first p2+1 entries of the header have been ** parsed and valid information is in aOffset[] and pC->aType[]. */ if( pC->nHdrParsed<=p2 ){ /* If there is more header available for parsing in the record, try | > > > > | 90197 90198 90199 90200 90201 90202 90203 90204 90205 90206 90207 90208 90209 90210 90211 90212 90213 90214 | ** database file. */ zData = pC->aRow; assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ testcase( aOffset[0]==0 ); goto op_column_read_header; } }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){ rc = sqlite3VdbeHandleMovedCursor(pC); if( rc ) goto abort_due_to_error; goto op_column_restart; } /* Make sure at least the first p2+1 entries of the header have been ** parsed and valid information is in aOffset[] and pC->aType[]. */ if( pC->nHdrParsed<=p2 ){ /* If there is more header available for parsing in the record, try |
︙ | ︙ | |||
90193 90194 90195 90196 90197 90198 90199 90200 90201 90202 90203 90204 90205 90206 90207 90208 90209 90210 90211 90212 90213 90214 90215 90216 90217 90218 90219 90220 90221 90222 90223 90224 90225 90226 90227 90228 90229 90230 90231 90232 90233 90234 90235 90236 90237 90238 90239 90240 90241 90242 90243 | } /* If after trying to extract new entries from the header, nHdrParsed is ** still not up to p2, that means that the record has fewer than p2 ** columns. So the result will be either the default value or a NULL. */ if( pC->nHdrParsed<=p2 ){ if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ sqlite3VdbeMemSetNull(pDest); } goto op_column_out; } }else{ t = pC->aType[p2]; } /* Extract the content for the p2+1-th column. Control can only ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are ** all valid. */ assert( p2<pC->nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ){ sqlite3VdbeMemSetNull(pDest); } assert( t==pC->aType[p2] ); 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 */ zData = pC->aRow + aOffset[p2]; if( t<12 ){ sqlite3VdbeSerialGet(zData, t, pDest); }else{ /* If the column value is a string, we need a persistent value, not ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). */ static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; pDest->n = len = (t-12)/2; pDest->enc = encoding; if( pDest->szMalloc < len+2 ){ pDest->flags = MEM_Null; if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; }else{ pDest->z = pDest->zMalloc; } memcpy(pDest->z, zData, len); pDest->z[len] = 0; | > > > > > | 90269 90270 90271 90272 90273 90274 90275 90276 90277 90278 90279 90280 90281 90282 90283 90284 90285 90286 90287 90288 90289 90290 90291 90292 90293 90294 90295 90296 90297 90298 90299 90300 90301 90302 90303 90304 90305 90306 90307 90308 90309 90310 90311 90312 90313 90314 90315 90316 90317 90318 90319 90320 90321 90322 90323 90324 | } /* If after trying to extract new entries from the header, nHdrParsed is ** still not up to p2, that means that the record has fewer than p2 ** columns. So the result will be either the default value or a NULL. */ if( pC->nHdrParsed<=p2 ){ pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ sqlite3VdbeMemSetNull(pDest); } goto op_column_out; } }else{ t = pC->aType[p2]; } /* Extract the content for the p2+1-th column. Control can only ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are ** all valid. */ assert( p2<pC->nHdrParsed ); assert( rc==SQLITE_OK ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ){ sqlite3VdbeMemSetNull(pDest); } assert( t==pC->aType[p2] ); 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 */ zData = pC->aRow + aOffset[p2]; if( t<12 ){ sqlite3VdbeSerialGet(zData, t, pDest); }else{ /* If the column value is a string, we need a persistent value, not ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). */ static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; pDest->n = len = (t-12)/2; pDest->enc = encoding; if( pDest->szMalloc < len+2 ){ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; pDest->flags = MEM_Null; if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; }else{ pDest->z = pDest->zMalloc; } memcpy(pDest->z, zData, len); pDest->z[len] = 0; |
︙ | ︙ | |||
90262 90263 90264 90265 90266 90267 90268 90269 90270 90271 90272 90273 90274 90275 | ** buffer passed to it, debugging function VdbeMemPrettyPrint() may ** read more. Use the global constant sqlite3CtypeMap[] as the array, ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) ** and it begins with a bunch of zeros. */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); pDest->flags &= ~MEM_Ephem; } } | > | 90343 90344 90345 90346 90347 90348 90349 90350 90351 90352 90353 90354 90355 90356 90357 | ** buffer passed to it, debugging function VdbeMemPrettyPrint() may ** read more. Use the global constant sqlite3CtypeMap[] as the array, ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) ** and it begins with a bunch of zeros. */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); pDest->flags &= ~MEM_Ephem; } } |
︙ | ︙ | |||
90474 90475 90476 90477 90478 90479 90480 | i64 nZero; /* Number of zero bytes at the end of the record */ int nVarint; /* Number of bytes in a varint */ u32 serial_type; /* Type field */ Mem *pData0; /* First field to be combined into the record */ Mem *pLast; /* Last field of the record */ int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ | < | 90556 90557 90558 90559 90560 90561 90562 90563 90564 90565 90566 90567 90568 90569 | i64 nZero; /* Number of zero bytes at the end of the record */ int nVarint; /* Number of bytes in a varint */ u32 serial_type; /* Type field */ Mem *pData0; /* First field to be combined into the record */ Mem *pLast; /* Last field of the record */ int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ u32 len; /* Length of a field */ u8 *zHdr; /* Where to write next byte of the header */ u8 *zPayload; /* Where to write next byte of the payload */ /* Assuming the record contains N fields, the record format looks ** like this: ** |
︙ | ︙ | |||
90503 90504 90505 90506 90507 90508 90509 | nZero = 0; /* Number of zero bytes at the end of the record */ nField = pOp->p1; zAffinity = pOp->p4.z; assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); pData0 = &aMem[nField]; nField = pOp->p2; pLast = &pData0[nField-1]; | < | 90584 90585 90586 90587 90588 90589 90590 90591 90592 90593 90594 90595 90596 90597 | nZero = 0; /* Number of zero bytes at the end of the record */ nField = pOp->p1; zAffinity = pOp->p4.z; assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); pData0 = &aMem[nField]; nField = pOp->p2; pLast = &pData0[nField-1]; /* Identify the output register */ assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); pOut = &aMem[pOp->p3]; memAboutToChange(p, pOut); /* Apply the requested affinity to all inputs |
︙ | ︙ | |||
90605 90606 90607 90608 90609 90610 90611 | nHdr++; testcase( uu==127 ); testcase( uu==128 ); testcase( uu==32767 ); testcase( uu==32768 ); testcase( uu==8388607 ); testcase( uu==8388608 ); testcase( uu==2147483647 ); testcase( uu==2147483648LL ); testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); if( uu<=127 ){ | | | 90685 90686 90687 90688 90689 90690 90691 90692 90693 90694 90695 90696 90697 90698 90699 | nHdr++; testcase( uu==127 ); testcase( uu==128 ); testcase( uu==32767 ); testcase( uu==32768 ); testcase( uu==8388607 ); testcase( uu==8388608 ); testcase( uu==2147483647 ); testcase( uu==2147483648LL ); testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); if( uu<=127 ){ if( (i&1)==i && p->minWriteFileFormat>=4 ){ pRec->uTemp = 8+(u32)uu; }else{ nData++; pRec->uTemp = 1; } }else if( uu<=32767 ){ nData += 2; |
︙ | ︙ | |||
93068 93069 93070 93071 93072 93073 93074 93075 93076 93077 93078 93079 93080 93081 | } /* Opcode: NullRow P1 * * * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. */ case OP_NullRow: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); | > > > > | 93148 93149 93150 93151 93152 93153 93154 93155 93156 93157 93158 93159 93160 93161 93162 93163 93164 93165 | } /* Opcode: NullRow P1 * * * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. ** ** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo) ** just reset the cache for that cursor. This causes the row of ** content held by the pseudo-cursor to be reparsed. */ case OP_NullRow: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); |
︙ | ︙ | |||
93247 93248 93249 93250 93251 93252 93253 | pC->nullRow = (u8)res; assert( pOp->p2>0 && pOp->p2<p->nOp ); VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; } | | < < < | < < < > > > > > > > > > > > > > < < < < < < | | < < < < | 93331 93332 93333 93334 93335 93336 93337 93338 93339 93340 93341 93342 93343 93344 93345 93346 93347 93348 93349 93350 93351 93352 93353 93354 93355 93356 93357 93358 93359 93360 93361 93362 93363 93364 93365 93366 93367 93368 93369 93370 93371 93372 93373 93374 93375 93376 93377 93378 93379 93380 93381 93382 93383 93384 93385 93386 93387 93388 93389 93390 93391 93392 93393 93394 93395 93396 93397 93398 93399 93400 93401 93402 93403 93404 93405 93406 93407 93408 93409 93410 93411 93412 93413 93414 93415 93416 93417 93418 93419 93420 93421 93422 93423 93424 93425 93426 93427 93428 93429 93430 93431 93432 | pC->nullRow = (u8)res; assert( pOp->p2>0 && pOp->p2<p->nOp ); VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; } /* Opcode: Next P1 P2 P3 * P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its ** table or index. If there are no more key/value pairs then fall through ** to the following instruction. But if the cursor advance was successful, ** jump immediately to P2. ** ** The Next opcode is only valid following an SeekGT, SeekGE, or ** OP_Rewind opcode used to position the cursor. Next is not allowed ** to follow SeekLT, SeekLE, or OP_Last. ** ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have ** been opened prior to this opcode or the program will segfault. ** ** The P3 value is a hint to the btree implementation. If P3==1, that ** means P1 is an SQL index and that this instruction could have been ** omitted if that index had been unique. P3 is usually 0. P3 is ** always either 0 or 1. ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** ** See also: Prev */ /* Opcode: Prev P1 P2 P3 * P5 ** ** Back up cursor P1 so that it points to the previous key/data pair in its ** table or index. If there is no previous key/value pairs then fall through ** to the following instruction. But if the cursor backup was successful, ** jump immediately to P2. ** ** ** The Prev opcode is only valid following an SeekLT, SeekLE, or ** OP_Last opcode used to position the cursor. Prev is not allowed ** to follow SeekGT, SeekGE, or OP_Rewind. ** ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is ** not open then the behavior is undefined. ** ** The P3 value is a hint to the btree implementation. If P3==1, that ** means P1 is an SQL index and that this instruction could have been ** omitted if that index had been unique. P3 is usually 0. P3 is ** always either 0 or 1. ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ /* Opcode: SorterNext P1 P2 * * P5 ** ** This opcode works just like OP_Next except that P1 must be a ** sorter object for which the OP_SorterSort opcode has been ** invoked. This opcode advances the cursor to the next sorted ** record, or jumps to P2 if there are no more sorted records. */ case OP_SorterNext: { /* jump */ VdbeCursor *pC; pC = p->apCsr[pOp->p1]; assert( isSorter(pC) ); rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; case OP_Prev: /* jump */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p5<ArraySize(p->aCounter) ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope || pC->seekOp==OP_NullRow); rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); goto next_tail; case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p5<ArraySize(p->aCounter) ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid || pC->seekOp==OP_IfNoHope); rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3); next_tail: pC->cacheStatus = CACHE_STALE; VdbeBranchTaken(rc==SQLITE_OK,2); if( rc==SQLITE_OK ){ pC->nullRow = 0; p->aCounter[pOp->p5]++; #ifdef SQLITE_TEST |
︙ | ︙ | |||
93555 93556 93557 93558 93559 93560 93561 93562 93563 93564 93565 93566 93567 93568 | assert( pTabCur!=0 ); assert( pTabCur->eCurType==CURTYPE_BTREE ); assert( pTabCur->uc.pCursor!=0 ); assert( pTabCur->isTable ); pTabCur->nullRow = 0; pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); assert( !pTabCur->isEphemeral ); pTabCur->ub.aAltMap = pOp->p4.ai; assert( !pC->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); | > | 93636 93637 93638 93639 93640 93641 93642 93643 93644 93645 93646 93647 93648 93649 93650 | assert( pTabCur!=0 ); assert( pTabCur->eCurType==CURTYPE_BTREE ); assert( pTabCur->uc.pCursor!=0 ); assert( pTabCur->isTable ); pTabCur->nullRow = 0; pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; pTabCur->cacheStatus = CACHE_STALE; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); assert( !pTabCur->isEphemeral ); pTabCur->ub.aAltMap = pOp->p4.ai; assert( !pC->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); |
︙ | ︙ | |||
112067 112068 112069 112070 112071 112072 112073 | if( db->xPreUpdateCallback ){ pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); if( pStat1==0 ) return; pStat1->zName = (char*)&pStat1[1]; memcpy(pStat1->zName, "sqlite_stat1", 13); pStat1->nCol = 3; pStat1->iPKey = -1; | | | 112149 112150 112151 112152 112153 112154 112155 112156 112157 112158 112159 112160 112161 112162 112163 | if( db->xPreUpdateCallback ){ pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); if( pStat1==0 ) return; pStat1->zName = (char*)&pStat1[1]; memcpy(pStat1->zName, "sqlite_stat1", 13); pStat1->nCol = 3; pStat1->iPKey = -1; sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC); } #endif /* Establish a read-lock on the table at the shared-cache level. ** Open a read-only cursor on the table. Also allocate a cursor number ** to use for scanning indexes (iIdxCur). No index cursor is opened at ** this time though. */ |
︙ | ︙ | |||
125673 125674 125675 125676 125677 125678 125679 | ** INSERT INTO <table1> SELECT * FROM <table2>; ** ** Then special optimizations can be applied that make the transfer ** very fast and which reduce fragmentation of indices. ** ** This is the 2nd template. */ | > > > | > | 125755 125756 125757 125758 125759 125760 125761 125762 125763 125764 125765 125766 125767 125768 125769 125770 125771 125772 125773 | ** INSERT INTO <table1> SELECT * FROM <table2>; ** ** Then special optimizations can be applied that make the transfer ** very fast and which reduce fragmentation of indices. ** ** This is the 2nd template. */ if( pColumn==0 && pSelect!=0 && pTrigger==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ assert( !pTrigger ); assert( pList==0 ); goto insert_end; } #endif /* SQLITE_OMIT_XFER_OPT */ /* If this is an AUTOINCREMENT table, look up the sequence number in the |
︙ | ︙ | |||
127644 127645 127646 127647 127648 127649 127650 | int emptyDestTest = 0; /* Address of test for empty pDest */ int emptySrcTest = 0; /* Address of test for empty pSrc */ Vdbe *v; /* The VDBE we are building */ int regAutoinc; /* Memory register used by AUTOINC */ int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ int regData, regRowid; /* Registers holding data and rowid */ | | < < < < < | 127730 127731 127732 127733 127734 127735 127736 127737 127738 127739 127740 127741 127742 127743 127744 127745 127746 127747 127748 127749 127750 | int emptyDestTest = 0; /* Address of test for empty pDest */ int emptySrcTest = 0; /* Address of test for empty pSrc */ Vdbe *v; /* The VDBE we are building */ int regAutoinc; /* Memory register used by AUTOINC */ int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ int regData, regRowid; /* Registers holding data and rowid */ assert( pSelect!=0 ); if( pParse->pWith || pSelect->pWith ){ /* Do not attempt to process this query if there are an WITH clauses ** attached to it. Proceeding may generate a false "no such table: xxx" ** error if pSelect reads from a CTE named "xxx". */ return 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pDest) ){ return 0; /* tab1 must not be a virtual table */ } #endif if( onError==OE_Default ){ if( pDest->iPKey>=0 ) onError = pDest->keyConf; |
︙ | ︙ | |||
130009 130010 130011 130012 130013 130014 130015 | /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, | | | 130090 130091 130092 130093 130094 130095 130096 130097 130098 130099 130100 130101 130102 130103 130104 | /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 47, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, |
︙ | ︙ | |||
130697 130698 130699 130700 130701 130702 130703 | */ static void pragmaFunclistLine( Vdbe *v, /* The prepared statement being created */ FuncDef *p, /* A particular function definition */ int isBuiltin, /* True if this is a built-in function */ int showInternFuncs /* True if showing internal functions */ ){ | < < | | | | | | | > > > | 130778 130779 130780 130781 130782 130783 130784 130785 130786 130787 130788 130789 130790 130791 130792 130793 130794 130795 130796 130797 130798 130799 130800 130801 | */ static void pragmaFunclistLine( Vdbe *v, /* The prepared statement being created */ FuncDef *p, /* A particular function definition */ int isBuiltin, /* True if this is a built-in function */ int showInternFuncs /* True if showing internal functions */ ){ u32 mask = SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY | SQLITE_SUBTYPE | SQLITE_INNOCUOUS | SQLITE_FUNC_INTERNAL ; if( showInternFuncs ) mask = 0xffffffff; for(; p; p=p->pNext){ const char *zType; static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" }; assert( SQLITE_FUNC_ENCMASK==0x3 ); assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 ); assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 ); assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 ); |
︙ | ︙ | |||
148506 148507 148508 148509 148510 148511 148512 148513 148514 | ** a rowid value just read from cursor iIdxCur, open on index pIdx. This ** function generates code to do a deferred seek of cursor iCur to the ** rowid stored in register iRowid. ** ** Normally, this is just: ** ** OP_DeferredSeek $iCur $iRowid ** ** However, if the scan currently being coded is a branch of an OR-loop and | > > | < > > > | | | | > > > > | 148588 148589 148590 148591 148592 148593 148594 148595 148596 148597 148598 148599 148600 148601 148602 148603 148604 148605 148606 148607 148608 148609 148610 148611 148612 148613 148614 148615 148616 148617 | ** a rowid value just read from cursor iIdxCur, open on index pIdx. This ** function generates code to do a deferred seek of cursor iCur to the ** rowid stored in register iRowid. ** ** Normally, this is just: ** ** OP_DeferredSeek $iCur $iRowid ** ** Which causes a seek on $iCur to the row with rowid $iRowid. ** ** However, if the scan currently being coded is a branch of an OR-loop and ** the statement currently being coded is a SELECT, then additional information ** is added that might allow OP_Column to omit the seek and instead do its ** lookup on the index, thus avoiding an expensive seek operation. To ** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur ** and P4 is set to an array of integers containing one entry for each column ** in the table. For each table column, if the column is the i'th ** column of the index, then the corresponding array entry is set to (i+1). ** If the column does not appear in the index at all, the array entry is set ** to 0. The OP_Column opcode can check this array to see if the column it ** wants is in the index and if it is, it will substitute the index cursor ** and column number and continue with those new values, rather than seeking ** the table cursor. */ static void codeDeferredSeek( WhereInfo *pWInfo, /* Where clause context */ Index *pIdx, /* Index scan is using */ int iCur, /* Cursor for IPK b-tree */ int iIdxCur /* Index cursor */ ){ |
︙ | ︙ | |||
234296 234297 234298 234299 234300 234301 234302 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); | | | 234386 234387 234388 234389 234390 234391 234392 234393 234394 234395 234396 234397 234398 234399 234400 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); sqlite3_result_text(pCtx, "fts5: 2022-03-02 01:02:16 6497997aa80419688890ed5dbbb7d6acc26bf3732305ff4a728cba1fe4d1626b", -1, SQLITE_TRANSIENT); } /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. */ static int fts5ShadowName(const char *zName){ |
︙ | ︙ |
Changes to extsrc/sqlite3.h.
︙ | ︙ | |||
142 143 144 145 146 147 148 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.39.0" #define SQLITE_VERSION_NUMBER 3039000 #define SQLITE_SOURCE_ID "2022-03-02 01:02:16 6497997aa80419688890ed5dbbb7d6acc26bf3732305ff4a728cba1fe4d1626b" /* ** 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 |
︙ | ︙ | |||
9763 9764 9765 9766 9767 9768 9769 | ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ ** ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value ** and remains valid for the duration of the xBestIndex method call. ** ^When xBestIndex returns, the sqlite3_value object returned by ** sqlite3_vtab_rhs_value() is automatically deallocated. ** | | | 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 | ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ ** ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value ** and remains valid for the duration of the xBestIndex method call. ** ^When xBestIndex returns, the sqlite3_value object returned by ** sqlite3_vtab_rhs_value() is automatically deallocated. ** ** The "_rhs_" in the name of this routine is an abbreviation for ** "Right-Hand Side". */ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} |
︙ | ︙ |