| | @@ -16,11 +16,11 @@ |
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | | -** 3f3fb9b638f59ad982beafb7c117f24ddd3d with changes in files: |
| 21 | +** 716782abe939083b7732289d862ddfd84105 with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -467,14 +467,14 @@ |
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 469 | 469 | */ |
| 470 | 470 | #define SQLITE_VERSION "3.54.0" |
| 471 | 471 | #define SQLITE_VERSION_NUMBER 3054000 |
| 472 | | -#define SQLITE_SOURCE_ID "2026-06-16 13:43:08 3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06" |
| 472 | +#define SQLITE_SOURCE_ID "2026-06-26 19:31:46 716782abe939083b7732289d862ddfd841057d3458814f96e5e6d7826ec7fa5c" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2026-06-16T13:43:08.110Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-06-26T19:31:46.902Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -3732,11 +3732,11 @@ |
| 3732 | 3732 | ** authorizer will fail with an error message explaining that |
| 3733 | 3733 | ** access is denied. |
| 3734 | 3734 | ** |
| 3735 | 3735 | ** ^The first parameter to the authorizer callback is a copy of the third |
| 3736 | 3736 | ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter |
| 3737 | | -** to the callback is an integer [SQLITE_COPY | action code] that specifies |
| 3737 | +** to the callback is an integer [SQLITE_READ | action code] that specifies |
| 3738 | 3738 | ** the particular action to be authorized. ^The third through sixth parameters |
| 3739 | 3739 | ** to the callback are either NULL pointers or zero-terminated strings |
| 3740 | 3740 | ** that contain additional details about the action to be authorized. |
| 3741 | 3741 | ** Applications must always be prepared to encounter a NULL pointer in any |
| 3742 | 3742 | ** of the third through the sixth parameters of the authorization callback. |
| | @@ -3775,25 +3775,37 @@ |
| 3775 | 3775 | ** ^(Only a single authorizer can be in place on a database connection |
| 3776 | 3776 | ** at a time. Each call to sqlite3_set_authorizer overrides the |
| 3777 | 3777 | ** previous call.)^ ^Disable the authorizer by installing a NULL callback. |
| 3778 | 3778 | ** The authorizer is disabled by default. |
| 3779 | 3779 | ** |
| 3780 | | -** The authorizer callback must not do anything that will modify |
| 3780 | +** <h3>Limitations And Caveats</h3><ul> |
| 3781 | +** |
| 3782 | +** <li>The authorizer callback must not do anything that will modify |
| 3781 | 3783 | ** the database connection that invoked the authorizer callback. |
| 3782 | 3784 | ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their |
| 3783 | 3785 | ** database connections for the meaning of "modify" in this paragraph. |
| 3784 | 3786 | ** |
| 3785 | | -** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the |
| 3787 | +** <li>^When [sqlite3_prepare_v2()] is used to prepare a statement, the |
| 3786 | 3788 | ** statement might be re-prepared during [sqlite3_step()] due to a |
| 3787 | 3789 | ** schema change. Hence, the application should ensure that the |
| 3788 | 3790 | ** correct authorizer callback remains in place during the [sqlite3_step()]. |
| 3789 | 3791 | ** |
| 3790 | | -** ^Note that the authorizer callback is invoked only during |
| 3792 | +** <li>^The authorizer callback is invoked only during |
| 3791 | 3793 | ** [sqlite3_prepare()] or its variants. Authorization is not |
| 3792 | 3794 | ** performed during statement evaluation in [sqlite3_step()], unless |
| 3793 | 3795 | ** as stated in the previous paragraph, sqlite3_step() invokes |
| 3794 | 3796 | ** sqlite3_prepare_v2() to reprepare a statement after a schema change. |
| 3797 | +** |
| 3798 | +** <li>Authorizer callbacks for the expressions of a |
| 3799 | +** [generated column] are invoked when the schema is parsed (and specifically |
| 3800 | +** when the [CREATE TABLE] statement that contains the generated column is |
| 3801 | +** parsed) not when the generated column is used in a DML statement. |
| 3802 | +** This is deliberate, as one of the purposes of generated columns |
| 3803 | +** is to give schema designers the ability to provide gated access |
| 3804 | +** to privileged columns and/or functions. |
| 3805 | +** |
| 3806 | +** </ul> |
| 3795 | 3807 | */ |
| 3796 | 3808 | SQLITE_API int sqlite3_set_authorizer( |
| 3797 | 3809 | sqlite3*, |
| 3798 | 3810 | int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), |
| 3799 | 3811 | void *pUserData |
| | @@ -3864,12 +3876,17 @@ |
| 3864 | 3876 | #define SQLITE_ANALYZE 28 /* Table Name NULL */ |
| 3865 | 3877 | #define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ |
| 3866 | 3878 | #define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ |
| 3867 | 3879 | #define SQLITE_FUNCTION 31 /* NULL Function Name */ |
| 3868 | 3880 | #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ |
| 3869 | | -#define SQLITE_COPY 0 /* No longer used */ |
| 3870 | 3881 | #define SQLITE_RECURSIVE 33 /* NULL NULL */ |
| 3882 | + |
| 3883 | +/* |
| 3884 | +** Note: The SQLITE_COPY macro (with value 0) used to be one of the |
| 3885 | +** action codes above. That macro has now been repurposed as a possible |
| 3886 | +** value to the 3rd argument to sqlite3_result_str(). |
| 3887 | +*/ |
| 3871 | 3888 | |
| 3872 | 3889 | /* |
| 3873 | 3890 | ** CAPI3REF: Deprecated Tracing And Profiling Functions |
| 3874 | 3891 | ** DEPRECATED |
| 3875 | 3892 | ** |
| | @@ -4860,10 +4877,12 @@ |
| 4860 | 4877 | ** there is a small performance advantage to passing an nByte parameter that |
| 4861 | 4878 | ** is the number of bytes in the input string <i>including</i> |
| 4862 | 4879 | ** the nul-terminator. |
| 4863 | 4880 | ** Note that nByte measures the length of the input in bytes, not |
| 4864 | 4881 | ** characters, even for the UTF-16 interfaces. |
| 4882 | +** For the sqlite3_prepare16() and sqlite3_prepare16_v2() interfaces, |
| 4883 | +** the nByte value must be even or undefined behavior can result. |
| 4865 | 4884 | ** |
| 4866 | 4885 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte |
| 4867 | 4886 | ** past the end of the first SQL statement in zSql. These routines only |
| 4868 | 4887 | ** compile the first statement in zSql, so *pzTail is left pointing to |
| 4869 | 4888 | ** what remains uncompiled. |
| | @@ -5606,11 +5625,11 @@ |
| 5606 | 5625 | ** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) |
| 5607 | 5626 | ** can be obtained by calling [sqlite3_reset()] on the |
| 5608 | 5627 | ** [prepared statement]. ^In the "v2" interface, |
| 5609 | 5628 | ** the more specific error code is returned directly by sqlite3_step(). |
| 5610 | 5629 | ** |
| 5611 | | -** [SQLITE_MISUSE] means that the this routine was called inappropriately. |
| 5630 | +** [SQLITE_MISUSE] means that this routine was called inappropriately. |
| 5612 | 5631 | ** Perhaps it was called on a [prepared statement] that has |
| 5613 | 5632 | ** already been [sqlite3_finalize | finalized] or on one that had |
| 5614 | 5633 | ** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could |
| 5615 | 5634 | ** be the case that the same database connection is being used by two or |
| 5616 | 5635 | ** more threads at the same moment in time. |
| | @@ -9117,12 +9136,12 @@ |
| 9117 | 9136 | ** The lifecycle of an sqlite3_str object is as follows: |
| 9118 | 9137 | ** <ol> |
| 9119 | 9138 | ** <li> ^The sqlite3_str object is created using [sqlite3_str_new()]. |
| 9120 | 9139 | ** <li> ^Text is appended to the sqlite3_str object using various |
| 9121 | 9140 | ** methods, such as [sqlite3_str_appendf()]. |
| 9122 | | -** <li> ^The sqlite3_str object is destroyed and the string it created |
| 9123 | | -** is returned using the [sqlite3_str_finish()] interface. |
| 9141 | +** <li> The sqlite3_str object is destroyed and the string it created |
| 9142 | +** is returned using [sqlite3_str_finish()] or [sqlite3_result_str()]. |
| 9124 | 9143 | ** </ol> |
| 9125 | 9144 | */ |
| 9126 | 9145 | typedef struct sqlite3_str sqlite3_str; |
| 9127 | 9146 | |
| 9128 | 9147 | /* |
| | @@ -9170,10 +9189,44 @@ |
| 9170 | 9189 | ** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). |
| 9171 | 9190 | */ |
| 9172 | 9191 | SQLITE_API char *sqlite3_str_finish(sqlite3_str*); |
| 9173 | 9192 | SQLITE_API void sqlite3_str_free(sqlite3_str*); |
| 9174 | 9193 | |
| 9194 | +/* |
| 9195 | +** CAPI3REF: Return A Dynamic String From an SQL Function |
| 9196 | +** |
| 9197 | +** The [sqlite3_result_str(C,S,F)] interface causes the |
| 9198 | +** [sqlite3_str|dynamic string] S to become the return value for the |
| 9199 | +** application-defined function or virtual table that uses |
| 9200 | +** [sqlite3_context] C. The F flag can be one of [SQLITE_COPY] |
| 9201 | +** or [SQLITE_XFER] or [SQLITE_FINISH]. |
| 9202 | +** |
| 9203 | +** If the dynamic string is invalid or incomplete due to an out-of-memory |
| 9204 | +** or string-too-large error, then this routine transfers that error |
| 9205 | +** over to the SQL function. |
| 9206 | +** |
| 9207 | +** If the F argument is SQLITE_COPY, then a copy of the dynamic string |
| 9208 | +** content is made and the dynamic string object is unchanged. |
| 9209 | +** If the F argument is SQLITE_XFER, then ownership of the content |
| 9210 | +** in the dynamic is transferred to the SQL function (via a pointer copy |
| 9211 | +** rather than a string copy) and the dynamic string is reset to an |
| 9212 | +** empty string. The SQLITE_FINISH value for F works like SQLITE_RESET |
| 9213 | +** except that it also invokes the [sqlite3_str_free(S)] destructor |
| 9214 | +** on the dynamic string object. |
| 9215 | +*/ |
| 9216 | +SQLITE_API void sqlite3_result_str(sqlite3_context*, sqlite3_str*, int); |
| 9217 | + |
| 9218 | +/* |
| 9219 | +** CAPI3REF: Control Flags For sqlite3_result_str() |
| 9220 | +** |
| 9221 | +** The following integers can be used as the third "F" argument |
| 9222 | +** to [sqlite3_result_str(C,S,F)]. |
| 9223 | +*/ |
| 9224 | +#define SQLITE_COPY 0 /* Results copied. Dynamic string unchanged */ |
| 9225 | +#define SQLITE_XFER 1 /* Results transfered. Dynamic string reset */ |
| 9226 | +#define SQLITE_FINISH 2 /* Like SQLITE_XFER, plus dynamic string freed */ |
| 9227 | + |
| 9175 | 9228 | /* |
| 9176 | 9229 | ** CAPI3REF: Add Content To A Dynamic String |
| 9177 | 9230 | ** METHOD: sqlite3_str |
| 9178 | 9231 | ** |
| 9179 | 9232 | ** These interfaces add or remove content to an sqlite3_str object |
| | @@ -17190,11 +17243,11 @@ |
| 17190 | 17243 | SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); |
| 17191 | 17244 | #endif |
| 17192 | 17245 | |
| 17193 | 17246 | SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); |
| 17194 | 17247 | SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); |
| 17195 | | -SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); |
| 17248 | +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree*, Btree*); |
| 17196 | 17249 | |
| 17197 | 17250 | SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); |
| 17198 | 17251 | |
| 17199 | 17252 | /* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR |
| 17200 | 17253 | ** of the flags shown below. |
| | @@ -17267,16 +17320,23 @@ |
| 17267 | 17320 | ** The design of the _RANGE hint is aid b-tree implementations that try |
| 17268 | 17321 | ** to prefetch content from remote machines - to provide those |
| 17269 | 17322 | ** implementations with limits on what needs to be prefetched and thereby |
| 17270 | 17323 | ** reduce network bandwidth. |
| 17271 | 17324 | ** |
| 17325 | +** BTREE_HINT_TABLECURSOR (arguments: BtCursor*) |
| 17326 | +** |
| 17327 | +** This hint is invoked on a non-covering index cursor soon after it |
| 17328 | +** is opened. The only argument is a pointer to the table cursor used to |
| 17329 | +** obtain non-covered fields from the database. |
| 17330 | +** |
| 17272 | 17331 | ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by |
| 17273 | 17332 | ** standard SQLite. The other hints are provided for extensions that use |
| 17274 | 17333 | ** the SQLite parser and code generator but substitute their own storage |
| 17275 | 17334 | ** engine. |
| 17276 | 17335 | */ |
| 17277 | 17336 | #define BTREE_HINT_RANGE 0 /* Range constraints on queries */ |
| 17337 | +#define BTREE_HINT_TABLECURSOR 1 /* Table csr associated with this index csr */ |
| 17278 | 17338 | |
| 17279 | 17339 | /* |
| 17280 | 17340 | ** Values that may be OR'd together to form the argument to the |
| 17281 | 17341 | ** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint(): |
| 17282 | 17342 | ** |
| | @@ -17332,10 +17392,13 @@ |
| 17332 | 17392 | #endif |
| 17333 | 17393 | SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); |
| 17334 | 17394 | SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); |
| 17335 | 17395 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 17336 | 17396 | SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); |
| 17397 | + #ifdef SQLITE_DEBUG |
| 17398 | +SQLITE_PRIVATE BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor*); |
| 17399 | + #endif |
| 17337 | 17400 | #endif |
| 17338 | 17401 | |
| 17339 | 17402 | SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); |
| 17340 | 17403 | SQLITE_PRIVATE int sqlite3BtreeTableMoveto( |
| 17341 | 17404 | BtCursor*, |
| | @@ -20940,16 +21003,16 @@ |
| 20940 | 21003 | bft bHasExists :1; /* Has a correlated "EXISTS (SELECT ....)" expression */ |
| 20941 | 21004 | bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */ |
| 20942 | 21005 | bft bHasWith :1; /* True if statement contains WITH */ |
| 20943 | 21006 | bft okConstFactor:1; /* OK to factor out constants */ |
| 20944 | 21007 | bft checkSchema :1; /* Causes schema cookie check after an error */ |
| 21008 | + bft usesAinc :1; /* True if pAinc is valid */ |
| 20945 | 21009 | int nRangeReg; /* Size of the temporary register block */ |
| 20946 | 21010 | int iRangeReg; /* First register in temporary register block */ |
| 20947 | 21011 | int nErr; /* Number of errors seen */ |
| 20948 | 21012 | int nTab; /* Number of previously allocated VDBE cursors */ |
| 20949 | 21013 | int nMem; /* Number of memory cells used so far */ |
| 20950 | | - int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ |
| 20951 | 21014 | int iSelfTab; /* Table associated with an index on expr, or negative |
| 20952 | 21015 | ** of the base register during check-constraint eval */ |
| 20953 | 21016 | int nNestSel; /* Number of nested SELECT statements and/or VIEWs */ |
| 20954 | 21017 | int nLabel; /* The *negative* of the number of labels used */ |
| 20955 | 21018 | int nLabelAlloc; /* Number of slots in aLabel */ |
| | @@ -20964,13 +21027,11 @@ |
| 20964 | 21027 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 20965 | 21028 | u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ |
| 20966 | 21029 | #endif |
| 20967 | 21030 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| 20968 | 21031 | int nTableLock; /* Number of locks in aTableLock */ |
| 20969 | | - TableLock *aTableLock; /* Required table locks for shared-cache mode */ |
| 20970 | 21032 | #endif |
| 20971 | | - AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ |
| 20972 | 21033 | Parse *pToplevel; /* Parse structure for main program (or NULL) */ |
| 20973 | 21034 | Table *pTriggerTab; /* Table triggers are being coded for */ |
| 20974 | 21035 | TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ |
| 20975 | 21036 | ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ |
| 20976 | 21037 | |
| | @@ -20995,10 +21056,17 @@ |
| 20995 | 21056 | } cr; |
| 20996 | 21057 | struct { /* These fields available to all other statements */ |
| 20997 | 21058 | Returning *pReturning; /* The RETURNING clause */ |
| 20998 | 21059 | } d; |
| 20999 | 21060 | } u1; |
| 21061 | + AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters. Only |
| 21062 | + ** valid if Parse.usesAinc is true */ |
| 21063 | +#ifndef SQLITE_OMIT_SHARED_CACHE |
| 21064 | + TableLock *aTableLock; /* Required table locks for shared-cache mode. Only |
| 21065 | + ** valid if Parse.nTableLock>0 */ |
| 21066 | +#endif |
| 21067 | + |
| 21000 | 21068 | |
| 21001 | 21069 | /************************************************************************ |
| 21002 | 21070 | ** Above is constant between recursions. Below is reset before and after |
| 21003 | 21071 | ** each recursion. The boundary between these two regions is determined |
| 21004 | 21072 | ** using offsetof(Parse,sLastToken) so the sLastToken field must be the |
| | @@ -22528,10 +22596,11 @@ |
| 22528 | 22596 | SQLITE_PRIVATE const unsigned char *sqlite3aEQb; |
| 22529 | 22597 | SQLITE_PRIVATE const unsigned char *sqlite3aGTb; |
| 22530 | 22598 | SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; |
| 22531 | 22599 | SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; |
| 22532 | 22600 | SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; |
| 22601 | +SQLITE_PRIVATE const sqlite3_str sqlite3OomStr; |
| 22533 | 22602 | #ifndef SQLITE_OMIT_WSD |
| 22534 | 22603 | SQLITE_PRIVATE int sqlite3PendingByte; |
| 22535 | 22604 | #endif |
| 22536 | 22605 | #endif /* SQLITE_AMALGAMATION */ |
| 22537 | 22606 | #ifdef VDBE_PROFILE |
| | @@ -22630,11 +22699,10 @@ |
| 22630 | 22699 | SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); |
| 22631 | 22700 | SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); |
| 22632 | 22701 | SQLITE_PRIVATE int sqlite3StrAccumEnlargeIfNeeded(StrAccum*, i64); |
| 22633 | 22702 | SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); |
| 22634 | 22703 | SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); |
| 22635 | | -SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); |
| 22636 | 22704 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); |
| 22637 | 22705 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| 22638 | 22706 | SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*); |
| 22639 | 22707 | SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*); |
| 22640 | 22708 | |
| | @@ -24228,10 +24296,20 @@ |
| 24228 | 24296 | ** Hash table for global functions - functions common to all |
| 24229 | 24297 | ** database connections. After initialization, this table is |
| 24230 | 24298 | ** read-only. |
| 24231 | 24299 | */ |
| 24232 | 24300 | SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; |
| 24301 | + |
| 24302 | +/* |
| 24303 | +** This singleton is an sqlite3_str object that is returned if |
| 24304 | +** sqlite3_malloc() fails to provide space for a real one. This |
| 24305 | +** sqlite3_str object accepts no new text and always returns |
| 24306 | +** an SQLITE_NOMEM error. |
| 24307 | +*/ |
| 24308 | +SQLITE_PRIVATE const sqlite3_str sqlite3OomStr = { |
| 24309 | + 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 |
| 24310 | +}; |
| 24233 | 24311 | |
| 24234 | 24312 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) |
| 24235 | 24313 | /* |
| 24236 | 24314 | ** Counter used for coverage testing. Does not come into play for |
| 24237 | 24315 | ** release builds. |
| | @@ -26947,42 +27025,42 @@ |
| 26947 | 27025 | ){ |
| 26948 | 27026 | DateTime x; |
| 26949 | 27027 | size_t i,j; |
| 26950 | 27028 | sqlite3 *db; |
| 26951 | 27029 | const char *zFmt; |
| 26952 | | - sqlite3_str sRes; |
| 27030 | + sqlite3_str *pRes; |
| 26953 | 27031 | |
| 26954 | 27032 | |
| 26955 | 27033 | if( argc==0 ) return; |
| 26956 | 27034 | zFmt = (const char*)sqlite3_value_text(argv[0]); |
| 26957 | 27035 | if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; |
| 26958 | 27036 | db = sqlite3_context_db_handle(context); |
| 26959 | | - sqlite3StrAccumInit(&sRes, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 27037 | + pRes = sqlite3_str_new(db); |
| 26960 | 27038 | |
| 26961 | 27039 | computeJD(&x); |
| 26962 | 27040 | computeYMD_HMS(&x); |
| 26963 | 27041 | for(i=j=0; zFmt[i]; i++){ |
| 26964 | 27042 | char cf; |
| 26965 | 27043 | if( zFmt[i]!='%' ) continue; |
| 26966 | | - if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j)); |
| 27044 | + if( j<i ) sqlite3_str_append(pRes, zFmt+j, (int)(i-j)); |
| 26967 | 27045 | i++; |
| 26968 | 27046 | j = i + 1; |
| 26969 | 27047 | cf = zFmt[i]; |
| 26970 | 27048 | switch( cf ){ |
| 26971 | 27049 | case 'd': /* Fall thru */ |
| 26972 | 27050 | case 'e': { |
| 26973 | | - sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); |
| 27051 | + sqlite3_str_appendf(pRes, cf=='d' ? "%02d" : "%2d", x.D); |
| 26974 | 27052 | break; |
| 26975 | 27053 | } |
| 26976 | 27054 | case 'f': { /* Fractional seconds. (Non-standard) */ |
| 26977 | 27055 | double s = x.s; |
| 26978 | 27056 | if( NEVER(s>59.999) ) s = 59.999; |
| 26979 | | - sqlite3_str_appendf(&sRes, "%06.3f", s); |
| 27057 | + sqlite3_str_appendf(pRes, "%06.3f", s); |
| 26980 | 27058 | break; |
| 26981 | 27059 | } |
| 26982 | 27060 | case 'F': { |
| 26983 | | - sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); |
| 27061 | + sqlite3_str_appendf(pRes, "%04d-%02d-%02d", x.Y, x.M, x.D); |
| 26984 | 27062 | break; |
| 26985 | 27063 | } |
| 26986 | 27064 | case 'G': /* Fall thru */ |
| 26987 | 27065 | case 'g': { |
| 26988 | 27066 | DateTime y = x; |
| | @@ -26990,85 +27068,85 @@ |
| 26990 | 27068 | /* Move y so that it is the Thursday in the same week as x */ |
| 26991 | 27069 | y.iJD += (3 - daysAfterMonday(&x))*86400000; |
| 26992 | 27070 | y.validYMD = 0; |
| 26993 | 27071 | computeYMD(&y); |
| 26994 | 27072 | if( cf=='g' ){ |
| 26995 | | - sqlite3_str_appendf(&sRes, "%02d", y.Y%100); |
| 27073 | + sqlite3_str_appendf(pRes, "%02d", y.Y%100); |
| 26996 | 27074 | }else{ |
| 26997 | | - sqlite3_str_appendf(&sRes, "%04d", y.Y); |
| 27075 | + sqlite3_str_appendf(pRes, "%04d", y.Y); |
| 26998 | 27076 | } |
| 26999 | 27077 | break; |
| 27000 | 27078 | } |
| 27001 | 27079 | case 'H': |
| 27002 | 27080 | case 'k': { |
| 27003 | | - sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); |
| 27081 | + sqlite3_str_appendf(pRes, cf=='H' ? "%02d" : "%2d", x.h); |
| 27004 | 27082 | break; |
| 27005 | 27083 | } |
| 27006 | 27084 | case 'I': /* Fall thru */ |
| 27007 | 27085 | case 'l': { |
| 27008 | 27086 | int h = x.h; |
| 27009 | 27087 | if( h>12 ) h -= 12; |
| 27010 | 27088 | if( h==0 ) h = 12; |
| 27011 | | - sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); |
| 27089 | + sqlite3_str_appendf(pRes, cf=='I' ? "%02d" : "%2d", h); |
| 27012 | 27090 | break; |
| 27013 | 27091 | } |
| 27014 | 27092 | case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */ |
| 27015 | | - sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1); |
| 27093 | + sqlite3_str_appendf(pRes,"%03d",daysAfterJan01(&x)+1); |
| 27016 | 27094 | break; |
| 27017 | 27095 | } |
| 27018 | 27096 | case 'J': { /* Julian day number. (Non-standard) */ |
| 27019 | | - sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); |
| 27097 | + sqlite3_str_appendf(pRes,"%.16g",x.iJD/86400000.0); |
| 27020 | 27098 | break; |
| 27021 | 27099 | } |
| 27022 | 27100 | case 'm': { |
| 27023 | | - sqlite3_str_appendf(&sRes,"%02d",x.M); |
| 27101 | + sqlite3_str_appendf(pRes,"%02d",x.M); |
| 27024 | 27102 | break; |
| 27025 | 27103 | } |
| 27026 | 27104 | case 'M': { |
| 27027 | | - sqlite3_str_appendf(&sRes,"%02d",x.m); |
| 27105 | + sqlite3_str_appendf(pRes,"%02d",x.m); |
| 27028 | 27106 | break; |
| 27029 | 27107 | } |
| 27030 | 27108 | case 'p': /* Fall thru */ |
| 27031 | 27109 | case 'P': { |
| 27032 | 27110 | if( x.h>=12 ){ |
| 27033 | | - sqlite3_str_append(&sRes, cf=='p' ? "PM" : "pm", 2); |
| 27111 | + sqlite3_str_append(pRes, cf=='p' ? "PM" : "pm", 2); |
| 27034 | 27112 | }else{ |
| 27035 | | - sqlite3_str_append(&sRes, cf=='p' ? "AM" : "am", 2); |
| 27113 | + sqlite3_str_append(pRes, cf=='p' ? "AM" : "am", 2); |
| 27036 | 27114 | } |
| 27037 | 27115 | break; |
| 27038 | 27116 | } |
| 27039 | 27117 | case 'R': { |
| 27040 | | - sqlite3_str_appendf(&sRes, "%02d:%02d", x.h, x.m); |
| 27118 | + sqlite3_str_appendf(pRes, "%02d:%02d", x.h, x.m); |
| 27041 | 27119 | break; |
| 27042 | 27120 | } |
| 27043 | 27121 | case 's': { |
| 27044 | 27122 | if( x.useSubsec ){ |
| 27045 | | - sqlite3_str_appendf(&sRes,"%.3f", |
| 27123 | + sqlite3_str_appendf(pRes,"%.3f", |
| 27046 | 27124 | (x.iJD - 21086676*(i64)10000000)/1000.0); |
| 27047 | 27125 | }else{ |
| 27048 | 27126 | i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); |
| 27049 | | - sqlite3_str_appendf(&sRes,"%lld",iS); |
| 27127 | + sqlite3_str_appendf(pRes,"%lld",iS); |
| 27050 | 27128 | } |
| 27051 | 27129 | break; |
| 27052 | 27130 | } |
| 27053 | 27131 | case 'S': { |
| 27054 | | - sqlite3_str_appendf(&sRes,"%02d",(int)x.s); |
| 27132 | + sqlite3_str_appendf(pRes,"%02d",(int)x.s); |
| 27055 | 27133 | break; |
| 27056 | 27134 | } |
| 27057 | 27135 | case 'T': { |
| 27058 | | - sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); |
| 27136 | + sqlite3_str_appendf(pRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); |
| 27059 | 27137 | break; |
| 27060 | 27138 | } |
| 27061 | 27139 | case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */ |
| 27062 | 27140 | case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */ |
| 27063 | 27141 | char c = (char)daysAfterSunday(&x) + '0'; |
| 27064 | 27142 | if( c=='0' && cf=='u' ) c = '7'; |
| 27065 | | - sqlite3_str_appendchar(&sRes, 1, c); |
| 27143 | + sqlite3_str_appendchar(pRes, 1, c); |
| 27066 | 27144 | break; |
| 27067 | 27145 | } |
| 27068 | 27146 | case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */ |
| 27069 | | - sqlite3_str_appendf(&sRes,"%02d", |
| 27147 | + sqlite3_str_appendf(pRes,"%02d", |
| 27070 | 27148 | (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7); |
| 27071 | 27149 | break; |
| 27072 | 27150 | } |
| 27073 | 27151 | case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */ |
| 27074 | 27152 | DateTime y = x; |
| | @@ -27075,34 +27153,34 @@ |
| 27075 | 27153 | /* Adjust y so that is the Thursday in the same week as x */ |
| 27076 | 27154 | assert( y.validJD ); |
| 27077 | 27155 | y.iJD += (3 - daysAfterMonday(&x))*86400000; |
| 27078 | 27156 | y.validYMD = 0; |
| 27079 | 27157 | computeYMD(&y); |
| 27080 | | - sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1); |
| 27158 | + sqlite3_str_appendf(pRes,"%02d", daysAfterJan01(&y)/7+1); |
| 27081 | 27159 | break; |
| 27082 | 27160 | } |
| 27083 | 27161 | case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */ |
| 27084 | | - sqlite3_str_appendf(&sRes,"%02d", |
| 27162 | + sqlite3_str_appendf(pRes,"%02d", |
| 27085 | 27163 | (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7); |
| 27086 | 27164 | break; |
| 27087 | 27165 | } |
| 27088 | 27166 | case 'Y': { |
| 27089 | | - sqlite3_str_appendf(&sRes,"%04d",x.Y); |
| 27167 | + sqlite3_str_appendf(pRes,"%04d",x.Y); |
| 27090 | 27168 | break; |
| 27091 | 27169 | } |
| 27092 | 27170 | case '%': { |
| 27093 | | - sqlite3_str_appendchar(&sRes, 1, '%'); |
| 27171 | + sqlite3_str_appendchar(pRes, 1, '%'); |
| 27094 | 27172 | break; |
| 27095 | 27173 | } |
| 27096 | 27174 | default: { |
| 27097 | | - sqlite3_str_reset(&sRes); |
| 27175 | + sqlite3_str_free(pRes); |
| 27098 | 27176 | return; |
| 27099 | 27177 | } |
| 27100 | 27178 | } |
| 27101 | 27179 | } |
| 27102 | | - if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j)); |
| 27103 | | - sqlite3ResultStrAccum(context, &sRes); |
| 27180 | + if( j<i ) sqlite3_str_append(pRes, zFmt+j, (int)(i-j)); |
| 27181 | + sqlite3_result_str(context, pRes, SQLITE_FINISH); |
| 27104 | 27182 | } |
| 27105 | 27183 | |
| 27106 | 27184 | /* |
| 27107 | 27185 | ** current_time() |
| 27108 | 27186 | ** |
| | @@ -27234,11 +27312,11 @@ |
| 27234 | 27312 | clearYMD_HMS_TZ(&d1); |
| 27235 | 27313 | computeYMD_HMS(&d1); |
| 27236 | 27314 | sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); |
| 27237 | 27315 | sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", |
| 27238 | 27316 | sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); |
| 27239 | | - sqlite3ResultStrAccum(context, &sRes); |
| 27317 | + sqlite3_result_str(context, &sRes, SQLITE_XFER); |
| 27240 | 27318 | } |
| 27241 | 27319 | |
| 27242 | 27320 | |
| 27243 | 27321 | /* |
| 27244 | 27322 | ** current_timestamp() |
| | @@ -27662,11 +27740,11 @@ |
| 27662 | 27740 | if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ |
| 27663 | 27741 | rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); |
| 27664 | 27742 | }else{ |
| 27665 | 27743 | double r; |
| 27666 | 27744 | rc = pVfs->xCurrentTime(pVfs, &r); |
| 27667 | | - *pTimeOut = (sqlite3_int64)(r*86400000.0); |
| 27745 | + *pTimeOut = sqlite3RealToI64(r*86400000.0); |
| 27668 | 27746 | } |
| 27669 | 27747 | return rc; |
| 27670 | 27748 | } |
| 27671 | 27749 | |
| 27672 | 27750 | SQLITE_PRIVATE int sqlite3OsOpenMalloc( |
| | @@ -32612,10 +32690,14 @@ |
| 32612 | 32690 | */ |
| 32613 | 32691 | #ifndef SQLITE_PRINTF_PRECISION_LIMIT |
| 32614 | 32692 | # define SQLITE_FP_PRECISION_LIMIT 100000000 |
| 32615 | 32693 | #endif |
| 32616 | 32694 | |
| 32695 | +/* Forward reference */ |
| 32696 | +static void sqlite3StrAppend64(sqlite3_str *p, const char *z, i64 N); |
| 32697 | +static void sqlite3StrAppendchar64(sqlite3_str *p, i64 N, char c); |
| 32698 | + |
| 32617 | 32699 | /* |
| 32618 | 32700 | ** Render a string given by "fmt" into the StrAccum object. |
| 32619 | 32701 | */ |
| 32620 | 32702 | SQLITE_API void sqlite3_str_vappendf( |
| 32621 | 32703 | sqlite3_str *pAccum, /* Accumulate results here */ |
| | @@ -32622,14 +32704,14 @@ |
| 32622 | 32704 | const char *fmt, /* Format string */ |
| 32623 | 32705 | va_list ap /* arguments */ |
| 32624 | 32706 | ){ |
| 32625 | 32707 | int c; /* Next character in the format string */ |
| 32626 | 32708 | char *bufpt; /* Pointer to the conversion buffer */ |
| 32627 | | - int precision; /* Precision of the current field */ |
| 32628 | | - int length; /* Length of the field */ |
| 32709 | + i64 precision; /* Precision of the current field */ |
| 32710 | + i64 length; /* Length of the field */ |
| 32629 | 32711 | int idx; /* A general purpose loop counter */ |
| 32630 | | - int width; /* Width of the current field */ |
| 32712 | + i64 width; /* Width of the current field */ |
| 32631 | 32713 | etByte flag_leftjustify; /* True if "-" flag is present */ |
| 32632 | 32714 | etByte flag_prefix; /* '+' or ' ' or 0 for prefix */ |
| 32633 | 32715 | etByte flag_alternateform; /* True if "#" flag is present */ |
| 32634 | 32716 | etByte flag_altform2; /* True if "!" flag is present */ |
| 32635 | 32717 | etByte flag_zeropad; /* True if field width constant starts with zero */ |
| | @@ -32673,11 +32755,11 @@ |
| 32673 | 32755 | fmt = strchr(fmt, '%'); |
| 32674 | 32756 | if( fmt==0 ){ |
| 32675 | 32757 | fmt = bufpt + strlen(bufpt); |
| 32676 | 32758 | } |
| 32677 | 32759 | #endif |
| 32678 | | - sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); |
| 32760 | + sqlite3StrAppend64(pAccum, bufpt, fmt - bufpt); |
| 32679 | 32761 | if( *fmt==0 ) break; |
| 32680 | 32762 | } |
| 32681 | 32763 | if( (c=(*++fmt))==0 ){ |
| 32682 | 32764 | sqlite3_str_append(pAccum, "%", 1); |
| 32683 | 32765 | break; |
| | @@ -32919,26 +33001,27 @@ |
| 32919 | 33001 | do{ /* Convert to ascii */ |
| 32920 | 33002 | *(--bufpt) = cset[longvalue%base]; |
| 32921 | 33003 | longvalue = longvalue/base; |
| 32922 | 33004 | }while( longvalue>0 ); |
| 32923 | 33005 | } |
| 32924 | | - length = (int)(&zOut[nOut-1]-bufpt); |
| 33006 | + length = &zOut[nOut-1] - bufpt; |
| 32925 | 33007 | if( precision>length ){ /* zero pad */ |
| 32926 | | - int nn = precision-length; |
| 33008 | + i64 nn = precision-length; |
| 32927 | 33009 | bufpt -= nn; |
| 32928 | 33010 | memset(bufpt,'0',nn); |
| 32929 | 33011 | length = precision; |
| 32930 | 33012 | } |
| 32931 | 33013 | if( cThousand ){ |
| 32932 | | - int nn = (length - 1)/3; /* Number of "," to insert */ |
| 32933 | | - int ix = (length - 1)%3 + 1; |
| 33014 | + i64 nn = (length - 1)/3; /* Number of "," to insert */ |
| 33015 | + i64 ix = (length - 1)%3 + 1; |
| 33016 | + int ii; |
| 32934 | 33017 | bufpt -= nn; |
| 32935 | | - for(idx=0; nn>0; idx++){ |
| 32936 | | - bufpt[idx] = bufpt[idx+nn]; |
| 33018 | + for(ii=0; nn>0; ii++){ |
| 33019 | + bufpt[ii] = bufpt[ii+nn]; |
| 32937 | 33020 | ix--; |
| 32938 | 33021 | if( ix==0 ){ |
| 32939 | | - bufpt[++idx] = cThousand; |
| 33022 | + bufpt[++ii] = cThousand; |
| 32940 | 33023 | nn--; |
| 32941 | 33024 | ix = 3; |
| 32942 | 33025 | } |
| 32943 | 33026 | } |
| 32944 | 33027 | } |
| | @@ -32947,11 +33030,11 @@ |
| 32947 | 33030 | const char *pre; |
| 32948 | 33031 | char x; |
| 32949 | 33032 | pre = &aPrefix[infop->prefix]; |
| 32950 | 33033 | for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; |
| 32951 | 33034 | } |
| 32952 | | - length = (int)(&zOut[nOut-1]-bufpt); |
| 33035 | + length = &zOut[nOut-1] - bufpt; |
| 32953 | 33036 | break; |
| 32954 | 33037 | case etFLOAT: |
| 32955 | 33038 | case etEXP: |
| 32956 | 33039 | case etGENERIC: { |
| 32957 | 33040 | FpDecode s; |
| | @@ -32979,12 +33062,17 @@ |
| 32979 | 33062 | iRound = precision+1; |
| 32980 | 33063 | } |
| 32981 | 33064 | sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 20 : 16); |
| 32982 | 33065 | if( s.isSpecial ){ |
| 32983 | 33066 | if( s.isSpecial==2 ){ |
| 32984 | | - bufpt = flag_zeropad ? "null" : "NaN"; |
| 32985 | | - length = sqlite3Strlen30(bufpt); |
| 33067 | + if( flag_zeropad ){ |
| 33068 | + bufpt = "null"; |
| 33069 | + length = 4; |
| 33070 | + }else{ |
| 33071 | + bufpt = "NaN"; |
| 33072 | + length = 3; |
| 33073 | + } |
| 32986 | 33074 | break; |
| 32987 | 33075 | }else if( flag_zeropad ){ |
| 32988 | 33076 | s.z[0] = '9'; |
| 32989 | 33077 | s.iDP = 1000; |
| 32990 | 33078 | s.n = 1; |
| | @@ -32996,11 +33084,11 @@ |
| 32996 | 33084 | }else if( flag_prefix ){ |
| 32997 | 33085 | buf[0] = flag_prefix; |
| 32998 | 33086 | }else{ |
| 32999 | 33087 | bufpt++; |
| 33000 | 33088 | } |
| 33001 | | - length = sqlite3Strlen30(bufpt); |
| 33089 | + length = strlen(bufpt); |
| 33002 | 33090 | break; |
| 33003 | 33091 | } |
| 33004 | 33092 | } |
| 33005 | 33093 | if( s.sign=='-' ){ |
| 33006 | 33094 | if( flag_alternateform |
| | @@ -33152,11 +33240,11 @@ |
| 33152 | 33240 | } |
| 33153 | 33241 | *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ |
| 33154 | 33242 | *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ |
| 33155 | 33243 | } |
| 33156 | 33244 | |
| 33157 | | - length = (int)(bufpt-zOut); |
| 33245 | + length = bufpt - zOut; |
| 33158 | 33246 | assert( length <= szBufNeeded ); |
| 33159 | 33247 | if( length<width ){ |
| 33160 | 33248 | i64 nPad = width - length; |
| 33161 | 33249 | if( flag_leftjustify ){ |
| 33162 | 33250 | memset(bufpt, ' ', nPad); |
| | @@ -33172,10 +33260,11 @@ |
| 33172 | 33260 | } |
| 33173 | 33261 | |
| 33174 | 33262 | if( zExtra==0 ){ |
| 33175 | 33263 | /* The result is being rendered directory into pAccum. This |
| 33176 | 33264 | ** is the common and fast case */ |
| 33265 | + assert( pAccum->nChar + length < SMXV(pAccum->nChar) ); |
| 33177 | 33266 | pAccum->nChar += length; |
| 33178 | 33267 | zOut[length] = 0; |
| 33179 | 33268 | continue; |
| 33180 | 33269 | }else{ |
| 33181 | 33270 | /* We were unable to render directly into pAccum because we |
| | @@ -33218,14 +33307,14 @@ |
| 33218 | 33307 | } |
| 33219 | 33308 | if( precision>1 ){ |
| 33220 | 33309 | i64 nPrior = 1; |
| 33221 | 33310 | width -= precision-1; |
| 33222 | 33311 | if( width>1 && !flag_leftjustify ){ |
| 33223 | | - sqlite3_str_appendchar(pAccum, width-1, ' '); |
| 33312 | + sqlite3StrAppendchar64(pAccum, width-1, ' '); |
| 33224 | 33313 | width = 0; |
| 33225 | 33314 | } |
| 33226 | | - sqlite3_str_append(pAccum, buf, length); |
| 33315 | + sqlite3StrAppend64(pAccum, buf, length); |
| 33227 | 33316 | precision--; |
| 33228 | 33317 | while( precision > 1 ){ |
| 33229 | 33318 | i64 nCopyBytes; |
| 33230 | 33319 | if( nPrior > precision-1 ) nPrior = precision - 1; |
| 33231 | 33320 | nCopyBytes = length*nPrior; |
| | @@ -33277,21 +33366,21 @@ |
| 33277 | 33366 | ** precision characters */ |
| 33278 | 33367 | unsigned char *z = (unsigned char*)bufpt; |
| 33279 | 33368 | while( precision-- > 0 && z[0] ){ |
| 33280 | 33369 | SQLITE_SKIP_UTF8(z); |
| 33281 | 33370 | } |
| 33282 | | - length = (int)(z - (unsigned char*)bufpt); |
| 33371 | + length = z - (unsigned char*)bufpt; |
| 33283 | 33372 | }else{ |
| 33284 | 33373 | for(length=0; length<precision && bufpt[length]; length++){} |
| 33285 | 33374 | } |
| 33286 | 33375 | }else{ |
| 33287 | | - length = 0x7fffffff & (int)strlen(bufpt); |
| 33376 | + length = strlen(bufpt); |
| 33288 | 33377 | } |
| 33289 | 33378 | adjust_width_for_utf8: |
| 33290 | 33379 | if( flag_altform2 && width>0 ){ |
| 33291 | 33380 | /* Adjust width to account for extra bytes in UTF-8 characters */ |
| 33292 | | - int ii = length - 1; |
| 33381 | + i64 ii = length - 1; |
| 33293 | 33382 | while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; |
| 33294 | 33383 | } |
| 33295 | 33384 | break; |
| 33296 | 33385 | case etESCAPE_j: /* %j: JSON string literal w/o "..." */ |
| 33297 | 33386 | case etESCAPE_J: { /* %J: Generate a JSON string literal */ |
| | @@ -33322,11 +33411,11 @@ |
| 33322 | 33411 | while( (escarg[px]&0xc0)==0x80 ) px++; |
| 33323 | 33412 | } |
| 33324 | 33413 | } |
| 33325 | 33414 | for(i=j=0; i<px; i++){ |
| 33326 | 33415 | if( (ch = ((u8*)escarg)[i])<=0x1f || ch=='"' || ch=='\\' ){ |
| 33327 | | - if( j<i ) sqlite3_str_append(pAccum, &escarg[j], i-j); |
| 33416 | + if( j<i ) sqlite3StrAppend64(pAccum, &escarg[j], i-j); |
| 33328 | 33417 | j = i+1; |
| 33329 | 33418 | if( ch==0 ) break; |
| 33330 | 33419 | sqlite3_str_appendchar(pAccum, 1, '\\'); |
| 33331 | 33420 | if( ch>0x1f ){ |
| 33332 | 33421 | sqlite3_str_appendchar(pAccum, 1, ch); |
| | @@ -33338,11 +33427,11 @@ |
| 33338 | 33427 | sqlite3_str_appendchar(pAccum, 1, aHex[ch>>4]); |
| 33339 | 33428 | sqlite3_str_appendchar(pAccum, 1, aHex[ch&0xf]); |
| 33340 | 33429 | } |
| 33341 | 33430 | } |
| 33342 | 33431 | } |
| 33343 | | - if( j<i ) sqlite3_str_append(pAccum, &escarg[j], i-j); |
| 33432 | + if( j<i ) sqlite3StrAppend64(pAccum, &escarg[j], i-j); |
| 33344 | 33433 | if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "\"", 1); |
| 33345 | 33434 | } |
| 33346 | 33435 | if( width>0 && sqlite3_str_errcode(pAccum)==SQLITE_OK ){ |
| 33347 | 33436 | sqlite3_int64 n = sqlite3_str_length(pAccum) - iStart; |
| 33348 | 33437 | sqlite3_int64 len = n; |
| | @@ -33354,11 +33443,11 @@ |
| 33354 | 33443 | } |
| 33355 | 33444 | } |
| 33356 | 33445 | if( width>len ){ |
| 33357 | 33446 | sqlite3_int64 sp = width-len; |
| 33358 | 33447 | assert( sp>0 && sp<0x7fffffff ); |
| 33359 | | - sqlite3_str_appendchar(pAccum, (int)sp, ' '); |
| 33448 | + sqlite3StrAppendchar64(pAccum, (int)sp, ' '); |
| 33360 | 33449 | if( !flag_leftjustify |
| 33361 | 33450 | && n>0 |
| 33362 | 33451 | && sqlite3_str_errcode(pAccum)==0 |
| 33363 | 33452 | ){ |
| 33364 | 33453 | zz = sqlite3_str_value(pAccum); |
| | @@ -33546,15 +33635,15 @@ |
| 33546 | 33635 | ** indicating that width and precision should be expressed in characters, |
| 33547 | 33636 | ** then the values have been translated prior to reaching this point. |
| 33548 | 33637 | */ |
| 33549 | 33638 | width -= length; |
| 33550 | 33639 | if( width>0 ){ |
| 33551 | | - if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); |
| 33552 | | - sqlite3_str_append(pAccum, bufpt, length); |
| 33553 | | - if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); |
| 33640 | + if( !flag_leftjustify ) sqlite3StrAppendchar64(pAccum, width, ' '); |
| 33641 | + sqlite3StrAppend64(pAccum, bufpt, length); |
| 33642 | + if( flag_leftjustify ) sqlite3StrAppendchar64(pAccum, width, ' '); |
| 33554 | 33643 | }else{ |
| 33555 | | - sqlite3_str_append(pAccum, bufpt, length); |
| 33644 | + sqlite3StrAppend64(pAccum, bufpt, length); |
| 33556 | 33645 | } |
| 33557 | 33646 | |
| 33558 | 33647 | if( zExtra ){ |
| 33559 | 33648 | sqlite3DbFree(pAccum->db, zExtra); |
| 33560 | 33649 | zExtra = 0; |
| | @@ -33670,10 +33759,17 @@ |
| 33670 | 33759 | if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ |
| 33671 | 33760 | return; |
| 33672 | 33761 | } |
| 33673 | 33762 | while( (N--)>0 ) p->zText[p->nChar++] = c; |
| 33674 | 33763 | } |
| 33764 | +static void sqlite3StrAppendchar64(sqlite3_str *p, i64 N, char c){ |
| 33765 | + testcase( p->nChar + N > 0x7fffffff ); |
| 33766 | + if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ |
| 33767 | + return; |
| 33768 | + } |
| 33769 | + while( (N--)>0 ) p->zText[p->nChar++] = c; |
| 33770 | +} |
| 33675 | 33771 | |
| 33676 | 33772 | /* |
| 33677 | 33773 | ** The StrAccum "p" is not large enough to accept N new bytes of z[]. |
| 33678 | 33774 | ** So enlarge if first, then do the append. |
| 33679 | 33775 | ** |
| | @@ -33704,10 +33800,24 @@ |
| 33704 | 33800 | assert( p->zText ); |
| 33705 | 33801 | p->nChar += N; |
| 33706 | 33802 | memcpy(&p->zText[p->nChar-N], z, N); |
| 33707 | 33803 | } |
| 33708 | 33804 | } |
| 33805 | +static void sqlite3StrAppend64(sqlite3_str *p, const char *z, i64 N){ |
| 33806 | + assert( z!=0 || N==0 ); |
| 33807 | + assert( p->zText!=0 || p->nChar==0 || p->accError ); |
| 33808 | + assert( N>=0 ); |
| 33809 | + assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 ); |
| 33810 | + if( p->nChar+N >= (i64)p->nAlloc ){ |
| 33811 | + enlargeAndAppend(p,z,N); |
| 33812 | + }else if( N ){ |
| 33813 | + assert( p->zText ); |
| 33814 | + p->nChar += N; |
| 33815 | + memcpy(&p->zText[p->nChar-N], z, N); |
| 33816 | + } |
| 33817 | +} |
| 33818 | + |
| 33709 | 33819 | |
| 33710 | 33820 | /* |
| 33711 | 33821 | ** Append the complete text of zero-terminated string z[] to the p string. |
| 33712 | 33822 | */ |
| 33713 | 33823 | SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){ |
| | @@ -33741,41 +33851,15 @@ |
| 33741 | 33851 | } |
| 33742 | 33852 | } |
| 33743 | 33853 | return p->zText; |
| 33744 | 33854 | } |
| 33745 | 33855 | |
| 33746 | | -/* |
| 33747 | | -** Use the content of the StrAccum passed as the second argument |
| 33748 | | -** as the result of an SQL function. |
| 33749 | | -*/ |
| 33750 | | -SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context *pCtx, StrAccum *p){ |
| 33751 | | - if( p->accError ){ |
| 33752 | | - sqlite3_result_error_code(pCtx, p->accError); |
| 33753 | | - sqlite3_str_reset(p); |
| 33754 | | - }else if( isMalloced(p) ){ |
| 33755 | | - sqlite3_result_text(pCtx, p->zText, p->nChar, SQLITE_DYNAMIC); |
| 33756 | | - }else{ |
| 33757 | | - sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); |
| 33758 | | - sqlite3_str_reset(p); |
| 33759 | | - } |
| 33760 | | -} |
| 33761 | | - |
| 33762 | | -/* |
| 33763 | | -** This singleton is an sqlite3_str object that is returned if |
| 33764 | | -** sqlite3_malloc() fails to provide space for a real one. This |
| 33765 | | -** sqlite3_str object accepts no new text and always returns |
| 33766 | | -** an SQLITE_NOMEM error. |
| 33767 | | -*/ |
| 33768 | | -static sqlite3_str sqlite3OomStr = { |
| 33769 | | - 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 |
| 33770 | | -}; |
| 33771 | | - |
| 33772 | 33856 | /* Finalize a string created using sqlite3_str_new(). |
| 33773 | 33857 | */ |
| 33774 | 33858 | SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){ |
| 33775 | 33859 | char *z; |
| 33776 | | - if( p!=0 && p!=&sqlite3OomStr ){ |
| 33860 | + if( p!=0 && p!=(sqlite3_str*)&sqlite3OomStr ){ |
| 33777 | 33861 | z = sqlite3StrAccumFinish(p); |
| 33778 | 33862 | sqlite3_free(p); |
| 33779 | 33863 | }else{ |
| 33780 | 33864 | z = 0; |
| 33781 | 33865 | } |
| | @@ -33812,10 +33896,12 @@ |
| 33812 | 33896 | */ |
| 33813 | 33897 | SQLITE_API void sqlite3_str_reset(StrAccum *p){ |
| 33814 | 33898 | if( isMalloced(p) ){ |
| 33815 | 33899 | sqlite3DbFree(p->db, p->zText); |
| 33816 | 33900 | p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; |
| 33901 | + }else if( p==(sqlite3_str*)&sqlite3OomStr ){ |
| 33902 | + return; |
| 33817 | 33903 | } |
| 33818 | 33904 | p->nAlloc = 0; |
| 33819 | 33905 | p->nChar = 0; |
| 33820 | 33906 | p->zText = 0; |
| 33821 | 33907 | } |
| | @@ -33823,11 +33909,11 @@ |
| 33823 | 33909 | /* |
| 33824 | 33910 | ** Destroy a dynamically allocate sqlite3_str object and all |
| 33825 | 33911 | ** of its content, all in one call. |
| 33826 | 33912 | */ |
| 33827 | 33913 | SQLITE_API void sqlite3_str_free(sqlite3_str *p){ |
| 33828 | | - if( p!=0 && p!=&sqlite3OomStr ){ |
| 33914 | + if( p!=0 && p!=(sqlite3_str*)&sqlite3OomStr ){ |
| 33829 | 33915 | sqlite3_str_reset(p); |
| 33830 | 33916 | sqlite3_free(p); |
| 33831 | 33917 | } |
| 33832 | 33918 | } |
| 33833 | 33919 | |
| | @@ -33860,11 +33946,11 @@ |
| 33860 | 33946 | sqlite3_str *p = sqlite3_malloc64(sizeof(*p)); |
| 33861 | 33947 | if( p ){ |
| 33862 | 33948 | sqlite3StrAccumInit(p, 0, 0, 0, |
| 33863 | 33949 | db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); |
| 33864 | 33950 | }else{ |
| 33865 | | - p = &sqlite3OomStr; |
| 33951 | + p = (sqlite3_str*)&sqlite3OomStr; |
| 33866 | 33952 | } |
| 33867 | 33953 | return p; |
| 33868 | 33954 | } |
| 33869 | 33955 | |
| 33870 | 33956 | /* |
| | @@ -37500,11 +37586,11 @@ |
| 37500 | 37586 | return mState; |
| 37501 | 37587 | } |
| 37502 | 37588 | } |
| 37503 | 37589 | return 0xfffffff0 | mState; |
| 37504 | 37590 | #else |
| 37505 | | - return sqlite3Atoi64(z, pResult, strlen(z), SQLITE_UTF8)==0; |
| 37591 | + return sqlite3Atoi64(zIn, pResult, strlen(zIn), SQLITE_UTF8)==0; |
| 37506 | 37592 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 37507 | 37593 | } |
| 37508 | 37594 | |
| 37509 | 37595 | /* |
| 37510 | 37596 | ** Digit pairs used to convert a U64 or I64 into text, two digits |
| | @@ -39731,20 +39817,21 @@ |
| 39731 | 39817 | i = 0; |
| 39732 | 39818 | j = 0; |
| 39733 | 39819 | while( 1 ){ |
| 39734 | 39820 | c = kvvfsHexValue[aIn[i]]; |
| 39735 | 39821 | if( c<0 ){ |
| 39736 | | - int n = 0; |
| 39737 | | - int mult = 1; |
| 39822 | + sqlite3_int64 n = 0; |
| 39823 | + sqlite3_int64 mult = 1; |
| 39738 | 39824 | c = aIn[i]; |
| 39739 | 39825 | if( c==0 ) break; |
| 39740 | 39826 | while( c>='a' && c<='z' ){ |
| 39741 | 39827 | n += (c - 'a')*mult; |
| 39828 | + if( n>nOut ) return -1 /* oversized/malformed input */; |
| 39742 | 39829 | mult *= 26; |
| 39743 | 39830 | c = aIn[++i]; |
| 39744 | 39831 | } |
| 39745 | | - if( j+n>nOut ) return -1; |
| 39832 | + if( j+n>nOut ) return -1 /* oversized/malformed input */; |
| 39746 | 39833 | memset(&aOut[j], 0, n); |
| 39747 | 39834 | j += n; |
| 39748 | 39835 | if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ |
| 39749 | 39836 | }else if( j<nOut ){ |
| 39750 | 39837 | aOut[j] = c<<4; |
| | @@ -39773,22 +39860,28 @@ |
| 39773 | 39860 | static void kvvfsDecodeJournal( |
| 39774 | 39861 | KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */ |
| 39775 | 39862 | const char *zTxt, /* Text encoding. Zero-terminated */ |
| 39776 | 39863 | int nTxt /* Bytes in zTxt, excluding zero terminator */ |
| 39777 | 39864 | ){ |
| 39778 | | - unsigned int n = 0; |
| 39779 | | - int c, i, mult; |
| 39865 | + unsigned int n = 0, mult; |
| 39866 | + int c, i; |
| 39780 | 39867 | i = 0; |
| 39781 | 39868 | mult = 1; |
| 39782 | | - while( (c = zTxt[i++])>='a' && c<='z' ){ |
| 39783 | | - n += (zTxt[i] - 'a')*mult; |
| 39869 | + sqlite3_free(pFile->aJrnl); |
| 39870 | + pFile->aJrnl = 0; |
| 39871 | + pFile->nJrnl = 0; |
| 39872 | + while( (c = zTxt[i])>='a' && c<='z' ){ |
| 39873 | + n += (c - 'a')*mult; |
| 39784 | 39874 | mult *= 26; |
| 39875 | + ++i; |
| 39785 | 39876 | } |
| 39786 | | - sqlite3_free(pFile->aJrnl); |
| 39877 | + if( ' '!=zTxt[i++] ){ |
| 39878 | + /* Malformed input */ |
| 39879 | + return; |
| 39880 | + } |
| 39787 | 39881 | pFile->aJrnl = sqlite3_malloc64( n ); |
| 39788 | 39882 | if( pFile->aJrnl==0 ){ |
| 39789 | | - pFile->nJrnl = 0; |
| 39790 | 39883 | return; |
| 39791 | 39884 | } |
| 39792 | 39885 | pFile->nJrnl = n; |
| 39793 | 39886 | n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl); |
| 39794 | 39887 | if( n<pFile->nJrnl ){ |
| | @@ -39824,13 +39917,11 @@ |
| 39824 | 39917 | |
| 39825 | 39918 | SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass, |
| 39826 | 39919 | pFile->isJournal ? "journal" : "db")); |
| 39827 | 39920 | sqlite3_free(pFile->aJrnl); |
| 39828 | 39921 | sqlite3_free(pFile->aData); |
| 39829 | | -#ifdef SQLITE_WASM |
| 39830 | 39922 | memset(pFile, 0, sizeof(*pFile)); |
| 39831 | | -#endif |
| 39832 | 39923 | return SQLITE_OK; |
| 39833 | 39924 | } |
| 39834 | 39925 | |
| 39835 | 39926 | /* |
| 39836 | 39927 | ** Read from the -journal file. |
| | @@ -39856,10 +39947,11 @@ |
| 39856 | 39947 | if( aTxt==0 ) return SQLITE_NOMEM; |
| 39857 | 39948 | rc = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "jrnl", |
| 39858 | 39949 | aTxt, szTxt+1); |
| 39859 | 39950 | if( rc>=0 ){ |
| 39860 | 39951 | kvvfsDecodeJournal(pFile, aTxt, szTxt); |
| 39952 | + rc = 0; |
| 39861 | 39953 | } |
| 39862 | 39954 | sqlite3_free(aTxt); |
| 39863 | 39955 | if( rc ) return rc; |
| 39864 | 39956 | if( pFile->aJrnl==0 ) return SQLITE_IOERR; |
| 39865 | 39957 | } |
| | @@ -40180,11 +40272,11 @@ |
| 40180 | 40272 | } |
| 40181 | 40273 | if( !pFile->zClass ){ |
| 40182 | 40274 | #ifdef SQLITE_WASM |
| 40183 | 40275 | if( strlen(zName) >= (KVRECORD_KEY_SZ |
| 40184 | 40276 | - 6 /* "kvvfs-" */ |
| 40185 | | - - 11 /* "-##########" */) ){ |
| 40277 | + - 11 /* "-NNNNNNNNNNN" */) ){ |
| 40186 | 40278 | return SQLITE_CANTOPEN; |
| 40187 | 40279 | } |
| 40188 | 40280 | #else |
| 40189 | 40281 | if( 0!=strcmp(zName, "local") && 0!=strcmp(zName, "session") ){ |
| 40190 | 40282 | /* Historical naming restriction which journaling depends on. */ |
| | @@ -52221,11 +52313,11 @@ |
| 52221 | 52313 | # define sqlite3_win_test_unc_locking 0 |
| 52222 | 52314 | #endif |
| 52223 | 52315 | |
| 52224 | 52316 | /* |
| 52225 | 52317 | ** Return true if the string passed as the only argument is likely |
| 52226 | | -** to be a UNC path. Return false if note. |
| 52318 | +** to be a UNC path. Return false if not. |
| 52227 | 52319 | ** |
| 52228 | 52320 | ** Return true if: |
| 52229 | 52321 | ** |
| 52230 | 52322 | ** (1) The name begins with "\\" |
| 52231 | 52323 | ** (2) But does not begin with "\\?\C:\" where C can be any alphabetic |
| | @@ -55070,26 +55162,27 @@ |
| 55070 | 55162 | int iDb; |
| 55071 | 55163 | Btree *pBt; |
| 55072 | 55164 | sqlite3_int64 sz; |
| 55073 | 55165 | int szPage = 0; |
| 55074 | 55166 | sqlite3_stmt *pStmt = 0; |
| 55075 | | - unsigned char *pOut; |
| 55167 | + unsigned char *pOut = 0; |
| 55076 | 55168 | char *zSql; |
| 55077 | 55169 | int rc; |
| 55078 | 55170 | |
| 55079 | 55171 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 55080 | 55172 | if( !sqlite3SafetyCheckOk(db) ){ |
| 55081 | 55173 | (void)SQLITE_MISUSE_BKPT; |
| 55082 | 55174 | return 0; |
| 55083 | 55175 | } |
| 55084 | 55176 | #endif |
| 55177 | + sqlite3_mutex_enter(db->mutex); |
| 55085 | 55178 | |
| 55086 | 55179 | if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; |
| 55087 | 55180 | p = memdbFromDbSchema(db, zSchema); |
| 55088 | 55181 | iDb = sqlite3FindDbName(db, zSchema); |
| 55089 | 55182 | if( piSize ) *piSize = -1; |
| 55090 | | - if( iDb<0 ) return 0; |
| 55183 | + if( iDb<0 ) goto serialize_out; |
| 55091 | 55184 | if( p ){ |
| 55092 | 55185 | MemStore *pStore = p->pStore; |
| 55093 | 55186 | assert( pStore->pMutex==0 ); |
| 55094 | 55187 | if( piSize ) *piSize = pStore->sz; |
| 55095 | 55188 | if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ |
| | @@ -55096,23 +55189,21 @@ |
| 55096 | 55189 | pOut = pStore->aData; |
| 55097 | 55190 | }else{ |
| 55098 | 55191 | pOut = sqlite3_malloc64( pStore->sz ); |
| 55099 | 55192 | if( pOut ) memcpy(pOut, pStore->aData, pStore->sz); |
| 55100 | 55193 | } |
| 55101 | | - return pOut; |
| 55194 | + goto serialize_out; |
| 55102 | 55195 | } |
| 55103 | 55196 | pBt = db->aDb[iDb].pBt; |
| 55104 | | - if( pBt==0 ) return 0; |
| 55197 | + if( pBt==0 ) goto serialize_out; |
| 55105 | 55198 | szPage = sqlite3BtreeGetPageSize(pBt); |
| 55106 | 55199 | zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); |
| 55107 | 55200 | rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; |
| 55108 | 55201 | sqlite3_free(zSql); |
| 55109 | | - if( rc ) return 0; |
| 55202 | + if( rc ) goto serialize_out; |
| 55110 | 55203 | rc = sqlite3_step(pStmt); |
| 55111 | | - if( rc!=SQLITE_ROW ){ |
| 55112 | | - pOut = 0; |
| 55113 | | - }else{ |
| 55204 | + if( rc==SQLITE_ROW ){ |
| 55114 | 55205 | sz = sqlite3_column_int64(pStmt, 0)*szPage; |
| 55115 | 55206 | if( sz==0 ){ |
| 55116 | 55207 | sqlite3_reset(pStmt); |
| 55117 | 55208 | sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0); |
| 55118 | 55209 | rc = sqlite3_step(pStmt); |
| | @@ -55142,10 +55233,13 @@ |
| 55142 | 55233 | } |
| 55143 | 55234 | } |
| 55144 | 55235 | } |
| 55145 | 55236 | } |
| 55146 | 55237 | sqlite3_finalize(pStmt); |
| 55238 | + |
| 55239 | + serialize_out: |
| 55240 | + sqlite3_mutex_leave(db->mutex); |
| 55147 | 55241 | return pOut; |
| 55148 | 55242 | } |
| 55149 | 55243 | |
| 55150 | 55244 | /* Convert zSchema to a MemDB and initialize its content. |
| 55151 | 55245 | */ |
| | @@ -59917,10 +60011,45 @@ |
| 59917 | 60011 | static void freeSuperJournal(char *zSuper){ |
| 59918 | 60012 | if( zSuper ){ |
| 59919 | 60013 | sqlite3_free(&zSuper[-4]); |
| 59920 | 60014 | } |
| 59921 | 60015 | } |
| 60016 | + |
| 60017 | +/* |
| 60018 | +** Check if zSuper is a valid super-journal name. There are two valid |
| 60019 | +** formats: |
| 60020 | +** |
| 60021 | +** + The 3rd and 4th last bytes of the filename are ".9", and the |
| 60022 | +** following 2 bytes are hex digits. This is a file created in 8.3 |
| 60023 | +** filenames mode. |
| 60024 | +** |
| 60025 | +** + The 3rd last byte of the filename is "9" and the filename |
| 60026 | +** contains the string "-mj" starting at the 12th last byte. |
| 60027 | +** All bytes following the "-mj" are hex digits. |
| 60028 | +** |
| 60029 | +** If the filename matches either of these patterns, return non-zero. |
| 60030 | +** Otherwise, return zero. |
| 60031 | +*/ |
| 60032 | +static int pagerIsSuperJrnlName(const char *zSuper){ |
| 60033 | + const int nSuper = sqlite3Strlen30(zSuper); |
| 60034 | + int ii; |
| 60035 | + |
| 60036 | +#ifdef SQLITE_ENABLE_8_3_NAMES |
| 60037 | + if( nSuper<4 ) return 0; |
| 60038 | + if( zSuper[nSuper-3]!='9' ) return 0; |
| 60039 | + if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0; |
| 60040 | + if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0; |
| 60041 | + if( zSuper[nSuper-4]=='.' ) return 1; |
| 60042 | +#endif |
| 60043 | + if( nSuper<12 ) return 0; |
| 60044 | + if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0; |
| 60045 | + if( zSuper[nSuper-3]!='9' ) return 0; |
| 60046 | + for(ii=nSuper-9; ii<nSuper; ii++){ |
| 60047 | + if( sqlite3Isxdigit(zSuper[ii])==0 ) return 0; |
| 60048 | + } |
| 60049 | + return 1; |
| 60050 | +} |
| 59922 | 60051 | |
| 59923 | 60052 | /* |
| 59924 | 60053 | ** Parameter pJrnl is a file-handle open on a journal file. This function |
| 59925 | 60054 | ** attempts to read a super-journal file name from the end of the journal |
| 59926 | 60055 | ** file. If successful, it sets output parameter (*pzSuper) to point to a |
| | @@ -59955,32 +60084,34 @@ |
| 59955 | 60084 | || len>=nSuper |
| 59956 | 60085 | || len>szJ-16 |
| 59957 | 60086 | || len==0 |
| 59958 | 60087 | || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) |
| 59959 | 60088 | || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) |
| 59960 | | - || memcmp(aMagic, aJournalMagic, 8) |
| 59961 | 60089 | ){ |
| 59962 | 60090 | return rc; |
| 59963 | 60091 | } |
| 59964 | 60092 | |
| 59965 | 60093 | zOut = (char*)sqlite3MallocZero(4 + len + 2); |
| 59966 | 60094 | if( !zOut ){ |
| 59967 | | - rc = SQLITE_NOMEM_BKPT; |
| 60095 | + rc = memcmp(aMagic,aJournalMagic,8) ? SQLITE_OK : SQLITE_NOMEM_BKPT; |
| 59968 | 60096 | }else{ |
| 59969 | 60097 | zOut = &zOut[4]; |
| 59970 | 60098 | if( SQLITE_OK==(rc = sqlite3OsRead(pJrnl, zOut, len, szJ-16-len)) ){ |
| 59971 | 60099 | u32 u; /* Unsigned loop counter */ |
| 59972 | 60100 | /* See if the checksum matches the super-journal name */ |
| 59973 | 60101 | for(u=0; u<len; u++){ |
| 59974 | 60102 | cksum -= zOut[u]; |
| 59975 | 60103 | } |
| 59976 | 60104 | } |
| 59977 | | - if( rc!=SQLITE_OK || cksum ){ |
| 59978 | | - /* If the checksum doesn't add up, then one or more of the disk sectors |
| 59979 | | - ** containing the super-journal filename is corrupted. This means |
| 59980 | | - ** definitely roll back, so just return SQLITE_OK and report a (nul) |
| 59981 | | - ** super-journal filename. */ |
| 60105 | + if( rc!=SQLITE_OK /* Couldn't read the name */ |
| 60106 | + || !pagerIsSuperJrnlName(zOut) /* Name is not valid */ |
| 60107 | + || cksum /* checksum is incorrect */ |
| 60108 | + || memcmp(aMagic, aJournalMagic, 8)!=0 /* Bad magic number */ |
| 60109 | + ){ |
| 60110 | + /* If any validity checks fail, that means the super-journal filename |
| 60111 | + ** is corrupted, so rollback. Return SQLITE_K and a NULL super-journal |
| 60112 | + ** name */ |
| 59982 | 60113 | freeSuperJournal(zOut); |
| 59983 | 60114 | zOut = 0; |
| 59984 | 60115 | } |
| 59985 | 60116 | } |
| 59986 | 60117 | |
| | @@ -60359,10 +60490,11 @@ |
| 60359 | 60490 | i64 jrnlSize; /* Size of journal file on disk */ |
| 60360 | 60491 | u32 cksum = 0; /* Checksum of string zSuper */ |
| 60361 | 60492 | |
| 60362 | 60493 | assert( pPager->setSuper==0 ); |
| 60363 | 60494 | assert( !pagerUseWal(pPager) ); |
| 60495 | + assert( zSuper==0 || pagerIsSuperJrnlName(zSuper) ); |
| 60364 | 60496 | |
| 60365 | 60497 | if( !zSuper |
| 60366 | 60498 | || pPager->journalMode==PAGER_JOURNALMODE_MEMORY |
| 60367 | 60499 | || !isOpen(pPager->jfd) |
| 60368 | 60500 | ){ |
| | @@ -61189,10 +61321,23 @@ |
| 61189 | 61321 | sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ |
| 61190 | 61322 | char *zSuperJournal = 0; /* Contents of super-journal file */ |
| 61191 | 61323 | i64 nSuperJournal; /* Size of super-journal file */ |
| 61192 | 61324 | char *zJournal; /* Pointer to one journal within MJ file */ |
| 61193 | 61325 | char *zFree = 0; /* Free this buffer */ |
| 61326 | + int bSeen = 0; /* If super-journal contains pPager->zJournal */ |
| 61327 | + |
| 61328 | + /* Check if this looks like a real super-journal name. If it does not, |
| 61329 | + ** return SQLITE_OK without attempting to delete it. This is to limit |
| 61330 | + ** the degree to which a crafted journal file can be used to cause |
| 61331 | + ** SQLite to delete arbitrary files. |
| 61332 | + ** |
| 61333 | + ** This test never fails, becaue the super journal name is checked |
| 61334 | + ** by readSuperJournal(). |
| 61335 | + */ |
| 61336 | + if( NEVER(pagerIsSuperJrnlName(zSuper)==0) ){ |
| 61337 | + return SQLITE_OK; |
| 61338 | + } |
| 61194 | 61339 | |
| 61195 | 61340 | /* Allocate space for both the pJournal and pSuper file descriptors. |
| 61196 | 61341 | ** If successful, open the super-journal file for reading. |
| 61197 | 61342 | */ |
| 61198 | 61343 | pSuper = (sqlite3_file *)sqlite3MallocZero(2 * (i64)pVfs->szOsFile); |
| | @@ -61228,51 +61373,60 @@ |
| 61228 | 61373 | zSuperJournal[nSuperJournal] = 0; |
| 61229 | 61374 | zSuperJournal[nSuperJournal+1] = 0; |
| 61230 | 61375 | |
| 61231 | 61376 | zJournal = zSuperJournal; |
| 61232 | 61377 | while( (zJournal-zSuperJournal)<nSuperJournal ){ |
| 61233 | | - int exists; |
| 61234 | | - rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); |
| 61235 | | - if( rc!=SQLITE_OK ){ |
| 61236 | | - goto delsuper_out; |
| 61237 | | - } |
| 61238 | | - if( exists ){ |
| 61239 | | - char *zSuperPtr = 0; |
| 61240 | | - |
| 61241 | | - /* One of the journals pointed to by the super-journal exists. |
| 61242 | | - ** Open it and check if it points at the super-journal. If |
| 61243 | | - ** so, return without deleting the super-journal file. |
| 61244 | | - ** NB: zJournal is really a MAIN_JOURNAL. But call it a |
| 61245 | | - ** SUPER_JOURNAL here so that the VFS will not send the zJournal |
| 61246 | | - ** name into sqlite3_database_file_object(). |
| 61247 | | - */ |
| 61248 | | - int c; |
| 61249 | | - int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); |
| 61250 | | - rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); |
| 61251 | | - if( rc!=SQLITE_OK ){ |
| 61252 | | - goto delsuper_out; |
| 61253 | | - } |
| 61254 | | - |
| 61255 | | - rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr); |
| 61256 | | - sqlite3OsClose(pJournal); |
| 61257 | | - if( rc!=SQLITE_OK ){ |
| 61258 | | - assert( zSuperPtr==0 ); |
| 61259 | | - goto delsuper_out; |
| 61260 | | - } |
| 61261 | | - |
| 61262 | | - c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0; |
| 61263 | | - freeSuperJournal(zSuperPtr); |
| 61264 | | - if( c ){ |
| 61265 | | - /* We have a match. Do not delete the super-journal file. */ |
| 61266 | | - goto delsuper_out; |
| 61378 | + if( strcmp(zJournal, pPager->zJournal)==0 ){ |
| 61379 | + bSeen = 1; |
| 61380 | + }else{ |
| 61381 | + int exists; |
| 61382 | + rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); |
| 61383 | + if( rc!=SQLITE_OK ){ |
| 61384 | + goto delsuper_out; |
| 61385 | + } |
| 61386 | + if( exists ){ |
| 61387 | + char *zSuperPtr = 0; |
| 61388 | + |
| 61389 | + /* One of the journals pointed to by the super-journal exists. |
| 61390 | + ** Open it and check if it points at the super-journal. If |
| 61391 | + ** so, return without deleting the super-journal file. |
| 61392 | + ** NB: zJournal is really a MAIN_JOURNAL. But call it a |
| 61393 | + ** SUPER_JOURNAL here so that the VFS will not send the zJournal |
| 61394 | + ** name into sqlite3_database_file_object(). |
| 61395 | + */ |
| 61396 | + int c; |
| 61397 | + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); |
| 61398 | + rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); |
| 61399 | + if( rc!=SQLITE_OK ){ |
| 61400 | + goto delsuper_out; |
| 61401 | + } |
| 61402 | + |
| 61403 | + rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr); |
| 61404 | + sqlite3OsClose(pJournal); |
| 61405 | + if( rc!=SQLITE_OK ){ |
| 61406 | + assert( zSuperPtr==0 ); |
| 61407 | + goto delsuper_out; |
| 61408 | + } |
| 61409 | + |
| 61410 | + c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0; |
| 61411 | + freeSuperJournal(zSuperPtr); |
| 61412 | + if( c ){ |
| 61413 | + /* We have a match. Do not delete the super-journal file. */ |
| 61414 | + goto delsuper_out; |
| 61415 | + } |
| 61267 | 61416 | } |
| 61268 | 61417 | } |
| 61269 | 61418 | zJournal += (sqlite3Strlen30(zJournal)+1); |
| 61270 | 61419 | } |
| 61271 | 61420 | |
| 61272 | 61421 | sqlite3OsClose(pSuper); |
| 61273 | | - rc = sqlite3OsDelete(pVfs, zSuper, 0); |
| 61422 | + if( bSeen ){ |
| 61423 | + /* Only delete the super-journal if bSeen is true - indicating that |
| 61424 | + ** the super-journal contained a pointer to this database's journal |
| 61425 | + ** file. */ |
| 61426 | + rc = sqlite3OsDelete(pVfs, zSuper, 0); |
| 61427 | + } |
| 61274 | 61428 | |
| 61275 | 61429 | delsuper_out: |
| 61276 | 61430 | sqlite3_free(zFree); |
| 61277 | 61431 | if( pSuper ){ |
| 61278 | 61432 | sqlite3OsClose(pSuper); |
| | @@ -71674,10 +71828,13 @@ |
| 71674 | 71828 | int skipNext; /* Prev() is noop if negative. Next() is noop if positive. |
| 71675 | 71829 | ** Error code if eState==CURSOR_FAULT */ |
| 71676 | 71830 | Btree *pBtree; /* The Btree to which this cursor belongs */ |
| 71677 | 71831 | Pgno *aOverflow; /* Cache of overflow page locations */ |
| 71678 | 71832 | void *pKey; /* Saved key that was cursor last known position */ |
| 71833 | +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) |
| 71834 | + BtCursor *pCursorHintTableCursor; |
| 71835 | +#endif |
| 71679 | 71836 | /* All fields above are zeroed when the cursor is allocated. See |
| 71680 | 71837 | ** sqlite3BtreeCursorZero(). Fields that follow must be manually |
| 71681 | 71838 | ** initialized. */ |
| 71682 | 71839 | #define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */ |
| 71683 | 71840 | BtShared *pBt; /* The BtShared this cursor points to */ |
| | @@ -71850,10 +72007,13 @@ |
| 71850 | 72007 | int v2; /* Value for third %d substitution in zPfx */ |
| 71851 | 72008 | StrAccum errMsg; /* Accumulate the error message text here */ |
| 71852 | 72009 | u32 *heap; /* Min-heap used for analyzing cell coverage */ |
| 71853 | 72010 | sqlite3 *db; /* Database connection running the check */ |
| 71854 | 72011 | i64 nRow; /* Number of rows visited in current tree */ |
| 72012 | +#ifdef SQLITE_DEBUG |
| 72013 | + u32 mxHeap; /* Maximum number of entries in the Min-heap */ |
| 72014 | +#endif |
| 71855 | 72015 | }; |
| 71856 | 72016 | |
| 71857 | 72017 | /* |
| 71858 | 72018 | ** Routines to read or write a two- and four-byte big-endian integer values. |
| 71859 | 72019 | */ |
| | @@ -73178,28 +73338,45 @@ |
| 73178 | 73338 | ** parameter. See the definitions of the BTREE_HINT_* macros for details. |
| 73179 | 73339 | */ |
| 73180 | 73340 | SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ |
| 73181 | 73341 | /* Used only by system that substitute their own storage engine */ |
| 73182 | 73342 | #ifdef SQLITE_DEBUG |
| 73183 | | - if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ |
| 73184 | | - va_list ap; |
| 73343 | + va_list ap; |
| 73344 | + va_start(ap, eHintType); |
| 73345 | + if( eHintType==BTREE_HINT_RANGE ){ |
| 73185 | 73346 | Expr *pExpr; |
| 73186 | 73347 | Walker w; |
| 73187 | 73348 | memset(&w, 0, sizeof(w)); |
| 73188 | 73349 | w.xExprCallback = sqlite3CursorRangeHintExprCheck; |
| 73189 | | - va_start(ap, eHintType); |
| 73190 | 73350 | pExpr = va_arg(ap, Expr*); |
| 73191 | 73351 | w.u.aMem = va_arg(ap, Mem*); |
| 73192 | | - va_end(ap); |
| 73193 | 73352 | assert( pExpr!=0 ); |
| 73194 | 73353 | assert( w.u.aMem!=0 ); |
| 73195 | 73354 | sqlite3WalkExpr(&w, pExpr); |
| 73355 | + }else if( ALWAYS(eHintType==BTREE_HINT_TABLECURSOR) ){ |
| 73356 | + BtCursor *pCsr = va_arg(ap, BtCursor*); |
| 73357 | + assert( pCur->pCursorHintTableCursor==0 |
| 73358 | + || pCur->pCursorHintTableCursor==pCsr |
| 73359 | + ); |
| 73360 | + assert( pCsr->pKeyInfo==0 || CORRUPT_DB ); |
| 73361 | + pCur->pCursorHintTableCursor = pCsr; |
| 73196 | 73362 | } |
| 73363 | + va_end(ap); |
| 73197 | 73364 | #endif /* SQLITE_DEBUG */ |
| 73198 | 73365 | } |
| 73199 | 73366 | #endif /* SQLITE_ENABLE_CURSOR_HINTS */ |
| 73200 | 73367 | |
| 73368 | +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) |
| 73369 | +/* |
| 73370 | +** Return the pointer configured via the BTREE_HINT_TABLECURSOR hint on |
| 73371 | +** cursor pCsr. This is used from OP_DeferredSeek to assert() that the |
| 73372 | +** index cursor has been correctly configured with the table cursor. |
| 73373 | +*/ |
| 73374 | +SQLITE_PRIVATE BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor *pCsr){ |
| 73375 | + return pCsr->pCursorHintTableCursor; |
| 73376 | +} |
| 73377 | +#endif |
| 73201 | 73378 | |
| 73202 | 73379 | /* |
| 73203 | 73380 | ** Provide flag hints to the cursor. |
| 73204 | 73381 | */ |
| 73205 | 73382 | SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ |
| | @@ -74321,12 +74498,16 @@ |
| 74321 | 74498 | /* Freeblock off the end of the page */ |
| 74322 | 74499 | return SQLITE_CORRUPT_PAGE(pPage); |
| 74323 | 74500 | } |
| 74324 | 74501 | next = get2byte(&data[pc]); |
| 74325 | 74502 | size = get2byte(&data[pc+2]); |
| 74503 | + if( size<4 ){ |
| 74504 | + /* Minimum freeblock size is 4 */ |
| 74505 | + return SQLITE_CORRUPT_PAGE(pPage); |
| 74506 | + } |
| 74326 | 74507 | nFree = nFree + size; |
| 74327 | | - if( next<=pc+size+3 ) break; |
| 74508 | + if( next<pc+size+4 ) break; |
| 74328 | 74509 | pc = next; |
| 74329 | 74510 | } |
| 74330 | 74511 | if( next>0 ){ |
| 74331 | 74512 | /* Freeblock not in ascending order */ |
| 74332 | 74513 | return SQLITE_CORRUPT_PAGE(pPage); |
| | @@ -78157,18 +78338,18 @@ |
| 78157 | 78338 | nCell = pCell[0]; |
| 78158 | 78339 | if( nCell<=pPage->max1bytePayload ){ |
| 78159 | 78340 | /* This branch runs if the record-size field of the cell is a |
| 78160 | 78341 | ** single byte varint and the record fits entirely on the main |
| 78161 | 78342 | ** b-tree page. */ |
| 78162 | | - testcase( pCell+nCell+1==pPage->aDataEnd ); |
| 78343 | + if( pCell + nCell >= pPage->aDataEnd ) return 99; |
| 78163 | 78344 | c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); |
| 78164 | 78345 | }else if( !(pCell[1] & 0x80) |
| 78165 | 78346 | && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal |
| 78166 | 78347 | ){ |
| 78167 | 78348 | /* The record-size field is a 2 byte varint and the record |
| 78168 | 78349 | ** fits entirely on the main b-tree page. */ |
| 78169 | | - testcase( pCell+nCell+2==pPage->aDataEnd ); |
| 78350 | + if( pCell + nCell >= pPage->aDataEnd ) return 99; |
| 78170 | 78351 | c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); |
| 78171 | 78352 | }else{ |
| 78172 | 78353 | /* If the record extends into overflow pages, do not attempt |
| 78173 | 78354 | ** the optimization. */ |
| 78174 | 78355 | c = 99; |
| | @@ -78326,18 +78507,21 @@ |
| 78326 | 78507 | nCell = pCell[0]; |
| 78327 | 78508 | if( nCell<=pPage->max1bytePayload ){ |
| 78328 | 78509 | /* This branch runs if the record-size field of the cell is a |
| 78329 | 78510 | ** single byte varint and the record fits entirely on the main |
| 78330 | 78511 | ** b-tree page. */ |
| 78331 | | - testcase( pCell+nCell+1==pPage->aDataEnd ); |
| 78512 | + if( pCell + nCell >= pPage->aDataEnd ){ |
| 78513 | + rc = SQLITE_CORRUPT_PAGE(pPage); |
| 78514 | + goto moveto_index_finish; |
| 78515 | + } |
| 78332 | 78516 | c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); |
| 78333 | 78517 | }else if( !(pCell[1] & 0x80) |
| 78334 | 78518 | && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal |
| 78519 | + && pCell + nCell < pPage->aDataEnd |
| 78335 | 78520 | ){ |
| 78336 | 78521 | /* The record-size field is a 2 byte varint and the record |
| 78337 | 78522 | ** fits entirely on the main b-tree page. */ |
| 78338 | | - testcase( pCell+nCell+2==pPage->aDataEnd ); |
| 78339 | 78523 | c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); |
| 78340 | 78524 | }else{ |
| 78341 | 78525 | /* The record flows over onto one or more overflow pages. In |
| 78342 | 78526 | ** this case the whole cell needs to be parsed, a buffer allocated |
| 78343 | 78527 | ** and accessPayload() used to retrieve the record into the |
| | @@ -83203,10 +83387,11 @@ |
| 83203 | 83387 | checkAppendMsg(pCheck, "Child page depth differs"); |
| 83204 | 83388 | depth = d2; |
| 83205 | 83389 | } |
| 83206 | 83390 | }else{ |
| 83207 | 83391 | /* Populate the coverage-checking heap for leaf pages */ |
| 83392 | + assert( heap[0] < pCheck->mxHeap ); |
| 83208 | 83393 | btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); |
| 83209 | 83394 | } |
| 83210 | 83395 | } |
| 83211 | 83396 | *piMinKey = maxKey; |
| 83212 | 83397 | |
| | @@ -83222,10 +83407,11 @@ |
| 83222 | 83407 | heap[0] = 0; |
| 83223 | 83408 | for(i=nCell-1; i>=0; i--){ |
| 83224 | 83409 | u32 size; |
| 83225 | 83410 | pc = get2byteAligned(&data[cellStart+i*2]); |
| 83226 | 83411 | size = pPage->xCellSize(pPage, &data[pc]); |
| 83412 | + assert( heap[0] < pCheck->mxHeap ); |
| 83227 | 83413 | btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); |
| 83228 | 83414 | } |
| 83229 | 83415 | } |
| 83230 | 83416 | assert( heap!=0 ); |
| 83231 | 83417 | /* Add the freeblocks to the min-heap |
| | @@ -83238,10 +83424,11 @@ |
| 83238 | 83424 | while( i>0 ){ |
| 83239 | 83425 | int size, j; |
| 83240 | 83426 | assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ |
| 83241 | 83427 | size = get2byte(&data[i+2]); |
| 83242 | 83428 | assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */ |
| 83429 | + assert( heap[0] < pCheck->mxHeap ); |
| 83243 | 83430 | btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1)); |
| 83244 | 83431 | /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a |
| 83245 | 83432 | ** big-endian integer which is the offset in the b-tree page of the next |
| 83246 | 83433 | ** freeblock in the chain, or zero if the freeblock is the last on the |
| 83247 | 83434 | ** chain. */ |
| | @@ -83372,10 +83559,13 @@ |
| 83372 | 83559 | if( !sCheck.aPgRef ){ |
| 83373 | 83560 | checkOom(&sCheck); |
| 83374 | 83561 | goto integrity_ck_cleanup; |
| 83375 | 83562 | } |
| 83376 | 83563 | sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); |
| 83564 | +#ifdef SQLITE_DEBUG |
| 83565 | + sCheck.mxHeap = pBt->pageSize/4 - 1; |
| 83566 | +#endif |
| 83377 | 83567 | if( sCheck.heap==0 ){ |
| 83378 | 83568 | checkOom(&sCheck); |
| 83379 | 83569 | goto integrity_ck_cleanup; |
| 83380 | 83570 | } |
| 83381 | 83571 | |
| | @@ -83796,17 +83986,18 @@ |
| 83796 | 83986 | /* |
| 83797 | 83987 | ** Structure allocated for each backup operation. |
| 83798 | 83988 | */ |
| 83799 | 83989 | struct sqlite3_backup { |
| 83800 | 83990 | sqlite3* pDestDb; /* Destination database handle */ |
| 83801 | | - Db *pDest; /* Destination db file */ |
| 83991 | + char *zDestDb; |
| 83992 | + Btree *pDest; /* Destination b-tree file */ |
| 83802 | 83993 | u32 iDestSchema; /* Original schema cookie in destination */ |
| 83803 | 83994 | int bDestLocked; /* True once a write-transaction is open on pDest */ |
| 83804 | 83995 | |
| 83805 | 83996 | Pgno iNext; /* Page number of the next source page to copy */ |
| 83806 | 83997 | sqlite3* pSrcDb; /* Source database handle */ |
| 83807 | | - Db *pSrc; /* Source db file */ |
| 83998 | + Btree *pSrc; /* Source b-tree file */ |
| 83808 | 83999 | |
| 83809 | 84000 | int rc; /* Backup process error code */ |
| 83810 | 84001 | |
| 83811 | 84002 | /* These two variables are set by every call to backup_step(). They are |
| 83812 | 84003 | ** read by calls to backup_remaining() and backup_pagecount(). |
| | @@ -83855,11 +84046,11 @@ |
| 83855 | 84046 | ** |
| 83856 | 84047 | ** If the "temp" database is requested, it may need to be opened by this |
| 83857 | 84048 | ** function. If an error occurs while doing so, return 0 and write an |
| 83858 | 84049 | ** error message to pErrorDb. |
| 83859 | 84050 | */ |
| 83860 | | -static Db *findDatabase(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ |
| 84051 | +static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ |
| 83861 | 84052 | int i = sqlite3FindDbName(pDb, zDb); |
| 83862 | 84053 | |
| 83863 | 84054 | if( i==1 ){ |
| 83864 | 84055 | Parse sParse; |
| 83865 | 84056 | int rc = 0; |
| | @@ -83878,21 +84069,19 @@ |
| 83878 | 84069 | if( i<0 ){ |
| 83879 | 84070 | sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); |
| 83880 | 84071 | return 0; |
| 83881 | 84072 | } |
| 83882 | 84073 | |
| 83883 | | - return &pDb->aDb[i]; |
| 84074 | + return pDb->aDb[i].pBt; |
| 83884 | 84075 | } |
| 83885 | 84076 | |
| 83886 | 84077 | /* |
| 83887 | 84078 | ** Attempt to set the page size of the destination to match the page size |
| 83888 | 84079 | ** of the source. |
| 83889 | 84080 | */ |
| 83890 | | -static int setDestPgsz(sqlite3_backup *p){ |
| 83891 | | - return sqlite3BtreeSetPageSize(p->pDest->pBt, |
| 83892 | | - sqlite3BtreeGetPageSize(p->pSrc->pBt), 0, 0 |
| 83893 | | - ); |
| 84081 | +static int setDestPgsz(Btree *pDest, Btree *pSrc){ |
| 84082 | + return sqlite3BtreeSetPageSize(pDest, sqlite3BtreeGetPageSize(pSrc), 0, 0); |
| 83894 | 84083 | } |
| 83895 | 84084 | |
| 83896 | 84085 | /* |
| 83897 | 84086 | ** Check that there is no open read-transaction on the b-tree passed as the |
| 83898 | 84087 | ** second argument. If there is not, return SQLITE_OK. Otherwise, if there |
| | @@ -83945,31 +84134,41 @@ |
| 83945 | 84134 | sqlite3ErrorWithMsg( |
| 83946 | 84135 | pDestDb, SQLITE_ERROR, "source and destination must be distinct" |
| 83947 | 84136 | ); |
| 83948 | 84137 | p = 0; |
| 83949 | 84138 | }else { |
| 84139 | + int nDest = sqlite3Strlen30(zDestDb); |
| 84140 | + |
| 83950 | 84141 | /* Allocate space for a new sqlite3_backup object... |
| 83951 | 84142 | ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a |
| 83952 | 84143 | ** call to sqlite3_backup_init() and is destroyed by a call to |
| 83953 | 84144 | ** sqlite3_backup_finish(). */ |
| 83954 | | - p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); |
| 84145 | + p = (sqlite3_backup*)sqlite3MallocZero(sizeof(sqlite3_backup)+nDest+1); |
| 83955 | 84146 | if( !p ){ |
| 83956 | 84147 | sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); |
| 84148 | + }else{ |
| 84149 | + p->zDestDb = (char*)&p[1]; |
| 84150 | + memcpy(p->zDestDb, zDestDb, nDest); |
| 83957 | 84151 | } |
| 83958 | 84152 | } |
| 83959 | 84153 | |
| 83960 | 84154 | /* If the allocation succeeded, populate the new object. */ |
| 83961 | 84155 | if( p ){ |
| 83962 | | - p->pSrc = findDatabase(pDestDb, pSrcDb, zSrcDb); |
| 83963 | | - p->pDest = findDatabase(pDestDb, pDestDb, zDestDb); |
| 84156 | + /* Do not store the pointer to the destination b-tree at this point. |
| 84157 | + ** This is because there is nothing preventing it from being detached |
| 84158 | + ** or otherwise freed before the first call to sqlite3_backup_step() |
| 84159 | + ** on this object. The source b-tree does not have this problem, as |
| 84160 | + ** incrementing Btree.nBackup (see below) effectively locks the object. */ |
| 84161 | + Btree *pDest = findBtree(pDestDb, pDestDb, zDestDb); |
| 84162 | + p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); |
| 83964 | 84163 | p->pDestDb = pDestDb; |
| 83965 | 84164 | p->pSrcDb = pSrcDb; |
| 83966 | 84165 | p->iNext = 1; |
| 83967 | 84166 | p->isAttached = 0; |
| 83968 | 84167 | |
| 83969 | | - if( 0==p->pSrc || 0==p->pDest |
| 83970 | | - || checkReadTransaction(pDestDb, p->pDest->pBt)!=SQLITE_OK |
| 84168 | + if( 0==p->pSrc || 0==pDest |
| 84169 | + || checkReadTransaction(pDestDb, pDest)!=SQLITE_OK |
| 83971 | 84170 | ){ |
| 83972 | 84171 | /* One (or both) of the named databases did not exist or an OOM |
| 83973 | 84172 | ** error was hit. Or there is a transaction open on the destination |
| 83974 | 84173 | ** database. The error has already been written into the pDestDb |
| 83975 | 84174 | ** handle. All that is left to do here is free the sqlite3_backup |
| | @@ -83977,11 +84176,11 @@ |
| 83977 | 84176 | sqlite3_free(p); |
| 83978 | 84177 | p = 0; |
| 83979 | 84178 | } |
| 83980 | 84179 | } |
| 83981 | 84180 | if( p ){ |
| 83982 | | - p->pSrc->pBt->nBackup++; |
| 84181 | + p->pSrc->nBackup++; |
| 83983 | 84182 | } |
| 83984 | 84183 | |
| 83985 | 84184 | sqlite3_mutex_leave(pDestDb->mutex); |
| 83986 | 84185 | sqlite3_mutex_leave(pSrcDb->mutex); |
| 83987 | 84186 | return p; |
| | @@ -84005,22 +84204,22 @@ |
| 84005 | 84204 | sqlite3_backup *p, /* Backup handle */ |
| 84006 | 84205 | Pgno iSrcPg, /* Source database page to backup */ |
| 84007 | 84206 | const u8 *zSrcData, /* Source database page data */ |
| 84008 | 84207 | int bUpdate /* True for an update, false otherwise */ |
| 84009 | 84208 | ){ |
| 84010 | | - Pager * const pDestPager = sqlite3BtreePager(p->pDest->pBt); |
| 84011 | | - const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc->pBt); |
| 84012 | | - int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest->pBt); |
| 84209 | + Pager * const pDestPager = sqlite3BtreePager(p->pDest); |
| 84210 | + const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); |
| 84211 | + int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); |
| 84013 | 84212 | const int nCopy = MIN(nSrcPgsz, nDestPgsz); |
| 84014 | 84213 | const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; |
| 84015 | 84214 | int rc = SQLITE_OK; |
| 84016 | 84215 | i64 iOff; |
| 84017 | 84216 | |
| 84018 | | - assert( sqlite3BtreeGetReserveNoMutex(p->pSrc->pBt)>=0 ); |
| 84217 | + assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); |
| 84019 | 84218 | assert( p->bDestLocked ); |
| 84020 | 84219 | assert( !isFatalError(p->rc) ); |
| 84021 | | - assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt->pBt) ); |
| 84220 | + assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); |
| 84022 | 84221 | assert( zSrcData ); |
| 84023 | 84222 | assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 ); |
| 84024 | 84223 | |
| 84025 | 84224 | /* This loop runs once for each destination page spanned by the source |
| 84026 | 84225 | ** page. For each iteration, variable iOff is set to the byte offset |
| | @@ -84027,11 +84226,11 @@ |
| 84027 | 84226 | ** of the destination page. |
| 84028 | 84227 | */ |
| 84029 | 84228 | for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){ |
| 84030 | 84229 | DbPage *pDestPg = 0; |
| 84031 | 84230 | Pgno iDest = (Pgno)(iOff/nDestPgsz)+1; |
| 84032 | | - if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt->pBt) ) continue; |
| 84231 | + if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue; |
| 84033 | 84232 | if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0)) |
| 84034 | 84233 | && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) |
| 84035 | 84234 | ){ |
| 84036 | 84235 | const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; |
| 84037 | 84236 | u8 *zDestData = sqlite3PagerGetData(pDestPg); |
| | @@ -84045,11 +84244,11 @@ |
| 84045 | 84244 | ** "MUST BE FIRST" for this purpose. |
| 84046 | 84245 | */ |
| 84047 | 84246 | memcpy(zOut, zIn, nCopy); |
| 84048 | 84247 | ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; |
| 84049 | 84248 | if( iOff==0 && bUpdate==0 ){ |
| 84050 | | - sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc->pBt)); |
| 84249 | + sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc)); |
| 84051 | 84250 | } |
| 84052 | 84251 | } |
| 84053 | 84252 | sqlite3PagerUnref(pDestPg); |
| 84054 | 84253 | } |
| 84055 | 84254 | |
| | @@ -84077,12 +84276,12 @@ |
| 84077 | 84276 | ** Register this backup object with the associated source pager for |
| 84078 | 84277 | ** callbacks when pages are changed or the cache invalidated. |
| 84079 | 84278 | */ |
| 84080 | 84279 | static void attachBackupObject(sqlite3_backup *p){ |
| 84081 | 84280 | sqlite3_backup **pp; |
| 84082 | | - assert( sqlite3BtreeHoldsMutex(p->pSrc->pBt) ); |
| 84083 | | - pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc->pBt)); |
| 84281 | + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); |
| 84282 | + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); |
| 84084 | 84283 | p->pNext = *pp; |
| 84085 | 84284 | *pp = p; |
| 84086 | 84285 | p->isAttached = 1; |
| 84087 | 84286 | } |
| 84088 | 84287 | |
| | @@ -84089,93 +84288,103 @@ |
| 84089 | 84288 | /* |
| 84090 | 84289 | ** Copy nPage pages from the source b-tree to the destination. |
| 84091 | 84290 | */ |
| 84092 | 84291 | SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ |
| 84093 | 84292 | int rc; |
| 84094 | | - int destMode; /* Destination journal mode */ |
| 84293 | + int destMode = 0; /* Destination journal mode */ |
| 84095 | 84294 | int pgszSrc = 0; /* Source page size */ |
| 84096 | 84295 | int pgszDest = 0; /* Destination page size */ |
| 84097 | | - Btree *pDest; |
| 84098 | | - Btree *pSrc; |
| 84099 | 84296 | |
| 84100 | 84297 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 84101 | 84298 | if( p==0 ) return SQLITE_MISUSE_BKPT; |
| 84102 | 84299 | #endif |
| 84103 | | - assert( p->pDest ); |
| 84104 | | - assert( p->pSrc ); |
| 84105 | | - pDest = p->pDest->pBt; |
| 84106 | | - pSrc = p->pSrc->pBt; |
| 84107 | 84300 | sqlite3_mutex_enter(p->pSrcDb->mutex); |
| 84108 | | - sqlite3BtreeEnter(pSrc); |
| 84301 | + sqlite3BtreeEnter(p->pSrc); |
| 84109 | 84302 | if( p->pDestDb ){ |
| 84110 | 84303 | sqlite3_mutex_enter(p->pDestDb->mutex); |
| 84111 | 84304 | } |
| 84112 | 84305 | |
| 84113 | 84306 | rc = p->rc; |
| 84114 | 84307 | if( !isFatalError(rc) ){ |
| 84115 | | - Pager * const pSrcPager = sqlite3BtreePager(pSrc); /* Source pager */ |
| 84116 | | - Pager * const pDestPager = sqlite3BtreePager(pDest); /* Dest pager */ |
| 84308 | + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ |
| 84309 | + Btree * pDest = 0; /* Dest btree */ |
| 84310 | + Pager * pDestPager = 0; /* Dest pager */ |
| 84117 | 84311 | int ii; /* Iterator variable */ |
| 84118 | 84312 | int nSrcPage = -1; /* Size of source db in pages */ |
| 84119 | 84313 | int bCloseTrans = 0; /* True if src db requires unlocking */ |
| 84120 | 84314 | |
| 84121 | 84315 | /* If the source pager is currently in a write-transaction, return |
| 84122 | 84316 | ** SQLITE_BUSY immediately. |
| 84123 | 84317 | */ |
| 84124 | | - if( p->pDestDb && pSrc->pBt->inTransaction==TRANS_WRITE ){ |
| 84318 | + if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){ |
| 84125 | 84319 | rc = SQLITE_BUSY; |
| 84126 | 84320 | }else{ |
| 84127 | 84321 | rc = SQLITE_OK; |
| 84128 | 84322 | } |
| 84323 | + |
| 84129 | 84324 | |
| 84130 | 84325 | /* If there is no open read-transaction on the source database, open |
| 84131 | 84326 | ** one now. If a transaction is opened here, then it will be closed |
| 84132 | 84327 | ** before this function exits. |
| 84133 | 84328 | */ |
| 84134 | | - if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(pSrc) ){ |
| 84135 | | - rc = sqlite3BtreeBeginTrans(pSrc, 0, 0); |
| 84329 | + if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){ |
| 84330 | + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); |
| 84136 | 84331 | bCloseTrans = 1; |
| 84137 | 84332 | } |
| 84333 | + |
| 84334 | + /* Locate the destination btree and pager. */ |
| 84335 | + if( (pDest = p->pDest)==0 ){ |
| 84336 | + pDest = findBtree(p->pDestDb, p->pDestDb, p->zDestDb); |
| 84337 | + } |
| 84338 | + if( pDest==0 ){ |
| 84339 | + rc = SQLITE_ERROR; |
| 84340 | + }else{ |
| 84341 | + pDestPager = sqlite3BtreePager(pDest); |
| 84342 | + } |
| 84138 | 84343 | |
| 84139 | 84344 | /* If the destination database has not yet been locked (i.e. if this |
| 84140 | 84345 | ** is the first call to backup_step() for the current backup operation), |
| 84141 | 84346 | ** try to set its page size to the same as the source database. This |
| 84142 | 84347 | ** is especially important on ZipVFS systems, as in that case it is |
| 84143 | 84348 | ** not possible to create a database file that uses one page size by |
| 84144 | 84349 | ** writing to it with another. */ |
| 84145 | | - if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){ |
| 84350 | + if( p->bDestLocked==0 && rc==SQLITE_OK |
| 84351 | + && setDestPgsz(pDest, p->pSrc)==SQLITE_NOMEM |
| 84352 | + ){ |
| 84146 | 84353 | rc = SQLITE_NOMEM; |
| 84147 | 84354 | } |
| 84148 | 84355 | |
| 84149 | 84356 | /* Lock the destination database, if it is not locked already. */ |
| 84150 | 84357 | if( SQLITE_OK==rc && p->bDestLocked==0 |
| 84151 | 84358 | && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(pDest, 2, |
| 84152 | 84359 | (int*)&p->iDestSchema)) |
| 84153 | 84360 | ){ |
| 84154 | 84361 | p->bDestLocked = 1; |
| 84362 | + p->pDest = pDest; |
| 84155 | 84363 | } |
| 84156 | 84364 | |
| 84157 | 84365 | /* Do not allow backup if the destination database is in WAL mode |
| 84158 | 84366 | ** and the page sizes are different between source and destination */ |
| 84159 | | - pgszSrc = sqlite3BtreeGetPageSize(pSrc); |
| 84160 | | - pgszDest = sqlite3BtreeGetPageSize(pDest); |
| 84161 | | - destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(pDest)); |
| 84162 | | - if( SQLITE_OK==rc |
| 84163 | | - && (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) |
| 84164 | | - && pgszSrc!=pgszDest |
| 84165 | | - ){ |
| 84166 | | - rc = SQLITE_READONLY; |
| 84367 | + if( rc==SQLITE_OK ){ |
| 84368 | + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); |
| 84369 | + pgszDest = sqlite3BtreeGetPageSize(p->pDest); |
| 84370 | + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); |
| 84371 | + if( (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) |
| 84372 | + && pgszSrc!=pgszDest |
| 84373 | + ){ |
| 84374 | + rc = SQLITE_READONLY; |
| 84375 | + } |
| 84167 | 84376 | } |
| 84168 | 84377 | |
| 84169 | 84378 | /* Now that there is a read-lock on the source database, query the |
| 84170 | 84379 | ** source pager for the number of pages in the database. |
| 84171 | 84380 | */ |
| 84172 | | - nSrcPage = (int)sqlite3BtreeLastPage(pSrc); |
| 84381 | + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); |
| 84173 | 84382 | assert( nSrcPage>=0 ); |
| 84174 | 84383 | for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){ |
| 84175 | 84384 | const Pgno iSrcPg = p->iNext; /* Source page number */ |
| 84176 | | - if( iSrcPg!=PENDING_BYTE_PAGE(pSrc->pBt) ){ |
| 84385 | + if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ |
| 84177 | 84386 | DbPage *pSrcPg; /* Source page object */ |
| 84178 | 84387 | rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY); |
| 84179 | 84388 | if( rc==SQLITE_OK ){ |
| 84180 | 84389 | rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); |
| 84181 | 84390 | sqlite3PagerUnref(pSrcPg); |
| | @@ -84198,22 +84407,22 @@ |
| 84198 | 84407 | ** the case where the source and destination databases have the |
| 84199 | 84408 | ** same schema version. |
| 84200 | 84409 | */ |
| 84201 | 84410 | if( rc==SQLITE_DONE ){ |
| 84202 | 84411 | if( nSrcPage==0 ){ |
| 84203 | | - rc = sqlite3BtreeNewDb(pDest); |
| 84412 | + rc = sqlite3BtreeNewDb(p->pDest); |
| 84204 | 84413 | nSrcPage = 1; |
| 84205 | 84414 | } |
| 84206 | 84415 | if( rc==SQLITE_OK || rc==SQLITE_DONE ){ |
| 84207 | | - rc = sqlite3BtreeUpdateMeta(pDest,1,p->iDestSchema+1); |
| 84416 | + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); |
| 84208 | 84417 | } |
| 84209 | 84418 | if( rc==SQLITE_OK ){ |
| 84210 | 84419 | if( p->pDestDb ){ |
| 84211 | 84420 | sqlite3ResetAllSchemasOfConnection(p->pDestDb); |
| 84212 | 84421 | } |
| 84213 | 84422 | if( destMode==PAGER_JOURNALMODE_WAL ){ |
| 84214 | | - rc = sqlite3BtreeSetVersion(pDest, 2); |
| 84423 | + rc = sqlite3BtreeSetVersion(p->pDest, 2); |
| 84215 | 84424 | } |
| 84216 | 84425 | } |
| 84217 | 84426 | if( rc==SQLITE_OK ){ |
| 84218 | 84427 | int nDestTruncate; |
| 84219 | 84428 | /* Set nDestTruncate to the final number of pages in the destination |
| | @@ -84226,16 +84435,16 @@ |
| 84226 | 84435 | ** sqlite3PagerTruncateImage() here so that any pages in the |
| 84227 | 84436 | ** destination file that lie beyond the nDestTruncate page mark are |
| 84228 | 84437 | ** journalled by PagerCommitPhaseOne() before they are destroyed |
| 84229 | 84438 | ** by the file truncation. |
| 84230 | 84439 | */ |
| 84231 | | - assert( pgszSrc==sqlite3BtreeGetPageSize(pSrc) ); |
| 84232 | | - assert( pgszDest==sqlite3BtreeGetPageSize(pDest) ); |
| 84440 | + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); |
| 84441 | + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); |
| 84233 | 84442 | if( pgszSrc<pgszDest ){ |
| 84234 | 84443 | int ratio = pgszDest/pgszSrc; |
| 84235 | 84444 | nDestTruncate = (nSrcPage+ratio-1)/ratio; |
| 84236 | | - if( nDestTruncate==(int)PENDING_BYTE_PAGE(pDest->pBt) ){ |
| 84445 | + if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){ |
| 84237 | 84446 | nDestTruncate--; |
| 84238 | 84447 | } |
| 84239 | 84448 | }else{ |
| 84240 | 84449 | nDestTruncate = nSrcPage * (pgszSrc/pgszDest); |
| 84241 | 84450 | } |
| | @@ -84259,11 +84468,11 @@ |
| 84259 | 84468 | i64 iEnd; |
| 84260 | 84469 | |
| 84261 | 84470 | assert( pFile ); |
| 84262 | 84471 | assert( nDestTruncate==0 |
| 84263 | 84472 | || (i64)nDestTruncate*(i64)pgszDest >= iSize || ( |
| 84264 | | - nDestTruncate==(int)(PENDING_BYTE_PAGE(pDest->pBt)-1) |
| 84473 | + nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) |
| 84265 | 84474 | && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest |
| 84266 | 84475 | )); |
| 84267 | 84476 | |
| 84268 | 84477 | /* This block ensures that all data required to recreate the original |
| 84269 | 84478 | ** database has been stored in the journal for pDestPager and the |
| | @@ -84271,11 +84480,11 @@ |
| 84271 | 84480 | ** the database file in any way, knowing that if a power failure |
| 84272 | 84481 | ** occurs, the original database will be reconstructed from the |
| 84273 | 84482 | ** journal file. */ |
| 84274 | 84483 | sqlite3PagerPagecount(pDestPager, &nDstPage); |
| 84275 | 84484 | for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){ |
| 84276 | | - if( iPg!=PENDING_BYTE_PAGE(pDest->pBt) ){ |
| 84485 | + if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){ |
| 84277 | 84486 | DbPage *pPg; |
| 84278 | 84487 | rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0); |
| 84279 | 84488 | if( rc==SQLITE_OK ){ |
| 84280 | 84489 | rc = sqlite3PagerWrite(pPg); |
| 84281 | 84490 | sqlite3PagerUnref(pPg); |
| | @@ -84315,11 +84524,11 @@ |
| 84315 | 84524 | rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0); |
| 84316 | 84525 | } |
| 84317 | 84526 | |
| 84318 | 84527 | /* Finish committing the transaction to the destination database. */ |
| 84319 | 84528 | if( SQLITE_OK==rc |
| 84320 | | - && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(pDest, 0)) |
| 84529 | + && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0)) |
| 84321 | 84530 | ){ |
| 84322 | 84531 | rc = SQLITE_DONE; |
| 84323 | 84532 | } |
| 84324 | 84533 | } |
| 84325 | 84534 | } |
| | @@ -84329,12 +84538,12 @@ |
| 84329 | 84538 | ** no need to check the return values of the btree methods here, as |
| 84330 | 84539 | ** "committing" a read-only transaction cannot fail. |
| 84331 | 84540 | */ |
| 84332 | 84541 | if( bCloseTrans ){ |
| 84333 | 84542 | TESTONLY( int rc2 ); |
| 84334 | | - TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(pSrc, 0); |
| 84335 | | - TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(pSrc, 0); |
| 84543 | + TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); |
| 84544 | + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); |
| 84336 | 84545 | assert( rc2==SQLITE_OK ); |
| 84337 | 84546 | } |
| 84338 | 84547 | |
| 84339 | 84548 | if( rc==SQLITE_IOERR_NOMEM ){ |
| 84340 | 84549 | rc = SQLITE_NOMEM_BKPT; |
| | @@ -84342,11 +84551,11 @@ |
| 84342 | 84551 | p->rc = rc; |
| 84343 | 84552 | } |
| 84344 | 84553 | if( p->pDestDb ){ |
| 84345 | 84554 | sqlite3_mutex_leave(p->pDestDb->mutex); |
| 84346 | 84555 | } |
| 84347 | | - sqlite3BtreeLeave(pSrc); |
| 84556 | + sqlite3BtreeLeave(p->pSrc); |
| 84348 | 84557 | sqlite3_mutex_leave(p->pSrcDb->mutex); |
| 84349 | 84558 | return rc; |
| 84350 | 84559 | } |
| 84351 | 84560 | |
| 84352 | 84561 | /* |
| | @@ -84359,41 +84568,43 @@ |
| 84359 | 84568 | |
| 84360 | 84569 | /* Enter the mutexes */ |
| 84361 | 84570 | if( p==0 ) return SQLITE_OK; |
| 84362 | 84571 | pSrcDb = p->pSrcDb; |
| 84363 | 84572 | sqlite3_mutex_enter(pSrcDb->mutex); |
| 84364 | | - sqlite3BtreeEnter(p->pSrc->pBt); |
| 84573 | + sqlite3BtreeEnter(p->pSrc); |
| 84365 | 84574 | if( p->pDestDb ){ |
| 84366 | 84575 | sqlite3_mutex_enter(p->pDestDb->mutex); |
| 84367 | 84576 | } |
| 84368 | 84577 | |
| 84369 | 84578 | /* Detach this backup from the source pager. */ |
| 84370 | 84579 | if( p->pDestDb ){ |
| 84371 | | - p->pSrc->pBt->nBackup--; |
| 84580 | + p->pSrc->nBackup--; |
| 84372 | 84581 | } |
| 84373 | 84582 | if( p->isAttached ){ |
| 84374 | | - pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc->pBt)); |
| 84583 | + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); |
| 84375 | 84584 | assert( pp!=0 ); |
| 84376 | 84585 | while( *pp!=p ){ |
| 84377 | 84586 | pp = &(*pp)->pNext; |
| 84378 | 84587 | assert( pp!=0 ); |
| 84379 | 84588 | } |
| 84380 | 84589 | *pp = p->pNext; |
| 84381 | 84590 | } |
| 84382 | 84591 | |
| 84383 | 84592 | /* If a transaction is still open on the Btree, roll it back. */ |
| 84384 | | - sqlite3BtreeRollback(p->pDest->pBt, SQLITE_OK, 0); |
| 84593 | + if( p->pDest ){ |
| 84594 | + sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); |
| 84595 | + } |
| 84385 | 84596 | |
| 84386 | 84597 | /* Set the error code of the destination database handle. */ |
| 84387 | 84598 | rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; |
| 84388 | 84599 | if( p->pDestDb ){ |
| 84389 | 84600 | sqlite3Error(p->pDestDb, rc); |
| 84390 | 84601 | |
| 84391 | 84602 | /* Exit the mutexes and free the backup context structure. */ |
| 84392 | 84603 | sqlite3LeaveMutexAndCloseZombie(p->pDestDb); |
| 84393 | 84604 | } |
| 84394 | | - sqlite3BtreeLeave(p->pSrc->pBt); |
| 84605 | + sqlite3BtreeLeave(p->pSrc); |
| 84395 | 84606 | if( p->pDestDb ){ |
| 84396 | 84607 | /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a |
| 84397 | 84608 | ** call to sqlite3_backup_init() and is destroyed by a call to |
| 84398 | 84609 | ** sqlite3_backup_finish(). */ |
| 84399 | 84610 | sqlite3_free(p); |
| | @@ -84447,11 +84658,11 @@ |
| 84447 | 84658 | Pgno iPage, |
| 84448 | 84659 | const u8 *aData |
| 84449 | 84660 | ){ |
| 84450 | 84661 | assert( p!=0 ); |
| 84451 | 84662 | do{ |
| 84452 | | - assert( sqlite3_mutex_held(p->pSrc->pBt->pBt->mutex) ); |
| 84663 | + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); |
| 84453 | 84664 | if( !isFatalError(p->rc) && iPage<p->iNext ){ |
| 84454 | 84665 | /* The backup process p has already copied page iPage. But now it |
| 84455 | 84666 | ** has been modified by a transaction on the source pager. Copy |
| 84456 | 84667 | ** the new data into the backup. |
| 84457 | 84668 | */ |
| | @@ -84483,11 +84694,11 @@ |
| 84483 | 84694 | ** called. |
| 84484 | 84695 | */ |
| 84485 | 84696 | SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ |
| 84486 | 84697 | sqlite3_backup *p; /* Iterator variable */ |
| 84487 | 84698 | for(p=pBackup; p; p=p->pNext){ |
| 84488 | | - assert( sqlite3_mutex_held(p->pSrc->pBt->pBt->mutex) ); |
| 84699 | + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); |
| 84489 | 84700 | p->iNext = 1; |
| 84490 | 84701 | } |
| 84491 | 84702 | } |
| 84492 | 84703 | |
| 84493 | 84704 | #ifndef SQLITE_OMIT_VACUUM |
| | @@ -84501,12 +84712,10 @@ |
| 84501 | 84712 | */ |
| 84502 | 84713 | SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ |
| 84503 | 84714 | int rc; |
| 84504 | 84715 | sqlite3_file *pFd; /* File descriptor for database pTo */ |
| 84505 | 84716 | sqlite3_backup b; |
| 84506 | | - Db dbDest; |
| 84507 | | - Db dbSrc; |
| 84508 | 84717 | sqlite3BtreeEnter(pTo); |
| 84509 | 84718 | sqlite3BtreeEnter(pFrom); |
| 84510 | 84719 | |
| 84511 | 84720 | assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE ); |
| 84512 | 84721 | pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); |
| | @@ -84521,17 +84730,13 @@ |
| 84521 | 84730 | ** to 0. This is used by the implementations of sqlite3_backup_step() |
| 84522 | 84731 | ** and sqlite3_backup_finish() to detect that they are being called |
| 84523 | 84732 | ** from this function, not directly by the user. |
| 84524 | 84733 | */ |
| 84525 | 84734 | memset(&b, 0, sizeof(b)); |
| 84526 | | - memset(&dbDest, 0, sizeof(dbDest)); |
| 84527 | | - memset(&dbSrc, 0, sizeof(dbSrc)); |
| 84528 | | - dbDest.pBt = pTo; |
| 84529 | | - dbSrc.pBt = pFrom; |
| 84530 | 84735 | b.pSrcDb = pFrom->db; |
| 84531 | | - b.pSrc = &dbSrc; |
| 84532 | | - b.pDest = &dbDest; |
| 84736 | + b.pSrc = pFrom; |
| 84737 | + b.pDest = pTo; |
| 84533 | 84738 | b.iNext = 1; |
| 84534 | 84739 | |
| 84535 | 84740 | /* 0x7FFFFFFF is the hard limit for the number of pages in a database |
| 84536 | 84741 | ** file. By passing this as the number of pages to copy to |
| 84537 | 84742 | ** sqlite3_backup_step(), we can guarantee that the copy finishes |
| | @@ -84543,11 +84748,11 @@ |
| 84543 | 84748 | |
| 84544 | 84749 | rc = sqlite3_backup_finish(&b); |
| 84545 | 84750 | if( rc==SQLITE_OK ){ |
| 84546 | 84751 | pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; |
| 84547 | 84752 | }else{ |
| 84548 | | - sqlite3PagerClearCache(sqlite3BtreePager(pTo)); |
| 84753 | + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); |
| 84549 | 84754 | } |
| 84550 | 84755 | |
| 84551 | 84756 | assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE ); |
| 84552 | 84757 | copy_finished: |
| 84553 | 84758 | sqlite3BtreeLeave(pFrom); |
| | @@ -86859,11 +87064,10 @@ |
| 86859 | 87064 | p->pParse = pParse; |
| 86860 | 87065 | pParse->pVdbe = p; |
| 86861 | 87066 | assert( pParse->aLabel==0 ); |
| 86862 | 87067 | assert( pParse->nLabel==0 ); |
| 86863 | 87068 | assert( p->nOpAlloc==0 ); |
| 86864 | | - assert( pParse->szOpAlloc==0 ); |
| 86865 | 87069 | sqlite3VdbeAddOp2(p, OP_Init, 0, 1); |
| 86866 | 87070 | return p; |
| 86867 | 87071 | } |
| 86868 | 87072 | |
| 86869 | 87073 | /* |
| | @@ -87009,12 +87213,11 @@ |
| 87009 | 87213 | |
| 87010 | 87214 | assert( nOp<=(int)(1024/sizeof(Op)) ); |
| 87011 | 87215 | assert( nNew>=(v->nOpAlloc+nOp) ); |
| 87012 | 87216 | pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); |
| 87013 | 87217 | if( pNew ){ |
| 87014 | | - p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); |
| 87015 | | - v->nOpAlloc = p->szOpAlloc/sizeof(Op); |
| 87218 | + v->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op); |
| 87016 | 87219 | v->aOp = pNew; |
| 87017 | 87220 | } |
| 87018 | 87221 | return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT); |
| 87019 | 87222 | } |
| 87020 | 87223 | |
| | @@ -87445,11 +87648,11 @@ |
| 87445 | 87648 | ** Resolve label "x" to be the address of the next instruction to |
| 87446 | 87649 | ** be inserted. The parameter "x" must have been obtained from |
| 87447 | 87650 | ** a prior call to sqlite3VdbeMakeLabel(). |
| 87448 | 87651 | */ |
| 87449 | 87652 | static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ |
| 87450 | | - int nNewSize = 10 - p->nLabel; |
| 87653 | + int nNewSize = 25 - p->nLabel; |
| 87451 | 87654 | p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, |
| 87452 | 87655 | nNewSize*sizeof(p->aLabel[0])); |
| 87453 | 87656 | if( p->aLabel==0 ){ |
| 87454 | 87657 | p->nLabelAlloc = 0; |
| 87455 | 87658 | }else{ |
| | @@ -89513,11 +89716,11 @@ |
| 89513 | 89716 | ** of the prepared statement. |
| 89514 | 89717 | */ |
| 89515 | 89718 | n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ |
| 89516 | 89719 | x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ |
| 89517 | 89720 | assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); |
| 89518 | | - x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ |
| 89721 | + x.nFree = ROUNDDOWN8((p->nOpAlloc-p->nOp)*sizeof(Op)); /* Bytes unused mem */ |
| 89519 | 89722 | assert( x.nFree>=0 ); |
| 89520 | 89723 | assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); |
| 89521 | 89724 | |
| 89522 | 89725 | resolveP2Values(p, &nArg); |
| 89523 | 89726 | p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); |
| | @@ -92662,12 +92865,18 @@ |
| 92662 | 92865 | ** that sqlite3_prepare() generates. For example, if new functions or |
| 92663 | 92866 | ** collating sequences are registered or if an authorizer function is |
| 92664 | 92867 | ** added or changed. |
| 92665 | 92868 | */ |
| 92666 | 92869 | SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){ |
| 92667 | | - Vdbe *p = (Vdbe*)pStmt; |
| 92668 | | - return p==0 || p->expired; |
| 92870 | + int iRet = 1; |
| 92871 | + if( pStmt ){ |
| 92872 | + Vdbe *p = (Vdbe*)pStmt; |
| 92873 | + sqlite3_mutex_enter(p->db->mutex); |
| 92874 | + iRet = p->expired; |
| 92875 | + sqlite3_mutex_leave(p->db->mutex); |
| 92876 | + } |
| 92877 | + return iRet; |
| 92669 | 92878 | } |
| 92670 | 92879 | #endif |
| 92671 | 92880 | |
| 92672 | 92881 | /* |
| 92673 | 92882 | ** Check on a Vdbe to make sure it has not been finalized. Log |
| | @@ -93009,19 +93218,22 @@ |
| 93009 | 93218 | sqlite3ValueFree(pOld); |
| 93010 | 93219 | } |
| 93011 | 93220 | |
| 93012 | 93221 | |
| 93013 | 93222 | /**************************** sqlite3_result_ ******************************* |
| 93014 | | -** The following routines are used by user-defined functions to specify |
| 93015 | | -** the function result. |
| 93016 | | -** |
| 93017 | | -** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the |
| 93018 | | -** result as a string or blob. Appropriate errors are set if the string/blob |
| 93019 | | -** is too big or if an OOM occurs. |
| 93020 | | -** |
| 93021 | | -** The invokeValueDestructor(P,X) routine invokes destructor function X() |
| 93022 | | -** on value P if P is not going to be used and need to be destroyed. |
| 93223 | +** The following routines are used by application-defined SQL functions to |
| 93224 | +** specify the function return value. There are many variations on |
| 93225 | +** sqlite3_result_xxxx() for different types of return values. |
| 93226 | +** |
| 93227 | +** The setStrOrError() function is a helper function that invokes |
| 93228 | +** sqlite3VdbeMemSetStr() to store the result as a string or blob. |
| 93229 | +** Appropriate errors are set if the string/blob is too big or if |
| 93230 | +** an OOM occurs. |
| 93231 | +** |
| 93232 | +** The invokeValueDestructor(P,X) helper function invokes the destructor |
| 93233 | +** function X() on value P if P is not going to be used and need to |
| 93234 | +** be destroyed. |
| 93023 | 93235 | */ |
| 93024 | 93236 | static void setResultStrOrError( |
| 93025 | 93237 | sqlite3_context *pCtx, /* Function context */ |
| 93026 | 93238 | const char *z, /* String pointer */ |
| 93027 | 93239 | int n, /* Bytes in string, or negative */ |
| | @@ -93330,11 +93542,11 @@ |
| 93330 | 93542 | setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, |
| 93331 | 93543 | SQLITE_STATIC); |
| 93332 | 93544 | } |
| 93333 | 93545 | } |
| 93334 | 93546 | |
| 93335 | | -/* Force an SQLITE_TOOBIG error. */ |
| 93547 | +/* Cause the SQL function to raise an SQLITE_TOOBIG error. */ |
| 93336 | 93548 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ |
| 93337 | 93549 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 93338 | 93550 | if( pCtx==0 ) return; |
| 93339 | 93551 | #endif |
| 93340 | 93552 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| | @@ -93341,20 +93553,82 @@ |
| 93341 | 93553 | pCtx->isError = SQLITE_TOOBIG; |
| 93342 | 93554 | sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, |
| 93343 | 93555 | SQLITE_UTF8, SQLITE_STATIC); |
| 93344 | 93556 | } |
| 93345 | 93557 | |
| 93346 | | -/* An SQLITE_NOMEM error. */ |
| 93558 | +/* Cause the SQL function to raise an SQLITE_NOMEM error. */ |
| 93347 | 93559 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ |
| 93348 | 93560 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 93349 | 93561 | if( pCtx==0 ) return; |
| 93350 | 93562 | #endif |
| 93351 | 93563 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 93352 | 93564 | sqlite3VdbeMemSetNull(pCtx->pOut); |
| 93353 | 93565 | pCtx->isError = SQLITE_NOMEM_BKPT; |
| 93354 | 93566 | sqlite3OomFault(pCtx->pOut->db); |
| 93355 | 93567 | } |
| 93568 | + |
| 93569 | +/* Make the return value of the SQL function or virtual table pCtx |
| 93570 | +** be the content of the sqlite3_str object pStr. The eOwn flag |
| 93571 | +** determines ownership of the sqlite3_str object and its content. |
| 93572 | +** |
| 93573 | +** eOwn Ownership transfer |
| 93574 | +** ------------- ------------------------------------------------ |
| 93575 | +** |
| 93576 | +** SQLITE_COPY The SQL function returns a copy the sqlite3_str |
| 93577 | +** content and leaves the sqlite3_str object itself |
| 93578 | +** unchanged. |
| 93579 | +** |
| 93580 | +** SQLITE_XFER The content of the sqlite3_str is transferred to |
| 93581 | +** the SQL function and the SQL function takes |
| 93582 | +** responsibility for freeing that content when it is |
| 93583 | +** no longer needed. The sqlite3_str object is reset |
| 93584 | +** to an empty string. |
| 93585 | +** |
| 93586 | +** SQLITE_FINISH Like SQLITE_XFER except that the pStr is also |
| 93587 | +** freed using sqlite3_str_free(). |
| 93588 | +*/ |
| 93589 | +SQLITE_API void sqlite3_result_str(sqlite3_context *pCtx, sqlite3_str *pStr, int eOwn){ |
| 93590 | +#ifdef SQLITE_ENABLE_API_ARMOR |
| 93591 | + if( pCtx==0 ) return; |
| 93592 | + if( pStr==0 ) return; |
| 93593 | +#endif |
| 93594 | + if( pStr->accError==0 ){ |
| 93595 | + if( pStr->nChar==0 ){ |
| 93596 | + setResultStrOrError(pCtx, "", 0, SQLITE_UTF8_ZT, SQLITE_STATIC); |
| 93597 | + if( eOwn ) sqlite3_str_reset(pStr); |
| 93598 | + }else{ |
| 93599 | + const char *zText = sqlite3_str_value(pStr); |
| 93600 | + /* Only internal code has the ability to capture a pointer to |
| 93601 | + ** an sqlite3_str object that uses static buffer. And none of |
| 93602 | + ** those internal use cases every invoke the sqlite3_result_str() |
| 93603 | + ** interface on a static-buffer sqlite3_str. Should this change |
| 93604 | + ** in the future, the following assert() will let us know. */ |
| 93605 | + assert( isMalloced(pStr) ); |
| 93606 | + if( eOwn==SQLITE_COPY ){ |
| 93607 | + setResultStrOrError(pCtx, zText, pStr->nChar, |
| 93608 | + SQLITE_UTF8, SQLITE_TRANSIENT); |
| 93609 | + }else{ |
| 93610 | + setResultStrOrError(pCtx, zText, pStr->nChar, |
| 93611 | + SQLITE_UTF8_ZT, SQLITE_DYNAMIC); |
| 93612 | + } |
| 93613 | + } |
| 93614 | + }else if( pStr->accError==SQLITE_NOMEM ){ |
| 93615 | + sqlite3_result_error_nomem(pCtx); |
| 93616 | + }else{ |
| 93617 | + assert( pStr->accError==SQLITE_TOOBIG ); |
| 93618 | + sqlite3_result_error_toobig(pCtx); |
| 93619 | + } |
| 93620 | + if( eOwn ){ |
| 93621 | + testcase( pStr==(sqlite3_str*)&sqlite3OomStr ); |
| 93622 | + if( pStr->accError==0 ){ |
| 93623 | + sqlite3StrAccumInit(pStr, pStr->db, 0, 0, pStr->mxAlloc); |
| 93624 | + } |
| 93625 | + if( eOwn==SQLITE_FINISH ){ |
| 93626 | + sqlite3_str_free(pStr); |
| 93627 | + } |
| 93628 | + } |
| 93629 | +} |
| 93356 | 93630 | |
| 93357 | 93631 | #ifndef SQLITE_UNTESTABLE |
| 93358 | 93632 | /* Force the INT64 value currently stored as the result to be |
| 93359 | 93633 | ** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL |
| 93360 | 93634 | ** test-control. |
| | @@ -102342,10 +102616,15 @@ |
| 102342 | 102616 | pTabCur = p->apCsr[pOp->p3]; |
| 102343 | 102617 | assert( pTabCur!=0 ); |
| 102344 | 102618 | assert( pTabCur->eCurType==CURTYPE_BTREE ); |
| 102345 | 102619 | assert( pTabCur->uc.pCursor!=0 ); |
| 102346 | 102620 | assert( pTabCur->isTable ); |
| 102621 | +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) |
| 102622 | + assert( |
| 102623 | + sqlite3BtreeCursorHintTblCsr(pC->uc.pCursor)==pTabCur->uc.pCursor |
| 102624 | + ); |
| 102625 | +#endif |
| 102347 | 102626 | pTabCur->nullRow = 0; |
| 102348 | 102627 | pTabCur->movetoTarget = rowid; |
| 102349 | 102628 | pTabCur->deferredMoveto = 1; |
| 102350 | 102629 | pTabCur->cacheStatus = CACHE_STALE; |
| 102351 | 102630 | assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); |
| | @@ -104724,27 +105003,41 @@ |
| 104724 | 105003 | p->aCounter[SQLITE_STMTSTATUS_RUN]++; |
| 104725 | 105004 | goto jump_to_p2; |
| 104726 | 105005 | } |
| 104727 | 105006 | |
| 104728 | 105007 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 104729 | | -/* Opcode: CursorHint P1 * * P4 * |
| 105008 | +/* Opcode: CursorHint P1 * P3 P4 * |
| 104730 | 105009 | ** |
| 104731 | | -** Provide a hint to cursor P1 that it only needs to return rows that |
| 104732 | | -** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer |
| 104733 | | -** to values currently held in registers. TK_COLUMN terms in the P4 |
| 105010 | +** Provide a hint to cursor P1. |
| 105011 | +** |
| 105012 | +** If P4 is of type P4_EXPR, then the hint is that the cursor need only return |
| 105013 | +** rows that satisfy the Expr in P4. TK_REGISTER terms in the P4 expression |
| 105014 | +** refer to values currently held in registers. TK_COLUMN terms in the P4 |
| 104734 | 105015 | ** expression refer to columns in the b-tree to which cursor P1 is pointing. |
| 105016 | +** P3 is ignore in this case. |
| 105017 | +** |
| 105018 | +** Or, if P4 is P4_NOTUSED, then the hint is that cursor P1 is an index cursor |
| 105019 | +** used to drive table cursor P3. In other words, that this VM may execute |
| 105020 | +** OP_DeferredSeek instructions to lazily position P3 based on current |
| 105021 | +** position of P1. |
| 104735 | 105022 | */ |
| 104736 | 105023 | case OP_CursorHint: { |
| 104737 | 105024 | VdbeCursor *pC; |
| 105025 | + pC = p->apCsr[pOp->p1]; |
| 104738 | 105026 | |
| 104739 | 105027 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 104740 | | - assert( pOp->p4type==P4_EXPR ); |
| 104741 | | - pC = p->apCsr[pOp->p1]; |
| 105028 | + |
| 104742 | 105029 | if( pC ){ |
| 104743 | 105030 | assert( pC->eCurType==CURTYPE_BTREE ); |
| 104744 | | - sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, |
| 104745 | | - pOp->p4.pExpr, aMem); |
| 105031 | + if( pOp->p4type==P4_EXPR ){ |
| 105032 | + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, |
| 105033 | + pOp->p4.pExpr, aMem); |
| 105034 | + }else if( p->apCsr[pOp->p3] ){ |
| 105035 | + sqlite3BtreeCursorHint( |
| 105036 | + pC->uc.pCursor, BTREE_HINT_TABLECURSOR, p->apCsr[pOp->p3]->uc.pCursor |
| 105037 | + ); |
| 105038 | + } |
| 104746 | 105039 | } |
| 104747 | 105040 | break; |
| 104748 | 105041 | } |
| 104749 | 105042 | #endif /* SQLITE_ENABLE_CURSOR_HINTS */ |
| 104750 | 105043 | |
| | @@ -117229,11 +117522,16 @@ |
| 117229 | 117522 | #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION |
| 117230 | 117523 | if( pDef==0 && pParse->explain ){ |
| 117231 | 117524 | pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); |
| 117232 | 117525 | } |
| 117233 | 117526 | #endif |
| 117234 | | - if( pDef==0 || pDef->xFinalize!=0 ){ |
| 117527 | + if( pDef==0 |
| 117528 | + || pDef->xFinalize!=0 |
| 117529 | + || ((pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && |
| 117530 | + !pParse->nested && |
| 117531 | + (db->mDbFlags & DBFLAG_InternalFunc)==0) |
| 117532 | + ){ |
| 117235 | 117533 | sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); |
| 117236 | 117534 | break; |
| 117237 | 117535 | } |
| 117238 | 117536 | if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ |
| 117239 | 117537 | assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); |
| | @@ -122236,13 +122534,12 @@ |
| 122236 | 122534 | const u8 *zSql = sqlite3_value_text(argv[0]); |
| 122237 | 122535 | const char *zCons = (const char*)sqlite3_value_text(argv[1]); |
| 122238 | 122536 | int iCol = sqlite3_value_int(argv[2]); |
| 122239 | 122537 | int iOff = 0; |
| 122240 | 122538 | int ii; |
| 122241 | | - char *zNew = 0; |
| 122539 | + sqlite3_str *pNew; |
| 122242 | 122540 | int t = 0; |
| 122243 | | - sqlite3 *db; |
| 122244 | 122541 | UNUSED_PARAMETER(NotUsed); |
| 122245 | 122542 | |
| 122246 | 122543 | if( skipCreateTable(ctx, zSql, &iOff) ) return; |
| 122247 | 122544 | |
| 122248 | 122545 | for(ii=0; ii<=iCol || (iCol<0 && t!=TK_RP); ii++){ |
| | @@ -122258,17 +122555,15 @@ |
| 122258 | 122555 | } |
| 122259 | 122556 | } |
| 122260 | 122557 | |
| 122261 | 122558 | iOff += getWhitespace(&zSql[iOff]); |
| 122262 | 122559 | |
| 122263 | | - db = sqlite3_context_db_handle(ctx); |
| 122264 | | - if( iCol<0 ){ |
| 122265 | | - zNew = sqlite3MPrintf(db, "%.*s, %s%s", iOff, zSql, zCons, &zSql[iOff]); |
| 122266 | | - }else{ |
| 122267 | | - zNew = sqlite3MPrintf(db, "%.*s %s%s", iOff, zSql, zCons, &zSql[iOff]); |
| 122268 | | - } |
| 122269 | | - sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC); |
| 122560 | + pNew = sqlite3_str_new(sqlite3_context_db_handle(ctx)); |
| 122561 | + sqlite3_str_append(pNew, (const char*)zSql, iOff); |
| 122562 | + if( iCol<0 ) sqlite3_str_append(pNew, ",", 1); |
| 122563 | + sqlite3_str_appendf(pNew, " %s%s", zCons, &zSql[iOff]); |
| 122564 | + sqlite3_result_str(ctx, pNew, SQLITE_FINISH); |
| 122270 | 122565 | } |
| 122271 | 122566 | |
| 122272 | 122567 | /* |
| 122273 | 122568 | ** Find a column named pCol in table pTab. If successful, set output |
| 122274 | 122569 | ** parameter *piCol to the index of the column in the table and return |
| | @@ -123524,11 +123819,11 @@ |
| 123524 | 123819 | sqlite3_str_appendf(&sStat, " %llu", iVal); |
| 123525 | 123820 | #ifdef SQLITE_ENABLE_STAT4 |
| 123526 | 123821 | assert( p->current.anEq[i] || p->nRow==0 ); |
| 123527 | 123822 | #endif |
| 123528 | 123823 | } |
| 123529 | | - sqlite3ResultStrAccum(context, &sStat); |
| 123824 | + sqlite3_result_str(context, &sStat, SQLITE_XFER); |
| 123530 | 123825 | } |
| 123531 | 123826 | #ifdef SQLITE_ENABLE_STAT4 |
| 123532 | 123827 | else if( eCall==STAT_GET_ROWID ){ |
| 123533 | 123828 | if( p->iGet<0 ){ |
| 123534 | 123829 | samplePushPrevious(p, 0); |
| | @@ -123561,11 +123856,11 @@ |
| 123561 | 123856 | sqlite3StrAccumInit(&sStat, 0, 0, 0, p->nCol*100); |
| 123562 | 123857 | for(i=0; i<p->nCol; i++){ |
| 123563 | 123858 | sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]); |
| 123564 | 123859 | } |
| 123565 | 123860 | if( sStat.nChar ) sStat.nChar--; |
| 123566 | | - sqlite3ResultStrAccum(context, &sStat); |
| 123861 | + sqlite3_result_str(context, &sStat, SQLITE_XFER); |
| 123567 | 123862 | } |
| 123568 | 123863 | #endif /* SQLITE_ENABLE_STAT4 */ |
| 123569 | 123864 | #ifndef SQLITE_DEBUG |
| 123570 | 123865 | UNUSED_PARAMETER( argc ); |
| 123571 | 123866 | #endif |
| | @@ -125649,10 +125944,11 @@ |
| 125649 | 125944 | } |
| 125650 | 125945 | } |
| 125651 | 125946 | |
| 125652 | 125947 | assert( pToplevel->nTableLock < 0x7fff0000 ); |
| 125653 | 125948 | nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); |
| 125949 | + if( pToplevel->nTableLock==0 ) pToplevel->aTableLock = 0; |
| 125654 | 125950 | pToplevel->aTableLock = |
| 125655 | 125951 | sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); |
| 125656 | 125952 | if( pToplevel->aTableLock ){ |
| 125657 | 125953 | p = &pToplevel->aTableLock[pToplevel->nTableLock++]; |
| 125658 | 125954 | p->iDb = iDb; |
| | @@ -125815,11 +126111,11 @@ |
| 125815 | 126111 | if( pParse->nTableLock ) codeTableLocks(pParse); |
| 125816 | 126112 | #endif |
| 125817 | 126113 | |
| 125818 | 126114 | /* Initialize any AUTOINCREMENT data structures required. |
| 125819 | 126115 | */ |
| 125820 | | - if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); |
| 126116 | + if( pParse->usesAinc ) sqlite3AutoincrementBegin(pParse); |
| 125821 | 126117 | |
| 125822 | 126118 | /* Code constant expressions that were factored out of inner loops. |
| 125823 | 126119 | */ |
| 125824 | 126120 | if( pParse->pConstExpr ){ |
| 125825 | 126121 | ExprList *pEL = pParse->pConstExpr; |
| | @@ -125848,11 +126144,11 @@ |
| 125848 | 126144 | assert( v!=0 || pParse->nErr ); |
| 125849 | 126145 | assert( db->mallocFailed==0 || pParse->nErr ); |
| 125850 | 126146 | if( pParse->nErr==0 ){ |
| 125851 | 126147 | /* A minimum of one cursor is required if autoincrement is used |
| 125852 | 126148 | * See ticket [a696379c1f08866] */ |
| 125853 | | - assert( pParse->pAinc==0 || pParse->nTab>0 ); |
| 126149 | + assert( pParse->usesAinc==0 || pParse->nTab>0 ); |
| 125854 | 126150 | sqlite3VdbeMakeReady(v, pParse); |
| 125855 | 126151 | pParse->rc = SQLITE_DONE; |
| 125856 | 126152 | }else{ |
| 125857 | 126153 | pParse->rc = SQLITE_ERROR; |
| 125858 | 126154 | } |
| | @@ -133318,32 +133614,20 @@ |
| 133318 | 133614 | sqlite3_value **argv |
| 133319 | 133615 | ){ |
| 133320 | 133616 | PrintfArguments x; |
| 133321 | 133617 | StrAccum str; |
| 133322 | 133618 | const char *zFormat; |
| 133323 | | - int n; |
| 133324 | 133619 | sqlite3 *db = sqlite3_context_db_handle(context); |
| 133325 | 133620 | |
| 133326 | 133621 | if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ |
| 133327 | 133622 | x.nArg = argc-1; |
| 133328 | 133623 | x.nUsed = 0; |
| 133329 | 133624 | x.apArg = argv+1; |
| 133330 | 133625 | sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 133331 | 133626 | str.printfFlags = SQLITE_PRINTF_SQLFUNC; |
| 133332 | 133627 | sqlite3_str_appendf(&str, zFormat, &x); |
| 133333 | | - if( str.accError==SQLITE_OK ){ |
| 133334 | | - n = str.nChar; |
| 133335 | | - sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, |
| 133336 | | - SQLITE_DYNAMIC); |
| 133337 | | - }else{ |
| 133338 | | - if( str.accError==SQLITE_NOMEM ){ |
| 133339 | | - sqlite3_result_error_nomem(context); |
| 133340 | | - }else{ |
| 133341 | | - sqlite3_result_error_toobig(context); |
| 133342 | | - } |
| 133343 | | - sqlite3_str_reset(&str); |
| 133344 | | - } |
| 133628 | + sqlite3_result_str(context, &str, SQLITE_XFER); |
| 133345 | 133629 | } |
| 133346 | 133630 | } |
| 133347 | 133631 | |
| 133348 | 133632 | /* |
| 133349 | 133633 | ** Implementation of the substr() function. |
| | @@ -134286,16 +134570,11 @@ |
| 134286 | 134570 | sqlite3 *db = sqlite3_context_db_handle(context); |
| 134287 | 134571 | assert( argc==1 ); |
| 134288 | 134572 | UNUSED_PARAMETER(argc); |
| 134289 | 134573 | sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 134290 | 134574 | sqlite3QuoteValue(&str,argv[0],SQLITE_PTR_TO_INT(sqlite3_user_data(context))); |
| 134291 | | - sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, |
| 134292 | | - SQLITE_DYNAMIC); |
| 134293 | | - if( str.accError!=SQLITE_OK ){ |
| 134294 | | - sqlite3_result_null(context); |
| 134295 | | - sqlite3_result_error_code(context, str.accError); |
| 134296 | | - } |
| 134575 | + sqlite3_result_str(context, &str, SQLITE_XFER); |
| 134297 | 134576 | } |
| 134298 | 134577 | |
| 134299 | 134578 | /* |
| 134300 | 134579 | ** The unicode() function. Return the integer unicode code-point value |
| 134301 | 134580 | ** for the first character of the input string. |
| | @@ -135324,32 +135603,22 @@ |
| 135324 | 135603 | #endif /* SQLITE_OMIT_WINDOWFUNC */ |
| 135325 | 135604 | static void groupConcatFinalize(sqlite3_context *context){ |
| 135326 | 135605 | GroupConcatCtx *pGCC |
| 135327 | 135606 | = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); |
| 135328 | 135607 | if( pGCC ){ |
| 135329 | | - sqlite3ResultStrAccum(context, &pGCC->str); |
| 135608 | + sqlite3_result_str(context, &pGCC->str, SQLITE_XFER); |
| 135330 | 135609 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 135331 | 135610 | sqlite3_free(pGCC->pnSepLengths); |
| 135332 | 135611 | #endif |
| 135333 | 135612 | } |
| 135334 | 135613 | } |
| 135335 | 135614 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 135336 | 135615 | static void groupConcatValue(sqlite3_context *context){ |
| 135337 | 135616 | GroupConcatCtx *pGCC |
| 135338 | 135617 | = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); |
| 135339 | | - if( pGCC ){ |
| 135340 | | - StrAccum *pAccum = &pGCC->str; |
| 135341 | | - if( pAccum->accError==SQLITE_TOOBIG ){ |
| 135342 | | - sqlite3_result_error_toobig(context); |
| 135343 | | - }else if( pAccum->accError==SQLITE_NOMEM ){ |
| 135344 | | - sqlite3_result_error_nomem(context); |
| 135345 | | - }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ |
| 135346 | | - sqlite3_result_text(context, "", 1, SQLITE_STATIC); |
| 135347 | | - }else{ |
| 135348 | | - const char *zText = sqlite3_str_value(pAccum); |
| 135349 | | - sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); |
| 135350 | | - } |
| 135618 | + if( pGCC && pGCC->nAccum>0 ){ |
| 135619 | + sqlite3_result_str(context, &pGCC->str, SQLITE_COPY); |
| 135351 | 135620 | } |
| 135352 | 135621 | } |
| 135353 | 135622 | #else |
| 135354 | 135623 | # define groupConcatValue 0 |
| 135355 | 135624 | #endif /* SQLITE_OMIT_WINDOWFUNC */ |
| | @@ -136190,12 +136459,11 @@ |
| 136190 | 136459 | sqlite3_str_appendall(pStr, ",\"journal\":"); |
| 136191 | 136460 | rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr); |
| 136192 | 136461 | if( rc ) sqlite3_str_append(pStr, "null", 4); |
| 136193 | 136462 | } |
| 136194 | 136463 | sqlite3_str_append(pStr, "}", 1); |
| 136195 | | - sqlite3_result_text(context, sqlite3_str_finish(pStr), -1, |
| 136196 | | - sqlite3_free); |
| 136464 | + sqlite3_result_str(context, pStr, SQLITE_FINISH); |
| 136197 | 136465 | } |
| 136198 | 136466 | sqlite3BtreeLeave(pBtree); |
| 136199 | 136467 | }else{ |
| 136200 | 136468 | sqlite3_result_text(context, "{}", 2, SQLITE_STATIC); |
| 136201 | 136469 | } |
| | @@ -136307,12 +136575,12 @@ |
| 136307 | 136575 | }else{ |
| 136308 | 136576 | sqlite3_str_appendf(pResult, ", NULL"); |
| 136309 | 136577 | } |
| 136310 | 136578 | } |
| 136311 | 136579 | } |
| 136312 | | - sqlite3_result_text(ctx, sqlite3_str_finish(pResult), -1, sqlite3_free); |
| 136313 | 136580 | } |
| 136581 | + sqlite3_result_str(ctx, pResult, SQLITE_FINISH); |
| 136314 | 136582 | sqlite3_free_filename(zFile); |
| 136315 | 136583 | sqlite3_free(zErr); |
| 136316 | 136584 | } |
| 136317 | 136585 | #endif /* SQLITE_DEBUG */ |
| 136318 | 136586 | |
| | @@ -136405,11 +136673,11 @@ |
| 136405 | 136673 | VFUNCTION(random, 0, 0, 0, randomFunc ), |
| 136406 | 136674 | VFUNCTION(randomblob, 1, 0, 0, randomBlob ), |
| 136407 | 136675 | FUNCTION(nullif, 2, 0, 1, nullifFunc ), |
| 136408 | 136676 | DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), |
| 136409 | 136677 | DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), |
| 136410 | | - FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), |
| 136678 | + SFUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), |
| 136411 | 136679 | FUNCTION(unistr, 1, 0, 0, unistrFunc ), |
| 136412 | 136680 | FUNCTION(quote, 1, 0, 0, quoteFunc ), |
| 136413 | 136681 | FUNCTION(unistr_quote, 1, 1, 0, quoteFunc ), |
| 136414 | 136682 | VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), |
| 136415 | 136683 | VFUNCTION(changes, 0, 0, 0, changes ), |
| | @@ -138454,19 +138722,23 @@ |
| 138454 | 138722 | pParse->nErr++; |
| 138455 | 138723 | pParse->rc = SQLITE_CORRUPT_SEQUENCE; |
| 138456 | 138724 | return 0; |
| 138457 | 138725 | } |
| 138458 | 138726 | |
| 138727 | + if( pToplevel->usesAinc==0 ){ |
| 138728 | + pToplevel->pAinc = 0; |
| 138729 | + } |
| 138459 | 138730 | pInfo = pToplevel->pAinc; |
| 138460 | 138731 | while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } |
| 138461 | 138732 | if( pInfo==0 ){ |
| 138462 | 138733 | pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); |
| 138463 | 138734 | sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo); |
| 138464 | 138735 | testcase( pParse->earlyCleanup ); |
| 138465 | 138736 | if( pParse->db->mallocFailed ) return 0; |
| 138466 | 138737 | pInfo->pNext = pToplevel->pAinc; |
| 138467 | 138738 | pToplevel->pAinc = pInfo; |
| 138739 | + pToplevel->usesAinc = 1; |
| 138468 | 138740 | pInfo->pTab = pTab; |
| 138469 | 138741 | pInfo->iDb = iDb; |
| 138470 | 138742 | pToplevel->nMem++; /* Register to hold name of table */ |
| 138471 | 138743 | pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ |
| 138472 | 138744 | pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */ |
| | @@ -138491,10 +138763,11 @@ |
| 138491 | 138763 | ** only called from the top-level */ |
| 138492 | 138764 | assert( pParse->pTriggerTab==0 ); |
| 138493 | 138765 | assert( sqlite3IsToplevel(pParse) ); |
| 138494 | 138766 | |
| 138495 | 138767 | assert( v ); /* We failed long ago if this is not so */ |
| 138768 | + assert( pParse->usesAinc ); |
| 138496 | 138769 | for(p = pParse->pAinc; p; p = p->pNext){ |
| 138497 | 138770 | static const int iLn = VDBE_OFFSET_LINENO(2); |
| 138498 | 138771 | static const VdbeOpList autoInc[] = { |
| 138499 | 138772 | /* 0 */ {OP_Null, 0, 0, 0}, |
| 138500 | 138773 | /* 1 */ {OP_Rewind, 0, 10, 0}, |
| | @@ -138558,10 +138831,11 @@ |
| 138558 | 138831 | AutoincInfo *p; |
| 138559 | 138832 | Vdbe *v = pParse->pVdbe; |
| 138560 | 138833 | sqlite3 *db = pParse->db; |
| 138561 | 138834 | |
| 138562 | 138835 | assert( v ); |
| 138836 | + assert( pParse->usesAinc ); |
| 138563 | 138837 | for(p = pParse->pAinc; p; p = p->pNext){ |
| 138564 | 138838 | static const int iLn = VDBE_OFFSET_LINENO(2); |
| 138565 | 138839 | static const VdbeOpList autoIncEnd[] = { |
| 138566 | 138840 | /* 0 */ {OP_NotNull, 0, 2, 0}, |
| 138567 | 138841 | /* 1 */ {OP_NewRowid, 0, 0, 0}, |
| | @@ -138590,11 +138864,11 @@ |
| 138590 | 138864 | aOp[3].p5 = OPFLAG_APPEND; |
| 138591 | 138865 | sqlite3ReleaseTempReg(pParse, iRec); |
| 138592 | 138866 | } |
| 138593 | 138867 | } |
| 138594 | 138868 | SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ |
| 138595 | | - if( pParse->pAinc ) autoIncrementEnd(pParse); |
| 138869 | + if( pParse->usesAinc ) autoIncrementEnd(pParse); |
| 138596 | 138870 | } |
| 138597 | 138871 | #else |
| 138598 | 138872 | /* |
| 138599 | 138873 | ** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines |
| 138600 | 138874 | ** above are all no-ops |
| | @@ -142023,10 +142297,11 @@ |
| 142023 | 142297 | void (*str_free)(sqlite3_str*); |
| 142024 | 142298 | int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*)); |
| 142025 | 142299 | int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*); |
| 142026 | 142300 | /* Version 3.54.0 and later */ |
| 142027 | 142301 | sqlite3_int64 (*incomplete)(const char*); |
| 142302 | + void (*result_str)(sqlite3_context*,sqlite3_str*,int); |
| 142028 | 142303 | }; |
| 142029 | 142304 | |
| 142030 | 142305 | /* |
| 142031 | 142306 | ** This is the function signature used for all extension entry points. It |
| 142032 | 142307 | ** is also defined in the file "loadext.c". |
| | @@ -142368,10 +142643,11 @@ |
| 142368 | 142643 | #define sqlite3_str_free sqlite3_api->str_free |
| 142369 | 142644 | #define sqlite3_carray_bind sqlite3_api->carray_bind |
| 142370 | 142645 | #define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2 |
| 142371 | 142646 | /* Version 3.54.0 and later */ |
| 142372 | 142647 | #define sqlite3_incomplete sqlite3_api->incomplete |
| 142648 | +#define sqlite3_result_str sqlite3_api->result_str |
| 142373 | 142649 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 142374 | 142650 | |
| 142375 | 142651 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 142376 | 142652 | /* This case when the file really is being compiled as a loadable |
| 142377 | 142653 | ** extension */ |
| | @@ -142905,11 +143181,13 @@ |
| 142905 | 143181 | sqlite3_carray_bind_v2, |
| 142906 | 143182 | #else |
| 142907 | 143183 | 0, |
| 142908 | 143184 | 0, |
| 142909 | 143185 | #endif |
| 142910 | | - sqlite3_incomplete |
| 143186 | + /* Version 3.54.0 and later */ |
| 143187 | + sqlite3_incomplete, |
| 143188 | + sqlite3_result_str |
| 142911 | 143189 | }; |
| 142912 | 143190 | |
| 142913 | 143191 | /* True if x is the directory separator character |
| 142914 | 143192 | */ |
| 142915 | 143193 | #if SQLITE_OS_WIN |
| | @@ -147674,11 +147952,11 @@ |
| 147674 | 147952 | sqlite3 *db = pParse->db; |
| 147675 | 147953 | assert( db!=0 ); |
| 147676 | 147954 | assert( db->pParse==pParse ); |
| 147677 | 147955 | assert( pParse->nested==0 ); |
| 147678 | 147956 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| 147679 | | - if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); |
| 147957 | + if( pParse->nTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); |
| 147680 | 147958 | #endif |
| 147681 | 147959 | while( pParse->pCleanup ){ |
| 147682 | 147960 | ParseCleanup *pCleanup = pParse->pCleanup; |
| 147683 | 147961 | pParse->pCleanup = pCleanup->pNext; |
| 147684 | 147962 | pCleanup->xCleanup(db, pCleanup->pPtr); |
| | @@ -148157,11 +148435,11 @@ |
| 148157 | 148435 | int nBytes, /* Length of zSql in bytes. */ |
| 148158 | 148436 | sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ |
| 148159 | 148437 | const void **pzTail /* OUT: End of parsed string */ |
| 148160 | 148438 | ){ |
| 148161 | 148439 | int rc; |
| 148162 | | - rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); |
| 148440 | + rc = sqlite3Prepare16(db,zSql,nBytes&~1,0,ppStmt,pzTail); |
| 148163 | 148441 | assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ |
| 148164 | 148442 | return rc; |
| 148165 | 148443 | } |
| 148166 | 148444 | SQLITE_API int sqlite3_prepare16_v2( |
| 148167 | 148445 | sqlite3 *db, /* Database handle. */ |
| | @@ -148169,11 +148447,11 @@ |
| 148169 | 148447 | int nBytes, /* Length of zSql in bytes. */ |
| 148170 | 148448 | sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ |
| 148171 | 148449 | const void **pzTail /* OUT: End of parsed string */ |
| 148172 | 148450 | ){ |
| 148173 | 148451 | int rc; |
| 148174 | | - rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); |
| 148452 | + rc = sqlite3Prepare16(db,zSql,nBytes&~1,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); |
| 148175 | 148453 | assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ |
| 148176 | 148454 | return rc; |
| 148177 | 148455 | } |
| 148178 | 148456 | SQLITE_API int sqlite3_prepare16_v3( |
| 148179 | 148457 | sqlite3 *db, /* Database handle. */ |
| | @@ -148182,11 +148460,11 @@ |
| 148182 | 148460 | unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ |
| 148183 | 148461 | sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ |
| 148184 | 148462 | const void **pzTail /* OUT: End of parsed string */ |
| 148185 | 148463 | ){ |
| 148186 | 148464 | int rc; |
| 148187 | | - rc = sqlite3Prepare16(db,zSql,nBytes, |
| 148465 | + rc = sqlite3Prepare16(db,zSql,nBytes&~1, |
| 148188 | 148466 | SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), |
| 148189 | 148467 | ppStmt,pzTail); |
| 148190 | 148468 | assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ |
| 148191 | 148469 | return rc; |
| 148192 | 148470 | } |
| | @@ -148855,11 +149133,12 @@ |
| 148855 | 149133 | pRight->u3.pOn = 0; |
| 148856 | 149134 | pRight->fg.isOn = 1; |
| 148857 | 149135 | p->selFlags |= SF_OnToWhere; |
| 148858 | 149136 | } |
| 148859 | 149137 | |
| 148860 | | - if( IsVirtual(pRightTab) && joinType==EP_OuterON && pRight->u1.pFuncArg ){ |
| 149138 | + if( pRight->fg.isTabFunc && joinType==EP_OuterON && pRight->u1.pFuncArg ){ |
| 149139 | + assert( IsVirtual(pRightTab) ); |
| 148861 | 149140 | p->selFlags |= SF_OnToWhere; |
| 148862 | 149141 | } |
| 148863 | 149142 | } |
| 148864 | 149143 | return 0; |
| 148865 | 149144 | } |
| | @@ -161225,10 +161504,11 @@ |
| 161225 | 161504 | SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ |
| 161226 | 161505 | HashElem *pThis, *pNext; |
| 161227 | 161506 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 161228 | 161507 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 161229 | 161508 | #endif |
| 161509 | + sqlite3_mutex_enter(db->mutex); |
| 161230 | 161510 | for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ |
| 161231 | 161511 | Module *pMod = (Module*)sqliteHashData(pThis); |
| 161232 | 161512 | pNext = sqliteHashNext(pThis); |
| 161233 | 161513 | if( azNames ){ |
| 161234 | 161514 | int ii; |
| | @@ -161235,10 +161515,11 @@ |
| 161235 | 161515 | for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){} |
| 161236 | 161516 | if( azNames[ii]!=0 ) continue; |
| 161237 | 161517 | } |
| 161238 | 161518 | createModule(db, pMod->zName, 0, 0, 0); |
| 161239 | 161519 | } |
| 161520 | + sqlite3_mutex_leave(db->mutex); |
| 161240 | 161521 | return SQLITE_OK; |
| 161241 | 161522 | } |
| 161242 | 161523 | |
| 161243 | 161524 | /* |
| 161244 | 161525 | ** Decrement the reference count on a Module object. Destroy the |
| | @@ -167001,33 +167282,62 @@ |
| 167001 | 167282 | } |
| 167002 | 167283 | } |
| 167003 | 167284 | } |
| 167004 | 167285 | } |
| 167005 | 167286 | |
| 167006 | | - /* At this point, okToChngToIN is true if original pTerm satisfies |
| 167007 | | - ** case 1. In that case, construct a new virtual term that is |
| 167008 | | - ** pTerm converted into an IN operator. |
| 167287 | + /* At this point, okToChngToIN is true if original pTerm is a |
| 167288 | + ** candidate to satisfy case 1, though we are not yet certain that |
| 167289 | + ** the collating sequences are all compatible. Try to construct a |
| 167290 | + ** new virtual term that is pTerm converted from an OR operator |
| 167291 | + ** into an IN operator. |
| 167292 | + ** |
| 167293 | + ** During construction, verify that the collating sequences on all |
| 167294 | + ** subterms of the OR are compatible. Omit the construction of the |
| 167295 | + ** new IN operator if there are any collating sequence mismatches. |
| 167009 | 167296 | */ |
| 167010 | 167297 | if( okToChngToIN ){ |
| 167011 | 167298 | Expr *pDup; /* A transient duplicate expression */ |
| 167012 | 167299 | ExprList *pList = 0; /* The RHS of the IN operator */ |
| 167013 | 167300 | Expr *pLeft = 0; /* The LHS of the IN operator */ |
| 167301 | + CollSeq *pCollSeq = 0; /* Collating sequence to use */ |
| 167014 | 167302 | Expr *pNew; /* The complete IN operator */ |
| 167015 | 167303 | |
| 167016 | 167304 | for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ |
| 167305 | + Expr *pThis; |
| 167017 | 167306 | if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue; |
| 167018 | 167307 | assert( pOrTerm->eOperator & WO_EQ ); |
| 167019 | 167308 | assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); |
| 167020 | 167309 | assert( pOrTerm->leftCursor==iCursor ); |
| 167021 | 167310 | assert( pOrTerm->u.x.leftColumn==iColumn ); |
| 167022 | | - pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); |
| 167311 | + pThis = pOrTerm->pExpr; |
| 167312 | + pDup = sqlite3ExprDup(db, pThis->pRight, 0); |
| 167023 | 167313 | pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); |
| 167024 | | - pLeft = pOrTerm->pExpr->pLeft; |
| 167314 | + if( pLeft==0 ){ |
| 167315 | + pLeft = pThis->pLeft; |
| 167316 | + pCollSeq = sqlite3ExprCompareCollSeq(pParse, pThis); |
| 167317 | + }else{ |
| 167318 | + assert( 0==sqlite3ExprCompare(pParse, |
| 167319 | + sqlite3ExprSkipCollate(pThis->pLeft), |
| 167320 | + sqlite3ExprSkipCollate(pLeft), -1) ); |
| 167321 | + if( pCollSeq!=sqlite3ExprCompareCollSeq(pParse, pThis) ){ |
| 167322 | + pLeft = 0; /* Collating sequence mismatch */ |
| 167323 | + break; |
| 167324 | + } |
| 167325 | + } |
| 167025 | 167326 | } |
| 167026 | | - assert( pLeft!=0 ); |
| 167027 | | - pDup = sqlite3ExprDup(db, pLeft, 0); |
| 167028 | | - pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); |
| 167327 | + if( pLeft==0 ){ |
| 167328 | + pNew = 0; /* Collating sequence mismatch */ |
| 167329 | + }else{ |
| 167330 | + pDup = sqlite3ExprDup(db, pLeft, 0); |
| 167331 | + if( sqlite3ExprCollSeq(pParse, pDup)!=pCollSeq |
| 167332 | + && ALWAYS(pCollSeq!=0) |
| 167333 | + ){ |
| 167334 | + assert( pCollSeq->zName!=0 ); |
| 167335 | + pDup = sqlite3ExprAddCollateString(pParse, pDup, pCollSeq->zName); |
| 167336 | + } |
| 167337 | + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); |
| 167338 | + } |
| 167029 | 167339 | if( pNew ){ |
| 167030 | 167340 | int idxNew; |
| 167031 | 167341 | transferJoinMarkings(pNew, pExpr); |
| 167032 | 167342 | assert( ExprUseXList(pNew) ); |
| 167033 | 167343 | pNew->x.pList = pList; |
| | @@ -175432,10 +175742,15 @@ |
| 175432 | 175742 | } |
| 175433 | 175743 | sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, |
| 175434 | 175744 | (u8*)&colUsed, P4_INT64); |
| 175435 | 175745 | } |
| 175436 | 175746 | #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ |
| 175747 | +#ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 175748 | + if( HasRowid(pTab) ){ |
| 175749 | + sqlite3VdbeAddOp3(v, OP_CursorHint, iIndexCur, 0, pTabItem->iCursor); |
| 175750 | + } |
| 175751 | +#endif |
| 175437 | 175752 | } |
| 175438 | 175753 | } |
| 175439 | 175754 | if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); |
| 175440 | 175755 | if( (pTabItem->fg.jointype & JT_RIGHT)!=0 |
| 175441 | 175756 | && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 |
| | @@ -176155,11 +176470,11 @@ |
| 176155 | 176470 | case SQLITE_INTEGER: |
| 176156 | 176471 | iVal = sqlite3_value_int64(apArg[1]); |
| 176157 | 176472 | break; |
| 176158 | 176473 | case SQLITE_FLOAT: { |
| 176159 | 176474 | double fVal = sqlite3_value_double(apArg[1]); |
| 176160 | | - if( ((i64)fVal)!=fVal ) goto error_out; |
| 176475 | + if( sqlite3RealToI64(fVal)!=fVal ) goto error_out; |
| 176161 | 176476 | iVal = (i64)fVal; |
| 176162 | 176477 | break; |
| 176163 | 176478 | } |
| 176164 | 176479 | default: |
| 176165 | 176480 | goto error_out; |
| | @@ -187755,17 +188070,21 @@ |
| 187755 | 188070 | |
| 187756 | 188071 | /* |
| 187757 | 188072 | ** Return the ROWID of the most recent insert |
| 187758 | 188073 | */ |
| 187759 | 188074 | SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ |
| 188075 | + i64 iRet; |
| 187760 | 188076 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 187761 | 188077 | if( !sqlite3SafetyCheckOk(db) ){ |
| 187762 | 188078 | (void)SQLITE_MISUSE_BKPT; |
| 187763 | 188079 | return 0; |
| 187764 | 188080 | } |
| 187765 | 188081 | #endif |
| 187766 | | - return db->lastRowid; |
| 188082 | + sqlite3_mutex_enter(db->mutex); |
| 188083 | + iRet = db->lastRowid; |
| 188084 | + sqlite3_mutex_leave(db->mutex); |
| 188085 | + return iRet; |
| 187767 | 188086 | } |
| 187768 | 188087 | |
| 187769 | 188088 | /* |
| 187770 | 188089 | ** Set the value returned by the sqlite3_last_insert_rowid() API function. |
| 187771 | 188090 | */ |
| | @@ -187784,33 +188103,41 @@ |
| 187784 | 188103 | /* |
| 187785 | 188104 | ** Return the number of changes in the most recently executed DML |
| 187786 | 188105 | ** statement. |
| 187787 | 188106 | */ |
| 187788 | 188107 | SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){ |
| 188108 | + i64 iRet; |
| 187789 | 188109 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 187790 | 188110 | if( !sqlite3SafetyCheckOk(db) ){ |
| 187791 | 188111 | (void)SQLITE_MISUSE_BKPT; |
| 187792 | 188112 | return 0; |
| 187793 | 188113 | } |
| 187794 | 188114 | #endif |
| 187795 | | - return db->nChange; |
| 188115 | + sqlite3_mutex_enter(db->mutex); |
| 188116 | + iRet = db->nChange; |
| 188117 | + sqlite3_mutex_leave(db->mutex); |
| 188118 | + return iRet; |
| 187796 | 188119 | } |
| 187797 | 188120 | SQLITE_API int sqlite3_changes(sqlite3 *db){ |
| 187798 | 188121 | return (int)sqlite3_changes64(db); |
| 187799 | 188122 | } |
| 187800 | 188123 | |
| 187801 | 188124 | /* |
| 187802 | 188125 | ** Return the number of changes since the database handle was opened. |
| 187803 | 188126 | */ |
| 187804 | 188127 | SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ |
| 188128 | + i64 iRet; |
| 187805 | 188129 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 187806 | 188130 | if( !sqlite3SafetyCheckOk(db) ){ |
| 187807 | 188131 | (void)SQLITE_MISUSE_BKPT; |
| 187808 | 188132 | return 0; |
| 187809 | 188133 | } |
| 187810 | 188134 | #endif |
| 187811 | | - return db->nTotalChange; |
| 188135 | + sqlite3_mutex_enter(db->mutex); |
| 188136 | + iRet = db->nTotalChange; |
| 188137 | + sqlite3_mutex_leave(db->mutex); |
| 188138 | + return iRet; |
| 187812 | 188139 | } |
| 187813 | 188140 | SQLITE_API int sqlite3_total_changes(sqlite3 *db){ |
| 187814 | 188141 | return (int)sqlite3_total_changes64(db); |
| 187815 | 188142 | } |
| 187816 | 188143 | |
| | @@ -188489,10 +188816,11 @@ |
| 188489 | 188816 | */ |
| 188490 | 188817 | SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ |
| 188491 | 188818 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 188492 | 188819 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 188493 | 188820 | #endif |
| 188821 | + sqlite3_mutex_enter(db->mutex); |
| 188494 | 188822 | if( ms>0 ){ |
| 188495 | 188823 | sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, |
| 188496 | 188824 | (void*)db); |
| 188497 | 188825 | db->busyTimeout = ms; |
| 188498 | 188826 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| | @@ -188499,10 +188827,11 @@ |
| 188499 | 188827 | db->setlkTimeout = ms; |
| 188500 | 188828 | #endif |
| 188501 | 188829 | }else{ |
| 188502 | 188830 | sqlite3_busy_handler(db, 0, 0); |
| 188503 | 188831 | } |
| 188832 | + sqlite3_mutex_leave(db->mutex); |
| 188504 | 188833 | return SQLITE_OK; |
| 188505 | 188834 | } |
| 188506 | 188835 | |
| 188507 | 188836 | /* |
| 188508 | 188837 | ** Set the setlk timeout value. |
| | @@ -189404,13 +189733,15 @@ |
| 189404 | 189733 | /* |
| 189405 | 189734 | ** Return the byte offset of the most recent error |
| 189406 | 189735 | */ |
| 189407 | 189736 | SQLITE_API int sqlite3_error_offset(sqlite3 *db){ |
| 189408 | 189737 | int iOffset = -1; |
| 189409 | | - if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){ |
| 189738 | + if( db && sqlite3SafetyCheckSickOrOk(db) ){ |
| 189410 | 189739 | sqlite3_mutex_enter(db->mutex); |
| 189411 | | - iOffset = db->errByteOffset; |
| 189740 | + if( db->errCode ){ |
| 189741 | + iOffset = db->errByteOffset; |
| 189742 | + } |
| 189412 | 189743 | sqlite3_mutex_leave(db->mutex); |
| 189413 | 189744 | } |
| 189414 | 189745 | return iOffset; |
| 189415 | 189746 | } |
| 189416 | 189747 | |
| | @@ -189460,29 +189791,47 @@ |
| 189460 | 189791 | /* |
| 189461 | 189792 | ** Return the most recent error code generated by an SQLite routine. If NULL is |
| 189462 | 189793 | ** passed to this function, we assume a malloc() failed during sqlite3_open(). |
| 189463 | 189794 | */ |
| 189464 | 189795 | SQLITE_API int sqlite3_errcode(sqlite3 *db){ |
| 189465 | | - if( db && !sqlite3SafetyCheckSickOrOk(db) ){ |
| 189796 | + int iRet; |
| 189797 | + if( !db ) return SQLITE_NOMEM_BKPT; |
| 189798 | + if( !sqlite3SafetyCheckSickOrOk(db) ){ |
| 189466 | 189799 | return SQLITE_MISUSE_BKPT; |
| 189467 | 189800 | } |
| 189468 | | - if( !db || db->mallocFailed ){ |
| 189469 | | - return SQLITE_NOMEM_BKPT; |
| 189801 | + sqlite3_mutex_enter(db->mutex); |
| 189802 | + if( db->mallocFailed ){ |
| 189803 | + iRet = SQLITE_NOMEM_BKPT; |
| 189804 | + }else{ |
| 189805 | + iRet = db->errCode & db->errMask; |
| 189470 | 189806 | } |
| 189471 | | - return db->errCode & db->errMask; |
| 189807 | + sqlite3_mutex_leave(db->mutex); |
| 189808 | + return iRet; |
| 189472 | 189809 | } |
| 189473 | 189810 | SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ |
| 189474 | | - if( db && !sqlite3SafetyCheckSickOrOk(db) ){ |
| 189811 | + int iRet; |
| 189812 | + if( !db ) return SQLITE_NOMEM_BKPT; |
| 189813 | + if( !sqlite3SafetyCheckSickOrOk(db) ){ |
| 189475 | 189814 | return SQLITE_MISUSE_BKPT; |
| 189476 | 189815 | } |
| 189477 | | - if( !db || db->mallocFailed ){ |
| 189478 | | - return SQLITE_NOMEM_BKPT; |
| 189816 | + sqlite3_mutex_enter(db->mutex); |
| 189817 | + if( db->mallocFailed ){ |
| 189818 | + iRet = SQLITE_NOMEM_BKPT; |
| 189819 | + }else{ |
| 189820 | + iRet = db->errCode; |
| 189479 | 189821 | } |
| 189480 | | - return db->errCode; |
| 189822 | + sqlite3_mutex_leave(db->mutex); |
| 189823 | + return iRet; |
| 189481 | 189824 | } |
| 189482 | 189825 | SQLITE_API int sqlite3_system_errno(sqlite3 *db){ |
| 189483 | | - return db ? db->iSysErrno : 0; |
| 189826 | + int iRet = 0; |
| 189827 | + if( db ){ |
| 189828 | + sqlite3_mutex_enter(db->mutex); |
| 189829 | + iRet = db->iSysErrno; |
| 189830 | + sqlite3_mutex_leave(db->mutex); |
| 189831 | + } |
| 189832 | + return iRet; |
| 189484 | 189833 | } |
| 189485 | 189834 | |
| 189486 | 189835 | /* |
| 189487 | 189836 | ** Return a string that describes the kind of error specified in the |
| 189488 | 189837 | ** argument. For now, this simply calls the internal sqlite3ErrStr() |
| | @@ -189673,19 +190022,21 @@ |
| 189673 | 190022 | |
| 189674 | 190023 | |
| 189675 | 190024 | if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ |
| 189676 | 190025 | return -1; |
| 189677 | 190026 | } |
| 190027 | + sqlite3_mutex_enter(db->mutex); |
| 189678 | 190028 | oldLimit = db->aLimit[limitId]; |
| 189679 | 190029 | if( newLimit>=0 ){ /* IMP: R-52476-28732 */ |
| 189680 | 190030 | if( newLimit>aHardLimit[limitId] ){ |
| 189681 | 190031 | newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ |
| 189682 | 190032 | }else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){ |
| 189683 | 190033 | newLimit = SQLITE_MIN_LENGTH; |
| 189684 | 190034 | } |
| 189685 | 190035 | db->aLimit[limitId] = newLimit; |
| 189686 | 190036 | } |
| 190037 | + sqlite3_mutex_leave(db->mutex); |
| 189687 | 190038 | return oldLimit; /* IMP: R-53341-35419 */ |
| 189688 | 190039 | } |
| 189689 | 190040 | |
| 189690 | 190041 | /* |
| 189691 | 190042 | ** This function is used to parse both URIs and non-URI filenames passed by the |
| | @@ -189724,22 +190075,22 @@ |
| 189724 | 190075 | int rc = SQLITE_OK; |
| 189725 | 190076 | unsigned int flags = *pFlags; |
| 189726 | 190077 | const char *zVfs = zDefaultVfs; |
| 189727 | 190078 | char *zFile; |
| 189728 | 190079 | char c; |
| 189729 | | - int nUri = sqlite3Strlen30(zUri); |
| 190080 | + i64 nUri = strlen(zUri); |
| 189730 | 190081 | |
| 189731 | 190082 | assert( *pzErrMsg==0 ); |
| 189732 | 190083 | |
| 189733 | 190084 | if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ |
| 189734 | 190085 | || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */ |
| 189735 | 190086 | && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ |
| 189736 | 190087 | ){ |
| 189737 | 190088 | char *zOpt; |
| 189738 | 190089 | int eState; /* Parser state when parsing URI */ |
| 189739 | | - int iIn; /* Input character index */ |
| 189740 | | - int iOut = 0; /* Output character index */ |
| 190090 | + i64 iIn; /* Input character index */ |
| 190091 | + i64 iOut = 0; /* Output character index */ |
| 189741 | 190092 | u64 nByte = nUri+8; /* Bytes of space to allocate */ |
| 189742 | 190093 | |
| 189743 | 190094 | /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen |
| 189744 | 190095 | ** method that there may be extra parameters following the file-name. */ |
| 189745 | 190096 | flags |= SQLITE_OPEN_URI; |
| | @@ -189769,11 +190120,11 @@ |
| 189769 | 190120 | if( zUri[5]=='/' && zUri[6]=='/' ){ |
| 189770 | 190121 | iIn = 7; |
| 189771 | 190122 | while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; |
| 189772 | 190123 | if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ |
| 189773 | 190124 | *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", |
| 189774 | | - iIn-7, &zUri[7]); |
| 190125 | + (int)(iIn-7), &zUri[7]); |
| 189775 | 190126 | rc = SQLITE_ERROR; |
| 189776 | 190127 | goto parse_uri_out; |
| 189777 | 190128 | } |
| 189778 | 190129 | } |
| 189779 | 190130 | #endif |
| | @@ -189844,15 +190195,15 @@ |
| 189844 | 190195 | |
| 189845 | 190196 | /* Check if there were any options specified that should be interpreted |
| 189846 | 190197 | ** here. Options that are interpreted here include "vfs" and those that |
| 189847 | 190198 | ** correspond to flags that may be passed to the sqlite3_open_v2() |
| 189848 | 190199 | ** method. */ |
| 189849 | | - zOpt = &zFile[sqlite3Strlen30(zFile)+1]; |
| 190200 | + zOpt = &zFile[strlen(zFile)+1]; |
| 189850 | 190201 | while( zOpt[0] ){ |
| 189851 | | - int nOpt = sqlite3Strlen30(zOpt); |
| 190202 | + i64 nOpt = strlen(zOpt); |
| 189852 | 190203 | char *zVal = &zOpt[nOpt+1]; |
| 189853 | | - int nVal = sqlite3Strlen30(zVal); |
| 190204 | + i64 nVal = strlen(zVal); |
| 189854 | 190205 | |
| 189855 | 190206 | if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ |
| 189856 | 190207 | zVfs = zVal; |
| 189857 | 190208 | }else{ |
| 189858 | 190209 | struct OpenMode { |
| | @@ -189894,11 +190245,11 @@ |
| 189894 | 190245 | if( aMode ){ |
| 189895 | 190246 | int i; |
| 189896 | 190247 | int mode = 0; |
| 189897 | 190248 | for(i=0; aMode[i].z; i++){ |
| 189898 | 190249 | const char *z = aMode[i].z; |
| 189899 | | - if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ |
| 190250 | + if( nVal==(i64)strlen(z) && 0==memcmp(zVal, z, nVal) ){ |
| 189900 | 190251 | mode = aMode[i].mode; |
| 189901 | 190252 | break; |
| 189902 | 190253 | } |
| 189903 | 190254 | } |
| 189904 | 190255 | if( mode==0 ){ |
| | @@ -190579,17 +190930,21 @@ |
| 190579 | 190930 | ** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on |
| 190580 | 190931 | ** by default. Autocommit is disabled by a BEGIN statement and reenabled |
| 190581 | 190932 | ** by the next COMMIT or ROLLBACK. |
| 190582 | 190933 | */ |
| 190583 | 190934 | SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ |
| 190935 | + int iRet; |
| 190584 | 190936 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 190585 | 190937 | if( !sqlite3SafetyCheckOk(db) ){ |
| 190586 | 190938 | (void)SQLITE_MISUSE_BKPT; |
| 190587 | 190939 | return 0; |
| 190588 | 190940 | } |
| 190589 | 190941 | #endif |
| 190590 | | - return db->autoCommit; |
| 190942 | + sqlite3_mutex_enter(db->mutex); |
| 190943 | + iRet = db->autoCommit; |
| 190944 | + sqlite3_mutex_leave(db->mutex); |
| 190945 | + return iRet; |
| 190591 | 190946 | } |
| 190592 | 190947 | |
| 190593 | 190948 | /* |
| 190594 | 190949 | ** The following routines are substitutes for constants SQLITE_CORRUPT, |
| 190595 | 190950 | ** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error |
| | @@ -191610,21 +191965,23 @@ |
| 191610 | 191965 | /* |
| 191611 | 191966 | ** Return the name of the N-th database schema. Return NULL if N is out |
| 191612 | 191967 | ** of range. |
| 191613 | 191968 | */ |
| 191614 | 191969 | SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){ |
| 191970 | + const char *zRet = 0; |
| 191615 | 191971 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 191616 | 191972 | if( !sqlite3SafetyCheckOk(db) ){ |
| 191617 | 191973 | (void)SQLITE_MISUSE_BKPT; |
| 191618 | 191974 | return 0; |
| 191619 | 191975 | } |
| 191620 | 191976 | #endif |
| 191621 | | - if( N<0 || N>=db->nDb ){ |
| 191622 | | - return 0; |
| 191623 | | - }else{ |
| 191624 | | - return db->aDb[N].zDbSName; |
| 191977 | + sqlite3_mutex_enter(db->mutex); |
| 191978 | + if( N>=0 && N<db->nDb ){ |
| 191979 | + zRet = db->aDb[N].zDbSName; |
| 191625 | 191980 | } |
| 191981 | + sqlite3_mutex_leave(db->mutex); |
| 191982 | + return zRet; |
| 191626 | 191983 | } |
| 191627 | 191984 | |
| 191628 | 191985 | /* |
| 191629 | 191986 | ** Return the filename of the database associated with a database |
| 191630 | 191987 | ** connection. |
| | @@ -197602,10 +197959,11 @@ |
| 197602 | 197959 | }else{ |
| 197603 | 197960 | int nDistance; |
| 197604 | 197961 | char *p1; |
| 197605 | 197962 | char *p2; |
| 197606 | 197963 | char *aOut; |
| 197964 | + i64 nAlloc = (i64)nPoslist*2 + FTS3_BUFFER_PADDING; |
| 197607 | 197965 | |
| 197608 | 197966 | if( nMaxUndeferred>iPrev ){ |
| 197609 | 197967 | p1 = aPoslist; |
| 197610 | 197968 | p2 = pPhrase->doclist.pList; |
| 197611 | 197969 | nDistance = nMaxUndeferred - iPrev; |
| | @@ -197613,11 +197971,11 @@ |
| 197613 | 197971 | p1 = pPhrase->doclist.pList; |
| 197614 | 197972 | p2 = aPoslist; |
| 197615 | 197973 | nDistance = iPrev - nMaxUndeferred; |
| 197616 | 197974 | } |
| 197617 | 197975 | |
| 197618 | | - aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING); |
| 197976 | + aOut = (char *)sqlite3Fts3MallocZero(nAlloc); |
| 197619 | 197977 | if( !aOut ){ |
| 197620 | 197978 | sqlite3_free(aPoslist); |
| 197621 | 197979 | return SQLITE_NOMEM; |
| 197622 | 197980 | } |
| 197623 | 197981 | |
| | @@ -207898,11 +208256,11 @@ |
| 207898 | 208256 | if( nHeight<1 || nHeight>=FTS_MAX_APPENDABLE_HEIGHT ){ |
| 207899 | 208257 | sqlite3_reset(pSelect); |
| 207900 | 208258 | return FTS_CORRUPT_VTAB; |
| 207901 | 208259 | } |
| 207902 | 208260 | |
| 207903 | | - pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; |
| 208261 | + pWriter->nLeafEst = (int)(((iEnd - iStart)+1)/FTS_MAX_APPENDABLE_HEIGHT); |
| 207904 | 208262 | pWriter->iStart = iStart; |
| 207905 | 208263 | pWriter->iEnd = iEnd; |
| 207906 | 208264 | pWriter->iAbsLevel = iAbsLevel; |
| 207907 | 208265 | pWriter->iIdx = iIdx; |
| 207908 | 208266 | |
| | @@ -215418,12 +215776,11 @@ |
| 215418 | 215776 | jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); |
| 215419 | 215777 | } |
| 215420 | 215778 | break; |
| 215421 | 215779 | } |
| 215422 | 215780 | case SQLITE_FLOAT: { |
| 215423 | | - double r = sqlite3_value_double(pArg); |
| 215424 | | - if( NEVER(sqlite3IsNaN(r)) ){ |
| 215781 | + if( NEVER(sqlite3IsNaN(sqlite3_value_double(pArg))) ){ |
| 215425 | 215782 | jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); |
| 215426 | 215783 | }else{ |
| 215427 | 215784 | int n = sqlite3_value_bytes(pArg); |
| 215428 | 215785 | const char *z = (const char*)sqlite3_value_text(pArg); |
| 215429 | 215786 | if( z==0 ) return 1; |
| | @@ -218016,11 +218373,11 @@ |
| 218016 | 218373 | int mxLevel; /* iLevel value for root of the tree */ |
| 218017 | 218374 | RtreeSearchPoint *aPoint; /* Priority queue for search points */ |
| 218018 | 218375 | sqlite3_stmt *pReadAux; /* Statement to read aux-data */ |
| 218019 | 218376 | RtreeSearchPoint sPoint; /* Cached next search point */ |
| 218020 | 218377 | RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ |
| 218021 | | - u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ |
| 218378 | + u32 anQueue[RTREE_MAX_DEPTH+2]; /* Number of queued entries by iLevel */ |
| 218022 | 218379 | }; |
| 218023 | 218380 | |
| 218024 | 218381 | /* Return the Rtree of a RtreeCursor */ |
| 218025 | 218382 | #define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) |
| 218026 | 218383 | |
| | @@ -218499,11 +218856,11 @@ |
| 218499 | 218856 | ** are the leaves, and so on. If the depth as specified on the root node |
| 218500 | 218857 | ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. |
| 218501 | 218858 | */ |
| 218502 | 218859 | if( rc==SQLITE_OK && pNode && iNode==1 ){ |
| 218503 | 218860 | pRtree->iDepth = readInt16(pNode->zData); |
| 218504 | | - if( pRtree->iDepth>RTREE_MAX_DEPTH ){ |
| 218861 | + if( pRtree->iDepth>=RTREE_MAX_DEPTH ){ |
| 218505 | 218862 | rc = SQLITE_CORRUPT_VTAB; |
| 218506 | 218863 | RTREE_IS_CORRUPT(pRtree); |
| 218507 | 218864 | } |
| 218508 | 218865 | } |
| 218509 | 218866 | |
| | @@ -234473,11 +234830,11 @@ |
| 234473 | 234830 | SessionBuffer *p, |
| 234474 | 234831 | const char *zStr, |
| 234475 | 234832 | int *pRc |
| 234476 | 234833 | ){ |
| 234477 | 234834 | int nStr = sqlite3Strlen30(zStr); |
| 234478 | | - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ |
| 234835 | + if( 0==sessionBufferGrow(p, (i64)nStr+1, pRc) ){ |
| 234479 | 234836 | memcpy(&p->aBuf[p->nBuf], zStr, nStr); |
| 234480 | 234837 | p->nBuf += nStr; |
| 234481 | 234838 | p->aBuf[p->nBuf] = 0x00; |
| 234482 | 234839 | } |
| 234483 | 234840 | } |
| | @@ -239875,18 +240232,21 @@ |
| 239875 | 240232 | int nCol, /* Number of columns in each record */ |
| 239876 | 240233 | u8 *a1, int n1, /* Record 1 */ |
| 239877 | 240234 | u8 *a2, int n2, /* Record 2 */ |
| 239878 | 240235 | int *pRc /* IN/OUT: error code */ |
| 239879 | 240236 | ){ |
| 239880 | | - sessionBufferGrow(pBuf, n1+n2, pRc); |
| 240237 | + u8 *a1Eof = &a1[n1]; |
| 240238 | + u8 *a2Eof = &a2[n2]; |
| 240239 | + |
| 240240 | + sessionBufferGrow(pBuf, (i64)n1+n2, pRc); |
| 239881 | 240241 | if( *pRc==SQLITE_OK ){ |
| 239882 | 240242 | int i; |
| 239883 | 240243 | u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; |
| 239884 | 240244 | for(i=0; i<nCol; i++){ |
| 239885 | | - int nn1 = sessionSerialLen(a1); |
| 239886 | | - int nn2 = sessionSerialLen(a2); |
| 239887 | | - if( *a1==0 || *a1==0xFF ){ |
| 240245 | + int nn1 = (a1<a1Eof ? sessionSerialLen(a1) : 0); |
| 240246 | + int nn2 = (a2<a2Eof ? sessionSerialLen(a2) : 0); |
| 240247 | + if( nn1==0 || (nn2>0 && (*a1==0 || *a1==0xFF)) ){ |
| 239888 | 240248 | memcpy(pOut, a2, nn2); |
| 239889 | 240249 | pOut += nn2; |
| 239890 | 240250 | }else{ |
| 239891 | 240251 | memcpy(pOut, a1, nn1); |
| 239892 | 240252 | pOut += nn1; |
| | @@ -239924,11 +240284,11 @@ |
| 239924 | 240284 | sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */ |
| 239925 | 240285 | u8 *aRec, int nRec, /* Local change */ |
| 239926 | 240286 | u8 *aChange, int nChange, /* Record to rebase against */ |
| 239927 | 240287 | int *pRc /* IN/OUT: Return Code */ |
| 239928 | 240288 | ){ |
| 239929 | | - sessionBufferGrow(pBuf, 2+nRec+nChange, pRc); |
| 240289 | + sessionBufferGrow(pBuf, (i64)2+nRec+nChange, pRc); |
| 239930 | 240290 | if( *pRc==SQLITE_OK ){ |
| 239931 | 240291 | int bData = 0; |
| 239932 | 240292 | u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; |
| 239933 | 240293 | int i; |
| 239934 | 240294 | u8 *a1 = aRec; |
| | @@ -258623,13 +258983,17 @@ |
| 258623 | 258983 | iRowidOff = fts5LeafFirstRowidOff(pLeaf); |
| 258624 | 258984 | if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){ |
| 258625 | 258985 | FTS5_CORRUPT_ROWID(p, iRow); |
| 258626 | 258986 | }else{ |
| 258627 | 258987 | iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm); |
| 258628 | | - res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); |
| 258629 | | - if( res==0 ) res = nTerm - nIdxTerm; |
| 258630 | | - if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow); |
| 258988 | + if( iOff+nTerm>pLeaf->szLeaf ){ |
| 258989 | + FTS5_CORRUPT_ROWID(p, iRow); |
| 258990 | + }else{ |
| 258991 | + res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); |
| 258992 | + if( res==0 ) res = nTerm - nIdxTerm; |
| 258993 | + if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow); |
| 258994 | + } |
| 258631 | 258995 | } |
| 258632 | 258996 | |
| 258633 | 258997 | fts5IntegrityCheckPgidx(p, iRow, pLeaf); |
| 258634 | 258998 | } |
| 258635 | 258999 | fts5DataRelease(pLeaf); |
| | @@ -263267,11 +263631,11 @@ |
| 263267 | 263631 | int nArg, /* Number of args */ |
| 263268 | 263632 | sqlite3_value **apUnused /* Function arguments */ |
| 263269 | 263633 | ){ |
| 263270 | 263634 | assert( nArg==0 ); |
| 263271 | 263635 | UNUSED_PARAM2(nArg, apUnused); |
| 263272 | | - sqlite3_result_text(pCtx, "fts5: 2026-06-16 13:43:08 3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06", -1, SQLITE_TRANSIENT); |
| 263636 | + sqlite3_result_text(pCtx, "fts5: 2026-06-26 19:31:46 716782abe939083b7732289d862ddfd841057d3458814f96e5e6d7826ec7fa5c", -1, SQLITE_TRANSIENT); |
| 263273 | 263637 | } |
| 263274 | 263638 | |
| 263275 | 263639 | /* |
| 263276 | 263640 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 263277 | 263641 | ** |
| | @@ -263909,38 +264273,35 @@ |
| 263909 | 264273 | |
| 263910 | 264274 | if( bCreate ){ |
| 263911 | 264275 | if( pConfig->eContent==FTS5_CONTENT_NORMAL |
| 263912 | 264276 | || pConfig->eContent==FTS5_CONTENT_UNINDEXED |
| 263913 | 264277 | ){ |
| 263914 | | - int nDefn = 32 + pConfig->nCol*10; |
| 263915 | | - char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); |
| 263916 | | - if( zDefn==0 ){ |
| 263917 | | - rc = SQLITE_NOMEM; |
| 263918 | | - }else{ |
| 263919 | | - int i; |
| 263920 | | - int iOff; |
| 263921 | | - sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); |
| 263922 | | - iOff = (int)strlen(zDefn); |
| 263923 | | - for(i=0; i<pConfig->nCol; i++){ |
| 263924 | | - if( pConfig->eContent==FTS5_CONTENT_NORMAL |
| 263925 | | - || pConfig->abUnindexed[i] |
| 263926 | | - ){ |
| 263927 | | - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); |
| 263928 | | - iOff += (int)strlen(&zDefn[iOff]); |
| 263929 | | - } |
| 263930 | | - } |
| 263931 | | - if( pConfig->bLocale ){ |
| 263932 | | - for(i=0; i<pConfig->nCol; i++){ |
| 263933 | | - if( pConfig->abUnindexed[i]==0 ){ |
| 263934 | | - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); |
| 263935 | | - iOff += (int)strlen(&zDefn[iOff]); |
| 263936 | | - } |
| 263937 | | - } |
| 263938 | | - } |
| 263939 | | - rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); |
| 263940 | | - } |
| 263941 | | - sqlite3_free(zDefn); |
| 264278 | + int i = 0; |
| 264279 | + char *zDefn = 0; |
| 264280 | + sqlite3_str *pDefn = sqlite3_str_new(pConfig->db); |
| 264281 | + |
| 264282 | + sqlite3_str_appendf(pDefn, "id INTEGER PRIMARY KEY"); |
| 264283 | + for(i=0; i<pConfig->nCol; i++){ |
| 264284 | + if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->abUnindexed[i] ){ |
| 264285 | + sqlite3_str_appendf(pDefn, ", c%d", i); |
| 264286 | + } |
| 264287 | + } |
| 264288 | + if( pConfig->bLocale ){ |
| 264289 | + for(i=0; i<pConfig->nCol; i++){ |
| 264290 | + if( pConfig->abUnindexed[i]==0 ){ |
| 264291 | + sqlite3_str_appendf(pDefn, ", l%d", i); |
| 264292 | + } |
| 264293 | + } |
| 264294 | + } |
| 264295 | + zDefn = sqlite3_str_finish(pDefn); |
| 264296 | + |
| 264297 | + if( zDefn ){ |
| 264298 | + rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); |
| 264299 | + sqlite3_free(zDefn); |
| 264300 | + }else{ |
| 264301 | + rc = SQLITE_NOMEM; |
| 264302 | + } |
| 263942 | 264303 | } |
| 263943 | 264304 | |
| 263944 | 264305 | if( rc==SQLITE_OK && pConfig->bColumnsize ){ |
| 263945 | 264306 | const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB"; |
| 263946 | 264307 | if( pConfig->bContentlessDelete ){ |
| 263947 | 264308 | |