| | @@ -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 | | -** 9f184f8dfa5ef6d57e10376adc30e0060ced with changes in files: |
| 21 | +** cf7163f82ca380958a79350473b2c5a2cebd with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -465,11 +465,11 @@ |
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | | -#define SQLITE_SOURCE_ID "2025-07-15 19:00:01 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839" |
| 470 | +#define SQLITE_SOURCE_ID "2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1" |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| | @@ -814,10 +814,13 @@ |
| 814 | 814 | ** [sqlite3_extended_errcode()]. |
| 815 | 815 | */ |
| 816 | 816 | #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) |
| 817 | 817 | #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) |
| 818 | 818 | #define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) |
| 819 | +#define SQLITE_ERROR_RESERVESIZE (SQLITE_ERROR | (4<<8)) |
| 820 | +#define SQLITE_ERROR_KEY (SQLITE_ERROR | (5<<8)) |
| 821 | +#define SQLITE_ERROR_UNABLE (SQLITE_ERROR | (6<<8)) |
| 819 | 822 | #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) |
| 820 | 823 | #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) |
| 821 | 824 | #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) |
| 822 | 825 | #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) |
| 823 | 826 | #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) |
| | @@ -848,10 +851,12 @@ |
| 848 | 851 | #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) |
| 849 | 852 | #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) |
| 850 | 853 | #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) |
| 851 | 854 | #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) |
| 852 | 855 | #define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) |
| 856 | +#define SQLITE_IOERR_BADKEY (SQLITE_IOERR | (35<<8)) |
| 857 | +#define SQLITE_IOERR_CODEC (SQLITE_IOERR | (36<<8)) |
| 853 | 858 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 854 | 859 | #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) |
| 855 | 860 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 856 | 861 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 857 | 862 | #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8)) |
| | @@ -19503,10 +19508,11 @@ |
| 19503 | 19508 | AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ |
| 19504 | 19509 | union { |
| 19505 | 19510 | Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL |
| 19506 | 19511 | ** for a column of an index on an expression */ |
| 19507 | 19512 | Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */ |
| 19513 | + int nReg; /* TK_NULLS: Number of registers to NULL out */ |
| 19508 | 19514 | struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ |
| 19509 | 19515 | int iAddr; /* Subroutine entry address */ |
| 19510 | 19516 | int regReturn; /* Register used to hold return address */ |
| 19511 | 19517 | } sub; |
| 19512 | 19518 | } y; |
| | @@ -21540,10 +21546,11 @@ |
| 21540 | 21546 | SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); |
| 21541 | 21547 | #endif |
| 21542 | 21548 | SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); |
| 21543 | 21549 | SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); |
| 21544 | 21550 | SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); |
| 21551 | +SQLITE_PRIVATE void sqlite3ExprNullRegisterRange(Parse*, int, int); |
| 21545 | 21552 | SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); |
| 21546 | 21553 | SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); |
| 21547 | 21554 | SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); |
| 21548 | 21555 | #define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ |
| 21549 | 21556 | #define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ |
| | @@ -24366,13 +24373,15 @@ |
| 24366 | 24373 | SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); |
| 24367 | 24374 | SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*); |
| 24368 | 24375 | #endif |
| 24369 | 24376 | |
| 24370 | 24377 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 24371 | | -SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); |
| 24378 | +SQLITE_PRIVATE int sqlite3VdbeCheckFkImmediate(Vdbe*); |
| 24379 | +SQLITE_PRIVATE int sqlite3VdbeCheckFkDeferred(Vdbe*); |
| 24372 | 24380 | #else |
| 24373 | | -# define sqlite3VdbeCheckFk(p,i) 0 |
| 24381 | +# define sqlite3VdbeCheckFkImmediate(p) 0 |
| 24382 | +# define sqlite3VdbeCheckFkDeferred(p) 0 |
| 24374 | 24383 | #endif |
| 24375 | 24384 | |
| 24376 | 24385 | #ifdef SQLITE_DEBUG |
| 24377 | 24386 | SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); |
| 24378 | 24387 | SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr); |
| | @@ -32252,11 +32261,25 @@ |
| 32252 | 32261 | length = sqlite3Strlen30(bufpt); |
| 32253 | 32262 | break; |
| 32254 | 32263 | } |
| 32255 | 32264 | } |
| 32256 | 32265 | if( s.sign=='-' ){ |
| 32257 | | - prefix = '-'; |
| 32266 | + if( flag_alternateform |
| 32267 | + && !flag_prefix |
| 32268 | + && xtype==etFLOAT |
| 32269 | + && s.iDP<=iRound |
| 32270 | + ){ |
| 32271 | + /* Suppress the minus sign if all of the following are true: |
| 32272 | + ** * The value displayed is zero |
| 32273 | + ** * The '#' flag is used |
| 32274 | + ** * The '+' flag is not used, and |
| 32275 | + ** * The format is %f |
| 32276 | + */ |
| 32277 | + prefix = 0; |
| 32278 | + }else{ |
| 32279 | + prefix = '-'; |
| 32280 | + } |
| 32258 | 32281 | }else{ |
| 32259 | 32282 | prefix = flag_prefix; |
| 32260 | 32283 | } |
| 32261 | 32284 | |
| 32262 | 32285 | exp = s.iDP-1; |
| | @@ -51192,10 +51215,107 @@ |
| 51192 | 51215 | ** on allocation size granularity boundaries. |
| 51193 | 51216 | ** During sqlite3_os_init() we do a GetSystemInfo() |
| 51194 | 51217 | ** to get the granularity size. |
| 51195 | 51218 | */ |
| 51196 | 51219 | static SYSTEM_INFO winSysInfo; |
| 51220 | + |
| 51221 | +/* |
| 51222 | +** Convert a UTF-8 filename into whatever form the underlying |
| 51223 | +** operating system wants filenames in. Space to hold the result |
| 51224 | +** is obtained from malloc and must be freed by the calling |
| 51225 | +** function |
| 51226 | +** |
| 51227 | +** On Cygwin, 3 possible input forms are accepted: |
| 51228 | +** - If the filename starts with "<drive>:/" or "<drive>:\", |
| 51229 | +** it is converted to UTF-16 as-is. |
| 51230 | +** - If the filename contains '/', it is assumed to be a |
| 51231 | +** Cygwin absolute path, it is converted to a win32 |
| 51232 | +** absolute path in UTF-16. |
| 51233 | +** - Otherwise it must be a filename only, the win32 filename |
| 51234 | +** is returned in UTF-16. |
| 51235 | +** Note: If the function cygwin_conv_path() fails, only |
| 51236 | +** UTF-8 -> UTF-16 conversion will be done. This can only |
| 51237 | +** happen when the file path >32k, in which case winUtf8ToUnicode() |
| 51238 | +** will fail too. |
| 51239 | +*/ |
| 51240 | +static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 51241 | + void *zConverted = 0; |
| 51242 | + if( osIsNT() ){ |
| 51243 | +#ifdef __CYGWIN__ |
| 51244 | + int nChar; |
| 51245 | + LPWSTR zWideFilename; |
| 51246 | + |
| 51247 | + if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51248 | + && winIsDirSep(zFilename[2])) ){ |
| 51249 | + i64 nByte; |
| 51250 | + int convertflag = CCP_POSIX_TO_WIN_W; |
| 51251 | + if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51252 | + nByte = (i64)osCygwin_conv_path(convertflag, |
| 51253 | + zFilename, 0, 0); |
| 51254 | + if( nByte>0 ){ |
| 51255 | + zConverted = sqlite3MallocZero(12+(u64)nByte); |
| 51256 | + if ( zConverted==0 ){ |
| 51257 | + return zConverted; |
| 51258 | + } |
| 51259 | + zWideFilename = zConverted; |
| 51260 | + /* Filenames should be prefixed, except when converted |
| 51261 | + * full path already starts with "\\?\". */ |
| 51262 | + if( osCygwin_conv_path(convertflag, zFilename, |
| 51263 | + zWideFilename+4, nByte)==0 ){ |
| 51264 | + if( (convertflag&CCP_RELATIVE) ){ |
| 51265 | + memmove(zWideFilename, zWideFilename+4, nByte); |
| 51266 | + }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ |
| 51267 | + memcpy(zWideFilename, L"\\\\?\\", 8); |
| 51268 | + }else if( zWideFilename[6]!='?' ){ |
| 51269 | + memmove(zWideFilename+6, zWideFilename+4, nByte); |
| 51270 | + memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 51271 | + }else{ |
| 51272 | + memmove(zWideFilename, zWideFilename+4, nByte); |
| 51273 | + } |
| 51274 | + return zConverted; |
| 51275 | + } |
| 51276 | + sqlite3_free(zConverted); |
| 51277 | + } |
| 51278 | + } |
| 51279 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 51280 | + if( nChar==0 ){ |
| 51281 | + return 0; |
| 51282 | + } |
| 51283 | + zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); |
| 51284 | + if( zWideFilename==0 ){ |
| 51285 | + return 0; |
| 51286 | + } |
| 51287 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 51288 | + zWideFilename, nChar); |
| 51289 | + if( nChar==0 ){ |
| 51290 | + sqlite3_free(zWideFilename); |
| 51291 | + zWideFilename = 0; |
| 51292 | + }else if( nChar>MAX_PATH |
| 51293 | + && winIsDriveLetterAndColon(zFilename) |
| 51294 | + && winIsDirSep(zFilename[2]) ){ |
| 51295 | + memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); |
| 51296 | + zWideFilename[2] = '\\'; |
| 51297 | + memcpy(zWideFilename, L"\\\\?\\", 8); |
| 51298 | + }else if( nChar>MAX_PATH |
| 51299 | + && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 51300 | + && zFilename[2] != '?' ){ |
| 51301 | + memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); |
| 51302 | + memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 51303 | + } |
| 51304 | + zConverted = zWideFilename; |
| 51305 | +#else |
| 51306 | + zConverted = winUtf8ToUnicode(zFilename); |
| 51307 | +#endif /* __CYGWIN__ */ |
| 51308 | + } |
| 51309 | +#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32) |
| 51310 | + else{ |
| 51311 | + zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); |
| 51312 | + } |
| 51313 | +#endif |
| 51314 | + /* caller will handle out of memory */ |
| 51315 | + return zConverted; |
| 51316 | +} |
| 51197 | 51317 | |
| 51198 | 51318 | #ifndef SQLITE_OMIT_WAL |
| 51199 | 51319 | |
| 51200 | 51320 | /* |
| 51201 | 51321 | ** Helper functions to obtain and relinquish the global mutex. The |
| | @@ -51387,107 +51507,10 @@ |
| 51387 | 51507 | |
| 51388 | 51508 | return rc; |
| 51389 | 51509 | } |
| 51390 | 51510 | |
| 51391 | 51511 | |
| 51392 | | -/* |
| 51393 | | -** Convert a UTF-8 filename into whatever form the underlying |
| 51394 | | -** operating system wants filenames in. Space to hold the result |
| 51395 | | -** is obtained from malloc and must be freed by the calling |
| 51396 | | -** function |
| 51397 | | -** |
| 51398 | | -** On Cygwin, 3 possible input forms are accepted: |
| 51399 | | -** - If the filename starts with "<drive>:/" or "<drive>:\", |
| 51400 | | -** it is converted to UTF-16 as-is. |
| 51401 | | -** - If the filename contains '/', it is assumed to be a |
| 51402 | | -** Cygwin absolute path, it is converted to a win32 |
| 51403 | | -** absolute path in UTF-16. |
| 51404 | | -** - Otherwise it must be a filename only, the win32 filename |
| 51405 | | -** is returned in UTF-16. |
| 51406 | | -** Note: If the function cygwin_conv_path() fails, only |
| 51407 | | -** UTF-8 -> UTF-16 conversion will be done. This can only |
| 51408 | | -** happen when the file path >32k, in which case winUtf8ToUnicode() |
| 51409 | | -** will fail too. |
| 51410 | | -*/ |
| 51411 | | -static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 51412 | | - void *zConverted = 0; |
| 51413 | | - if( osIsNT() ){ |
| 51414 | | -#ifdef __CYGWIN__ |
| 51415 | | - int nChar; |
| 51416 | | - LPWSTR zWideFilename; |
| 51417 | | - |
| 51418 | | - if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51419 | | - && winIsDirSep(zFilename[2])) ){ |
| 51420 | | - i64 nByte; |
| 51421 | | - int convertflag = CCP_POSIX_TO_WIN_W; |
| 51422 | | - if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51423 | | - nByte = (i64)osCygwin_conv_path(convertflag, |
| 51424 | | - zFilename, 0, 0); |
| 51425 | | - if( nByte>0 ){ |
| 51426 | | - zConverted = sqlite3MallocZero(12+(u64)nByte); |
| 51427 | | - if ( zConverted==0 ){ |
| 51428 | | - return zConverted; |
| 51429 | | - } |
| 51430 | | - zWideFilename = zConverted; |
| 51431 | | - /* Filenames should be prefixed, except when converted |
| 51432 | | - * full path already starts with "\\?\". */ |
| 51433 | | - if( osCygwin_conv_path(convertflag, zFilename, |
| 51434 | | - zWideFilename+4, nByte)==0 ){ |
| 51435 | | - if( (convertflag&CCP_RELATIVE) ){ |
| 51436 | | - memmove(zWideFilename, zWideFilename+4, nByte); |
| 51437 | | - }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ |
| 51438 | | - memcpy(zWideFilename, L"\\\\?\\", 8); |
| 51439 | | - }else if( zWideFilename[6]!='?' ){ |
| 51440 | | - memmove(zWideFilename+6, zWideFilename+4, nByte); |
| 51441 | | - memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 51442 | | - }else{ |
| 51443 | | - memmove(zWideFilename, zWideFilename+4, nByte); |
| 51444 | | - } |
| 51445 | | - return zConverted; |
| 51446 | | - } |
| 51447 | | - sqlite3_free(zConverted); |
| 51448 | | - } |
| 51449 | | - } |
| 51450 | | - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 51451 | | - if( nChar==0 ){ |
| 51452 | | - return 0; |
| 51453 | | - } |
| 51454 | | - zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); |
| 51455 | | - if( zWideFilename==0 ){ |
| 51456 | | - return 0; |
| 51457 | | - } |
| 51458 | | - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 51459 | | - zWideFilename, nChar); |
| 51460 | | - if( nChar==0 ){ |
| 51461 | | - sqlite3_free(zWideFilename); |
| 51462 | | - zWideFilename = 0; |
| 51463 | | - }else if( nChar>MAX_PATH |
| 51464 | | - && winIsDriveLetterAndColon(zFilename) |
| 51465 | | - && winIsDirSep(zFilename[2]) ){ |
| 51466 | | - memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); |
| 51467 | | - zWideFilename[2] = '\\'; |
| 51468 | | - memcpy(zWideFilename, L"\\\\?\\", 8); |
| 51469 | | - }else if( nChar>MAX_PATH |
| 51470 | | - && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 51471 | | - && zFilename[2] != '?' ){ |
| 51472 | | - memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); |
| 51473 | | - memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 51474 | | - } |
| 51475 | | - zConverted = zWideFilename; |
| 51476 | | -#else |
| 51477 | | - zConverted = winUtf8ToUnicode(zFilename); |
| 51478 | | -#endif /* __CYGWIN__ */ |
| 51479 | | - } |
| 51480 | | -#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32) |
| 51481 | | - else{ |
| 51482 | | - zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); |
| 51483 | | - } |
| 51484 | | -#endif |
| 51485 | | - /* caller will handle out of memory */ |
| 51486 | | - return zConverted; |
| 51487 | | -} |
| 51488 | | - |
| 51489 | 51512 | /* |
| 51490 | 51513 | ** This function is used to open a handle on a *-shm file. |
| 51491 | 51514 | ** |
| 51492 | 51515 | ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file |
| 51493 | 51516 | ** is opened with FILE_FLAG_OVERLAPPED specified. If not, it is not. |
| | @@ -89078,14 +89101,16 @@ |
| 89078 | 89101 | ** simple case then too. |
| 89079 | 89102 | */ |
| 89080 | 89103 | if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) |
| 89081 | 89104 | || nTrans<=1 |
| 89082 | 89105 | ){ |
| 89083 | | - for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ |
| 89084 | | - Btree *pBt = db->aDb[i].pBt; |
| 89085 | | - if( pBt ){ |
| 89086 | | - rc = sqlite3BtreeCommitPhaseOne(pBt, 0); |
| 89106 | + if( needXcommit ){ |
| 89107 | + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ |
| 89108 | + Btree *pBt = db->aDb[i].pBt; |
| 89109 | + if( sqlite3BtreeTxnState(pBt)>=SQLITE_TXN_WRITE ){ |
| 89110 | + rc = sqlite3BtreeCommitPhaseOne(pBt, 0); |
| 89111 | + } |
| 89087 | 89112 | } |
| 89088 | 89113 | } |
| 89089 | 89114 | |
| 89090 | 89115 | /* Do the commit only if all databases successfully complete phase 1. |
| 89091 | 89116 | ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an |
| | @@ -89092,11 +89117,13 @@ |
| 89092 | 89117 | ** IO error while deleting or truncating a journal file. It is unlikely, |
| 89093 | 89118 | ** but could happen. In this case abandon processing and return the error. |
| 89094 | 89119 | */ |
| 89095 | 89120 | for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ |
| 89096 | 89121 | Btree *pBt = db->aDb[i].pBt; |
| 89097 | | - if( pBt ){ |
| 89122 | + int txn = sqlite3BtreeTxnState(pBt); |
| 89123 | + if( txn!=SQLITE_TXN_NONE ){ |
| 89124 | + assert( needXcommit || txn==SQLITE_TXN_READ ); |
| 89098 | 89125 | rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); |
| 89099 | 89126 | } |
| 89100 | 89127 | } |
| 89101 | 89128 | if( rc==SQLITE_OK ){ |
| 89102 | 89129 | sqlite3VtabCommit(db); |
| | @@ -89347,32 +89374,35 @@ |
| 89347 | 89374 | return SQLITE_OK; |
| 89348 | 89375 | } |
| 89349 | 89376 | |
| 89350 | 89377 | |
| 89351 | 89378 | /* |
| 89352 | | -** This function is called when a transaction opened by the database |
| 89379 | +** These functions are called when a transaction opened by the database |
| 89353 | 89380 | ** handle associated with the VM passed as an argument is about to be |
| 89354 | | -** committed. If there are outstanding deferred foreign key constraint |
| 89355 | | -** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. |
| 89381 | +** committed. If there are outstanding foreign key constraint violations |
| 89382 | +** return an error code. Otherwise, SQLITE_OK. |
| 89356 | 89383 | ** |
| 89357 | 89384 | ** If there are outstanding FK violations and this function returns |
| 89358 | | -** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY |
| 89359 | | -** and write an error message to it. Then return SQLITE_ERROR. |
| 89385 | +** non-zero, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY |
| 89386 | +** and write an error message to it. |
| 89360 | 89387 | */ |
| 89361 | 89388 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 89362 | | -SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ |
| 89389 | +static SQLITE_NOINLINE int vdbeFkError(Vdbe *p){ |
| 89390 | + p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; |
| 89391 | + p->errorAction = OE_Abort; |
| 89392 | + sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); |
| 89393 | + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR; |
| 89394 | + return SQLITE_CONSTRAINT_FOREIGNKEY; |
| 89395 | +} |
| 89396 | +SQLITE_PRIVATE int sqlite3VdbeCheckFkImmediate(Vdbe *p){ |
| 89397 | + if( p->nFkConstraint==0 ) return SQLITE_OK; |
| 89398 | + return vdbeFkError(p); |
| 89399 | +} |
| 89400 | +SQLITE_PRIVATE int sqlite3VdbeCheckFkDeferred(Vdbe *p){ |
| 89363 | 89401 | sqlite3 *db = p->db; |
| 89364 | | - if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) |
| 89365 | | - || (!deferred && p->nFkConstraint>0) |
| 89366 | | - ){ |
| 89367 | | - p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; |
| 89368 | | - p->errorAction = OE_Abort; |
| 89369 | | - sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); |
| 89370 | | - if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR; |
| 89371 | | - return SQLITE_CONSTRAINT_FOREIGNKEY; |
| 89372 | | - } |
| 89373 | | - return SQLITE_OK; |
| 89402 | + if( (db->nDeferredCons+db->nDeferredImmCons)==0 ) return SQLITE_OK; |
| 89403 | + return vdbeFkError(p); |
| 89374 | 89404 | } |
| 89375 | 89405 | #endif |
| 89376 | 89406 | |
| 89377 | 89407 | /* |
| 89378 | 89408 | ** This routine is called the when a VDBE tries to halt. If the VDBE |
| | @@ -89462,11 +89492,11 @@ |
| 89462 | 89492 | } |
| 89463 | 89493 | } |
| 89464 | 89494 | |
| 89465 | 89495 | /* Check for immediate foreign key violations. */ |
| 89466 | 89496 | if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ |
| 89467 | | - (void)sqlite3VdbeCheckFk(p, 0); |
| 89497 | + (void)sqlite3VdbeCheckFkImmediate(p); |
| 89468 | 89498 | } |
| 89469 | 89499 | |
| 89470 | 89500 | /* If the auto-commit flag is set and this is the only active writer |
| 89471 | 89501 | ** VM, then we do either a commit or rollback of the current transaction. |
| 89472 | 89502 | ** |
| | @@ -89476,11 +89506,11 @@ |
| 89476 | 89506 | if( !sqlite3VtabInSync(db) |
| 89477 | 89507 | && db->autoCommit |
| 89478 | 89508 | && db->nVdbeWrite==(p->readOnly==0) |
| 89479 | 89509 | ){ |
| 89480 | 89510 | if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ |
| 89481 | | - rc = sqlite3VdbeCheckFk(p, 1); |
| 89511 | + rc = sqlite3VdbeCheckFkDeferred(p); |
| 89482 | 89512 | if( rc!=SQLITE_OK ){ |
| 89483 | 89513 | if( NEVER(p->readOnly) ){ |
| 89484 | 89514 | sqlite3VdbeLeave(p); |
| 89485 | 89515 | return SQLITE_ERROR; |
| 89486 | 89516 | } |
| | @@ -90341,19 +90371,19 @@ |
| 90341 | 90371 | /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ |
| 90342 | 90372 | pMem->szMalloc = 0; |
| 90343 | 90373 | pMem->z = 0; |
| 90344 | 90374 | sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); |
| 90345 | 90375 | d += sqlite3VdbeSerialTypeLen(serial_type); |
| 90346 | | - pMem++; |
| 90347 | 90376 | if( (++u)>=p->nField ) break; |
| 90377 | + pMem++; |
| 90348 | 90378 | } |
| 90349 | 90379 | if( d>(u32)nKey && u ){ |
| 90350 | 90380 | assert( CORRUPT_DB ); |
| 90351 | 90381 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90352 | 90382 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90353 | 90383 | ** warnings from MSAN. */ |
| 90354 | | - sqlite3VdbeMemSetNull(pMem-1); |
| 90384 | + sqlite3VdbeMemSetNull(pMem-(u<p->nField)); |
| 90355 | 90385 | } |
| 90356 | 90386 | testcase( u == pKeyInfo->nKeyField + 1 ); |
| 90357 | 90387 | testcase( u < pKeyInfo->nKeyField + 1 ); |
| 90358 | 90388 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90359 | 90389 | p->nField = u; |
| | @@ -90520,10 +90550,36 @@ |
| 90520 | 90550 | ** Both *pMem1 and *pMem2 contain string values. Compare the two values |
| 90521 | 90551 | ** using the collation sequence pColl. As usual, return a negative , zero |
| 90522 | 90552 | ** or positive value if *pMem1 is less than, equal to or greater than |
| 90523 | 90553 | ** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". |
| 90524 | 90554 | */ |
| 90555 | +static SQLITE_NOINLINE int vdbeCompareMemStringWithEncodingChange( |
| 90556 | + const Mem *pMem1, |
| 90557 | + const Mem *pMem2, |
| 90558 | + const CollSeq *pColl, |
| 90559 | + u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ |
| 90560 | +){ |
| 90561 | + int rc; |
| 90562 | + const void *v1, *v2; |
| 90563 | + Mem c1; |
| 90564 | + Mem c2; |
| 90565 | + sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); |
| 90566 | + sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); |
| 90567 | + sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); |
| 90568 | + sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); |
| 90569 | + v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); |
| 90570 | + v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); |
| 90571 | + if( (v1==0 || v2==0) ){ |
| 90572 | + if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; |
| 90573 | + rc = 0; |
| 90574 | + }else{ |
| 90575 | + rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); |
| 90576 | + } |
| 90577 | + sqlite3VdbeMemReleaseMalloc(&c1); |
| 90578 | + sqlite3VdbeMemReleaseMalloc(&c2); |
| 90579 | + return rc; |
| 90580 | +} |
| 90525 | 90581 | static int vdbeCompareMemString( |
| 90526 | 90582 | const Mem *pMem1, |
| 90527 | 90583 | const Mem *pMem2, |
| 90528 | 90584 | const CollSeq *pColl, |
| 90529 | 90585 | u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ |
| | @@ -90531,29 +90587,11 @@ |
| 90531 | 90587 | if( pMem1->enc==pColl->enc ){ |
| 90532 | 90588 | /* The strings are already in the correct encoding. Call the |
| 90533 | 90589 | ** comparison function directly */ |
| 90534 | 90590 | return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); |
| 90535 | 90591 | }else{ |
| 90536 | | - int rc; |
| 90537 | | - const void *v1, *v2; |
| 90538 | | - Mem c1; |
| 90539 | | - Mem c2; |
| 90540 | | - sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); |
| 90541 | | - sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); |
| 90542 | | - sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); |
| 90543 | | - sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); |
| 90544 | | - v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); |
| 90545 | | - v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); |
| 90546 | | - if( (v1==0 || v2==0) ){ |
| 90547 | | - if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; |
| 90548 | | - rc = 0; |
| 90549 | | - }else{ |
| 90550 | | - rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); |
| 90551 | | - } |
| 90552 | | - sqlite3VdbeMemReleaseMalloc(&c1); |
| 90553 | | - sqlite3VdbeMemReleaseMalloc(&c2); |
| 90554 | | - return rc; |
| 90592 | + return vdbeCompareMemStringWithEncodingChange(pMem1,pMem2,pColl,prcErr); |
| 90555 | 90593 | } |
| 90556 | 90594 | } |
| 90557 | 90595 | |
| 90558 | 90596 | /* |
| 90559 | 90597 | ** The input pBlob is guaranteed to be a Blob that is not marked |
| | @@ -96256,11 +96294,11 @@ |
| 96256 | 96294 | ** exits. This opcode is used to raise foreign key constraint errors prior |
| 96257 | 96295 | ** to returning results such as a row change count or the result of a |
| 96258 | 96296 | ** RETURNING clause. |
| 96259 | 96297 | */ |
| 96260 | 96298 | case OP_FkCheck: { |
| 96261 | | - if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ |
| 96299 | + if( (rc = sqlite3VdbeCheckFkImmediate(p))!=SQLITE_OK ){ |
| 96262 | 96300 | goto abort_due_to_error; |
| 96263 | 96301 | } |
| 96264 | 96302 | break; |
| 96265 | 96303 | } |
| 96266 | 96304 | |
| | @@ -98440,11 +98478,11 @@ |
| 98440 | 98478 | ** and this is a RELEASE command, then the current transaction |
| 98441 | 98479 | ** is committed. |
| 98442 | 98480 | */ |
| 98443 | 98481 | int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; |
| 98444 | 98482 | if( isTransaction && p1==SAVEPOINT_RELEASE ){ |
| 98445 | | - if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ |
| 98483 | + if( (rc = sqlite3VdbeCheckFkDeferred(p))!=SQLITE_OK ){ |
| 98446 | 98484 | goto vdbe_return; |
| 98447 | 98485 | } |
| 98448 | 98486 | db->autoCommit = 1; |
| 98449 | 98487 | if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ |
| 98450 | 98488 | p->pc = (int)(pOp - aOp); |
| | @@ -98558,11 +98596,11 @@ |
| 98558 | 98596 | */ |
| 98559 | 98597 | sqlite3VdbeError(p, "cannot commit transaction - " |
| 98560 | 98598 | "SQL statements in progress"); |
| 98561 | 98599 | rc = SQLITE_BUSY; |
| 98562 | 98600 | goto abort_due_to_error; |
| 98563 | | - }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ |
| 98601 | + }else if( (rc = sqlite3VdbeCheckFkDeferred(p))!=SQLITE_OK ){ |
| 98564 | 98602 | goto vdbe_return; |
| 98565 | 98603 | }else{ |
| 98566 | 98604 | db->autoCommit = (u8)desiredAutoCommit; |
| 98567 | 98605 | } |
| 98568 | 98606 | if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ |
| | @@ -109256,12 +109294,12 @@ |
| 109256 | 109294 | assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ |
| 109257 | 109295 | if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R); |
| 109258 | 109296 | |
| 109259 | 109297 | /* |
| 109260 | 109298 | ** Expression p should encode a floating point value between 1.0 and 0.0. |
| 109261 | | -** Return 1024 times this value. Or return -1 if p is not a floating point |
| 109262 | | -** value between 1.0 and 0.0. |
| 109299 | +** Return 134,217,728 (2^27) times this value. Or return -1 if p is not |
| 109300 | +** a floating point value between 1.0 and 0.0. |
| 109263 | 109301 | */ |
| 109264 | 109302 | static int exprProbability(Expr *p){ |
| 109265 | 109303 | double r = -1.0; |
| 109266 | 109304 | if( p->op!=TK_FLOAT ) return -1; |
| 109267 | 109305 | assert( !ExprHasProperty(p, EP_IntValue) ); |
| | @@ -115633,10 +115671,16 @@ |
| 115633 | 115671 | case TK_STRING: { |
| 115634 | 115672 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 115635 | 115673 | sqlite3VdbeLoadString(v, target, pExpr->u.zToken); |
| 115636 | 115674 | return target; |
| 115637 | 115675 | } |
| 115676 | + case TK_NULLS: { |
| 115677 | + /* Set a range of registers to NULL. pExpr->y.nReg registers starting |
| 115678 | + ** with target */ |
| 115679 | + sqlite3VdbeAddOp3(v, OP_Null, 0, target, target + pExpr->y.nReg - 1); |
| 115680 | + return target; |
| 115681 | + } |
| 115638 | 115682 | default: { |
| 115639 | 115683 | /* Make NULL the default case so that if a bug causes an illegal |
| 115640 | 115684 | ** Expr node to be passed into this function, it will be handled |
| 115641 | 115685 | ** sanely and not crash. But keep the assert() to bring the problem |
| 115642 | 115686 | ** to the attention of the developers. */ |
| | @@ -116341,10 +116385,29 @@ |
| 116341 | 116385 | } |
| 116342 | 116386 | pParse->pConstExpr = p; |
| 116343 | 116387 | } |
| 116344 | 116388 | return regDest; |
| 116345 | 116389 | } |
| 116390 | + |
| 116391 | +/* |
| 116392 | +** Make arrangements to invoke OP_Null on a range of registers |
| 116393 | +** during initialization. |
| 116394 | +*/ |
| 116395 | +SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3ExprNullRegisterRange( |
| 116396 | + Parse *pParse, /* Parsing context */ |
| 116397 | + int iReg, /* First register to set to NULL */ |
| 116398 | + int nReg /* Number of sequential registers to NULL out */ |
| 116399 | +){ |
| 116400 | + u8 okConstFactor = pParse->okConstFactor; |
| 116401 | + Expr t; |
| 116402 | + memset(&t, 0, sizeof(t)); |
| 116403 | + t.op = TK_NULLS; |
| 116404 | + t.y.nReg = nReg; |
| 116405 | + pParse->okConstFactor = 1; |
| 116406 | + sqlite3ExprCodeRunJustOnce(pParse, &t, iReg); |
| 116407 | + pParse->okConstFactor = okConstFactor; |
| 116408 | +} |
| 116346 | 116409 | |
| 116347 | 116410 | /* |
| 116348 | 116411 | ** Generate code to evaluate an expression and store the results |
| 116349 | 116412 | ** into a register. Return the register number where the results |
| 116350 | 116413 | ** are stored. |
| | @@ -152746,10 +152809,11 @@ |
| 152746 | 152809 | Select *pSub = pWhere->x.pSelect; |
| 152747 | 152810 | Expr *pSubWhere = pSub->pWhere; |
| 152748 | 152811 | if( pSub->pSrc->nSrc==1 |
| 152749 | 152812 | && (pSub->selFlags & SF_Aggregate)==0 |
| 152750 | 152813 | && !pSub->pSrc->a[0].fg.isSubquery |
| 152814 | + && pSub->pLimit==0 |
| 152751 | 152815 | ){ |
| 152752 | 152816 | memset(pWhere, 0, sizeof(*pWhere)); |
| 152753 | 152817 | pWhere->op = TK_INTEGER; |
| 152754 | 152818 | pWhere->u.iValue = 1; |
| 152755 | 152819 | ExprSetProperty(pWhere, EP_IntValue); |
| | @@ -153766,10 +153830,11 @@ |
| 153766 | 153830 | iBMem = pParse->nMem + 1; |
| 153767 | 153831 | pParse->nMem += pGroupBy->nExpr; |
| 153768 | 153832 | sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); |
| 153769 | 153833 | VdbeComment((v, "clear abort flag")); |
| 153770 | 153834 | sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); |
| 153835 | + sqlite3ExprNullRegisterRange(pParse, iAMem, pGroupBy->nExpr); |
| 153771 | 153836 | |
| 153772 | 153837 | /* Begin a loop that will extract all source rows in GROUP BY order. |
| 153773 | 153838 | ** This might involve two separate loops with an OP_Sort in between, or |
| 153774 | 153839 | ** it might be a single loop that uses an index to extract information |
| 153775 | 153840 | ** in the right order to begin with. |
| | @@ -169084,10 +169149,11 @@ |
| 169084 | 169149 | if( pProbe->bNoQuery ) continue; |
| 169085 | 169150 | rSize = pProbe->aiRowLogEst[0]; |
| 169086 | 169151 | pNew->u.btree.nEq = 0; |
| 169087 | 169152 | pNew->u.btree.nBtm = 0; |
| 169088 | 169153 | pNew->u.btree.nTop = 0; |
| 169154 | + pNew->u.btree.nDistinctCol = 0; |
| 169089 | 169155 | pNew->nSkip = 0; |
| 169090 | 169156 | pNew->nLTerm = 0; |
| 169091 | 169157 | pNew->iSortIdx = 0; |
| 169092 | 169158 | pNew->rSetup = 0; |
| 169093 | 169159 | pNew->prereq = mPrereq; |
| | @@ -170152,12 +170218,10 @@ |
| 170152 | 170218 | && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) |
| 170153 | 170219 | ){ |
| 170154 | 170220 | obSat = obDone; |
| 170155 | 170221 | } |
| 170156 | 170222 | break; |
| 170157 | | - }else if( wctrlFlags & WHERE_DISTINCTBY ){ |
| 170158 | | - pLoop->u.btree.nDistinctCol = 0; |
| 170159 | 170223 | } |
| 170160 | 170224 | iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; |
| 170161 | 170225 | |
| 170162 | 170226 | /* Mark off any ORDER BY term X that is a column in the table of |
| 170163 | 170227 | ** the current loop for which there is term in the WHERE |
| | @@ -258113,11 +258177,11 @@ |
| 258113 | 258177 | int nArg, /* Number of args */ |
| 258114 | 258178 | sqlite3_value **apUnused /* Function arguments */ |
| 258115 | 258179 | ){ |
| 258116 | 258180 | assert( nArg==0 ); |
| 258117 | 258181 | UNUSED_PARAM2(nArg, apUnused); |
| 258118 | | - sqlite3_result_text(pCtx, "fts5: 2025-07-15 19:00:01 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839", -1, SQLITE_TRANSIENT); |
| 258182 | + sqlite3_result_text(pCtx, "fts5: 2025-07-30 16:17:14 cf7163f82ca380958a79350473b2c5a2cebda7496d6d575fa2835c362010fea1", -1, SQLITE_TRANSIENT); |
| 258119 | 258183 | } |
| 258120 | 258184 | |
| 258121 | 258185 | /* |
| 258122 | 258186 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 258123 | 258187 | ** |
| 258124 | 258188 | |